Command line &> redirection not working? - bash

I've been using a Ruby script to help automate my testing. As a part of this script I am redirecting output from a program into a file like this:
`./program_name #{params} > #{temp_file}`
This works fine, how I'd like to redirect both STDOUT and STDERR to the file. Which I would do like this:
`./program_name #{params} &> #{temp_file}`
Having added the &, the temp file no longer receives any output.
Note that the &> operator works as expected when used on the command line, it seems only to be in the Ruby script that it causes the problem.
Any ideas why this might be, and how I might get around the issue?

&> is a bashism. Simply use POSIX redirections:
`./program_name #{params} >#{temp_file} 2>&1`

Related

bash: separating command from pipe

I have a third-part software that accepts command line arguments. I want to pipe the output in a file. I have found that for some inexplicable reasons the code hangs if I try:
./run_third_part.py &> log
but it works if
./run_third_part.py
I believe that piping the output is messing up with the process of reading command line arguments, although other ideas are welcome. How can I isolate the program from the pipe command? (I was thinking about putting some sort of parentheses.)
Probably the script is waiting for input on an interactive prompt. The easiest way around this is usually to give it some input:
./run_third_part.py < /dev/null &> log
Can you try creating a subshell and run the script,
bash$ `./run_third_part.py` &> log
Please notice ` is not '
(single quote)

Pipe direct tty output to sed

I have a script using for a building a program that I redirect to sed to highlight errors and such during the build.
This works great, but the problem is at the end of this build script it starts an application which usually writes to the terminal, but stdout and stderr redirection doesn't seem to capture it. I'm not exactly sure how this output gets printed and it's kind of complicated to figure out.
buildAndStartApp # everything outputs correctly
buildAndStartApp 2>&1 | colorize # Catches build output, but not server output
Is there any way to capture all terminal output? The "script" command catches everything, but I would like the output to still print to my terminal rather than redirecting to a file.
I found out script has a -c option which runs a command and all of the output is printed to stdout as well as to a file.
My command ended up being:
script -c "buildAndStartApp" /dev/null | colorize
First, when you use script, the output does still go to the terminal (as well as redirecting to the file). You could do something like this in a second window to see the colorized output live:
tail -f typescript | colorize
Second, if the output of a command is going to the terminal even though you have both stdout and stderr redirected, it's possible that the command is writing directly to /dev/tty, in which case something like script that uses a pseudo-terminal is the only thing that will work.

Copy script output to file

I have a series of bash scripts that echo a lot of data to stdout and occasionally to stderr. There is a main bash script which then imports and/or invokes many other bash scripts.
I'm trying to implement something that will capture the output from not just the parent script, but all children scripts. I need to capture both stdout and stderr so that any issues from compilation, etc... get captured in this log file.
I'm aware of tee and of course the normal stdout redirect >... but these don't seem to work without either adding these commands to each line of every script, both parent and children. There's several thousand lines in these scripts, so adding a redirect to each line would be impractical, even using sed.
I've seen suggestions such as: Redirect stderr and stdout in a Bash script
But these require editing every line in the scripts. Forcing my users to install screen is also impractical.
UPDATE:
Forgot to mention I want the output to still display on the console as well as write to the log. The scripts take several hours to run, and the user needs to know something is happening...
You can use yourmainscript 2>&1 | tee log which will capture stdout and stderr from all imported/invoked scripts in yourmainscript while also showing it on screen.
Inside yourmainscript, you can get the same effect using:
echo "Redirecting the rest of script output to 'log'"
exec > >(tee log) 2>&1
rest of your code
To redirect just a certain section:
echo "Redirecting the next commands"
{
cmd1
cmd2
} > >(tee log) 2>&1
echo "Continuing as normal"

bash assign output of fuser to a variable oddity

when using the following bash script to assign variable to the output of fuser, it still outputs the part of result(before :) of fuser to screen.
why isn't it suppressed? I suspect it has to do with the ":" char output by fuser. how do I fix this?
test=`fuser -f /home/whois_database_collection_v4/whoisdatacollector/logs/com_log_2013_02_15_12_40_43.log`
/home/whois_database_collection_v4/whoisdatacollector/logs/com_log_2013_02_15_12_40_43.log:
fuser sends the part of the output you see to stderr, and the rest to stdout (I suspect that it tries to simplify its usage from scripts, while preserving some beauty from the user's point of view). It will disappear if you add 2> /dev/null redirection for stderr.

log all stderr to file and console

There are plenty of threads here discussing how to do this for scripts or for the cmdline (mostly involving pipes, redirections, tee).
What I didn't find is a solution which can be set up once and then just works globally, without manipulating single scripts or adding something to every command line.
What I want to achieve is something like described in the top answer of
How do I write stderr to a file while using "tee" with a pipe?
Isn't it possible to configure the bash session so that all stderr output is logged to a file, while still writing it to console? Something I could add to .bashrc and thus automatically set up every time I login?
Software: Bash 4.2.24(1)-release (x86_64-pc-linux-gnu), xterm, Ubuntu 12.04
Try this variation on #0xC0000022L's previous solution (put it in your .bash_profile):
exec 2> >( tee log.file > /dev/tty )
A couple of caveats:
The prompt and anything you type at the command line are printed to stderr, and so will be logged in your file.
There could be an issue with the newline that terminates a command not being displayed in your terminal; I observe it on my Linux host, but not on my Mac OS X laptop. Perhaps someone else can explain and/or fix the issue. For example, if I type "echo stdout", I see the following:
$ echo stdoutstdout
$

Resources