nohup gedit &> /dev/null
is POSIX syntax and is the same as:
nohup gedit &
> /dev/null
That is run nohup gedit
in background and then do a > /dev/null
redirection without running a command.
nohup gedit >& /dev/null
is not POSIX syntax and is the csh
way to redirect both stdout and stderr to /dev/null. csh
doesn't have the 2>&1
operator as found in Bourne, so it's the only way csh
has to redirect stderr.
zsh
(as often) also provides with the csh
syntax, but it also supports the x>&y
fd duplication operator of the Bourne shell, which means there's a conflict there.
ls >&file
redirects ls
's stdout and stderr to file
, but if the file is 2
, you've got a problem as
ls >&2
means redirect stdout to the resource pointed to by fd 2 (dup(2, 1)
). So you need to write it:
ls >& ./2
if you wanted to redirect both the stdout and stderr of ls
into a file called 2
in the current directory; or use the standard syntax.
bash
initially did no understand >&
, but it introduced the &>
operator instead for that, breaking POSIX compliance in the process (though it's unlikely a script would use cmd &> xxx
).
ksh
copied that operator in ksh93t+ in 2009, mksh in R35 in 2008 (disabled in posix
mode) but not >&
.
bash
added support for >&
in 2.05.
busybox sh
added support for both &>
and >&
in 1.13 (2008).
Neither >&
nor &>
as meaning redirect stdout and stderr are POSIX/Bourne.
If you want to redirect both stdout and stderr portably, the syntax is
cmd > file 2>&1
The command will output the data from device /dev/null
to the given file (mailbox of the root account). Since /dev/null
responds just with end-of-file when reading from it nothing will be written to the file, but with the redirection >
the shell will have cleared the file already. Actually this is equivalent to writing just
> /var/spool/mail/root
(i.e., the same without cat
or /dev/null
).
Best Answer
[this answer is about asynchronous pipelines in scripts; for the deprecated
&>
bash operator and why you should always use>output 2>&1
instead, refer to obsolete and deprecated syntax]Here you have a pipeline running asynchronously (because terminated by
&
), started from a script, ie is from a shell with the job control disabled.According to the standard:
The problem is that
dash
,ksh
,mksh
,yash
, etc intepret "asynchronous list" as any command, including a pipeline, and will redirect the stdin of the first command from/dev/null
:But
bash
will only interpret it as "simple command" and will only redirect its stdin from/dev/null
when it's not part of a pipeline:zsh
will only redirect it from/dev/null
when the original stdin is a tty, not when it's other kind of file:A workaround which works in all shells is to duplicate the stdin into another file descriptor, and redirect the stdin of the first command from it: