Why does 'nohup command >& /dev/null' seem to "work" in some shells?

20,993
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
Share:
20,993

Related videos on Youtube

terdon
Author by

terdon

Elected moderator on Unix & Linux. I've been using Linux since the late '90s and have gone through a variety of distributions. At one time or another, I've been a user of Mandrake, SuSe, openSuSe, Fedora, RedHat, Ubuntu, Mint, Linux Mint Debian Edition (basically Debian testing but more green) and, for the past few years, Arch. My Linux expertise, such as it is, is mostly on manipulating text and regular expressions since that represents a large chunk of my daily work.

Updated on September 18, 2022

Comments

  • terdon
    terdon over 1 year

    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) and tcsh (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 no gedit 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?

    • Admin
      Admin about 10 years
      In my machine, Ubuntu 12.04, this command run normally for dash.
    • Admin
      Admin about 10 years
      nohup command, run independent tty your application.According to my memory, dash extended of ash , Debian ash , ash developed byOpenBSD and it's limited shell,even maemo OS(Debian Base on n900 mobile) uses dash,ash family shell have limited usage expect of bash or tcsh.
    • Admin
      Admin about 10 years
      @Gnouc huh, perhaps a different version (I'm on Debian)? I can't figure out how to get my dash to print its version out but the package is 0.5.7-3, what's yours? Also, are you sure you're running dash? That's Ubuntu's default sh isn't it?
    • Admin
      Admin about 10 years
      @MohsenPahlevanzadeh I'm not sure what your point is, I know what nohup does, my question is why the >& seems to work with nohup alone in some shells.
    • Admin
      Admin about 10 years
      @MohsenPahlevanzadeh again, thank you but you have completely missed the point of my question.
    • Admin
      Admin about 10 years
      @terdon: mine is 0.5.7-2. I use bash as default shell. But I haved switched to dash before running this command.
    • Admin
      Admin about 10 years
      When I do that in bash and then do jobs, I see this as command (note >& changed to &>) $ jobs [1]+ Running nohup gedit &>/dev/null &
    • Admin
      Admin about 10 years
      @XTian umm, the whole point is the >&, &> is just shorthand for 2>&1 > so of course it works. I think that the shells where this works are simply ignoring the space between the >& and /dev/null, >& means redirect to the file descriptor that follows, >&2 means redirect to stderr for example.
  • Pandya
    Pandya about 8 years
    Do you mean Bash in POSIX/Bourne by "Bourne"?