I edited an answer on Ask Ubuntu that was suggesting the following
nohup gedit >& /dev/null &
When they actually meant
nohup gedit &> /dev/null &
The latter correctly redirects both stderr and stdout to /dev/null
. I was expecting the former to either create a file called &
or, more likely, to give an error as it does for other cases:
$ echo "foo" >&
bash: syntax error near unexpected token `newline'
Instead, it seems to work in exactly the same way as the former, a gedit
window appears and no error message is printed.
I should also note that this is shell specific:
-
bash
(4.2.45(1)-release),zsh
(5.0.2),csh
(deb package version: 20110502-2) andtcsh
(6.18.01) : works as described above, no error message, no files created. -
dash
(0.5.7-3):$ nohup gedit >& /dev/null & $ dash: 2: Syntax error: Bad fd number
-
ksh
(93u+ 2012-08-01): fails, but a process is apparently started (1223
) though nogedit
window appears:$ nohup gedit >& /dev/null & [1] 1223 $ ksh: /dev/null: bad file unit number
-
fish
(2.0.0):> nohup gedit >& /dev/null & fish: Requested redirection to something that is not a file descriptor /dev/null nohup gedit >& /dev/null & ^
So, why does this command simply run with no errors (and no output file created) in some shells and fail in others? What is the >&
doing in the apparently special case of nohup
? I am guessing that >& /dev/null
is being interpreted as >&/dev/null
but why isn't the space causing an error in these shells?
Best Answer
is POSIX syntax and is the same as:
That is run
nohup gedit
in background and then do a> /dev/null
redirection without running a command.is not POSIX syntax and is the
csh
way to redirect both stdout and stderr to /dev/null.csh
doesn't have the2>&1
operator as found in Bourne, so it's the only waycsh
has to redirect stderr.zsh
(as often) also provides with thecsh
syntax, but it also supports thex>&y
fd duplication operator of the Bourne shell, which means there's a conflict there.redirects
ls
's stdout and stderr tofile
, but if the file is2
, you've got a problem asmeans redirect stdout to the resource pointed to by fd 2 (
dup(2, 1)
). So you need to write it:if you wanted to redirect both the stdout and stderr of
ls
into a file called2
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 usecmd &> xxx
).ksh
copied that operator in ksh93t+ in 2009, mksh in R35 in 2008 (disabled inposix
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