There are two forms of redirection the standard output and standard error into standard output. But which one is better? and why the &>
is considered the perfect?
I can't find what is the differences so that many tutorials and even bash manual state that &>
is better!
So Why shall I use &>
and not 2>&1
Mainly using bash
shell
EDIT: Thanks for commentors
Only >& works in csh or tcsh
In ksh only 2>&1 works.
dash use >file 2>&1 redirection only
Then which one to use to ensure my script is compatible with other systems whatever the used shells are!
Bash's man page mentions there's two ways to redirect stderr and stdout:
&> file
and>& file
. Now, notice that it says both stderr and stdout.In case of this
>file 2>&1
we are doing redirection of stdout (1) to file, but then also telling stderr(2) to be redirected to the same place as stdout ! So the purpose may be the same, but the idea slightly different. In other words "John, go to school; Suzzie go where John goes".What about preference ?
&>
is abash
thing. So if you're porting a script, that won't do it. But if you're 100% certain your script will be only working on system with bash - then there's no preferenceHere's an example with
dash
, the Debian Amquist Shell which is Ubuntu's default.As you can see, stderr is not being redirected
To address your edits in the question, you can use if statement to check $SHELL variable and change redirects accordingly
But for most cases
> file 2>&1
should workIn more technical terms, the form
[integer]>&word
is called Duplicating Output File Descriptor, and is a feature specified by POSIX Shell Command Language standard, which is supported by most POSIX-compliant and Brourne-like shells.See also What does & mean exactly in output redirection?
I would generally recommend following the Bourne-again SHell's way of doing things, since bash is arguably the most popular Unix shell out there. Bash typically uses either
&>
or2>&1
. IMHO, neither is "perfect", so I recommend forgetting about that nonsense. Realistically, which one you should use depends on what you are trying to do.2>&1
merges stderr with stdout, which can be useful if, for example, you want to pipe stderr text. So, for example, if you want to see if a program prints a certain stderr message, but don't want your screen filled with (presumably) unimportant garbage, you could do something likeprogram 2>&1 | grep crashed
, which will search the stdout and stderr from a program called "program" for the word "crashed".On the other hand, if you don't want a program to print anything at all, you could simply run
program &> /dev/null
, which will redirect both stderr and stdout to /dev/null, a special file which magically makes things disappear. Or, if you want to save the output of a program (perhaps to report a bug or something), you could redirect both stderr and stdout to a file:program &> log.txt
will redirect all data to a file called "log.txt". If you wanted to, you could redirect the stdout and stderr viaprogram 2> log.txt > log.txt
orprogram 2>&1 | cat > log.txt
, both of which would have the same effect as using&>
. If you do something likeprogram 2>&1 > file
, only stdout will be redirected, but stderr can still be piped to another program, such as cat, which could be redirected as shown above. However, typing&>
is easier than any of the above examples, since it involve typing fewer characters (and it's a bit easier for human beings to read). Do note thatprogram 2> log.txt > log.txt
might be more likely to work on non-bash shells.PS: if you are worried about people using other shells, there's something you can add to be first line of your script called a "magic number", or "shebang". This is essentially a way to make sure other computers (particularly those running Unix-like operating systems) know which program to use to execute a script. Different scripts use different shebangs. A shebang for a bash script looks like this:
If you use the above as the first line of a given script, bash will generally be used to execute said script. This will make it much more difficult for someone to accidentally execute the script with the wrong shell.
PS: I'm not going to lie: up till now, I didn't know one could use
>&
, but, as far as bash goes, it seems to do the same as&>
. You learn something new everyday.2>&1
is standard Bourne/POSIX shell.&>
is a bash extension and not de jure standard.If you write scripts using bash extensions, sooner or later you're going to encounter head-scratching failures with cryptic syntax error messages because they're being run in a standard shell.
From Bash Reference Manual -> 3.6.4 Redirecting Standard Output and Standard Error:
Also good to refer to Greg's wiki on Input And Output -> 4.2. File Descriptor Manipulation: