- How do I use the nohup command without getting nohup.out?
- 9 Answers 9
- Why does ‘nohup command >& /dev/null’ seem to «work» in some shells?
- 1 Answer 1
- How to Run Linux Shell Command / Script in Background
- Running shell command in background using (&) sign
- Running shell command or script in background using nohup command
- Conclusion
- How to run nohup and write its pid file in a single bash statement
How do I use the nohup command without getting nohup.out?
I have a problem with the nohup command. When I run my job, I have a lot of data. The output nohup.out becomes too large and my process slows down. How can I run this command without getting nohup.out?
9 Answers 9
The nohup command only writes to nohup.out if the output would otherwise go to the terminal. If you have redirected the output of the command somewhere else — including /dev/null — that’s where it goes instead.
nohup command >/dev/null 2>&1 # doesn't create nohup.out
Note that the >/dev/null 2>&1 sequence can be abbreviated to just >&/dev/null in most (but not all) shells.
If you’re using nohup , that probably means you want to run the command in the background by putting another & on the end of the whole thing:
nohup command >/dev/null 2>&1 & # runs in background, still doesn't create nohup.out
On Linux, running a job with nohup automatically closes its input as well. On other systems, notably BSD and macOS, that is not the case, so when running in the background, you might want to close input manually. While closing input has no effect on the creation or not of nohup.out , it avoids another problem: if a background process tries to read anything from standard input, it will pause, waiting for you to bring it back to the foreground and type something. So the extra-safe version looks like this:
nohup command /dev/null 2>&1 & # completely detached from terminal
Note, however, that this does not prevent the command from accessing the terminal directly, nor does it remove it from your shell’s process group. If you want to do the latter, and you are running bash, ksh, or zsh, you can do so by running disown with no argument as the next command. That will mean the background process is no longer associated with a shell «job» and will not have any signals forwarded to it from the shell. (A disown ed process gets no signals forwarded to it automatically by its parent shell — but without nohup , it will still receive a HUP signal sent via other means, such as a manual kill command. A nohup ‘ed process ignores any and all HUP signals, no matter how they are sent.)
In Unixy systems, every source of input or target of output has a number associated with it called a «file descriptor», or «fd» for short. Every running program («process») has its own set of these, and when a new process starts up it has three of them already open: «standard input», which is fd 0, is open for the process to read from, while «standard output» (fd 1) and «standard error» (fd 2) are open for it to write to. If you just run a command in a terminal window, then by default, anything you type goes to its standard input, while both its standard output and standard error get sent to that window.
But you can ask the shell to change where any or all of those file descriptors point before launching the command; that’s what the redirection ( < , , >> ) and pipe ( | ) operators do.
The pipe is the simplest of these. command1 | command2 arranges for the standard output of command1 to feed directly into the standard input of command2 . This is a very handy arrangement that has led to a particular design pattern in UNIX tools (and explains the existence of standard error, which allows a program to send messages to the user even though its output is going into the next program in the pipeline). But you can only pipe standard output to standard input; you can’t send any other file descriptors to a pipe without some juggling.
The redirection operators are friendlier in that they let you specify which file descriptor to redirect. So 0>logfile appends standard error to the end of the file named logfile . If you don’t specify a number, then input redirection defaults to fd 0 ( < is the same as 0< ), while output redirection defaults to fd 1 ( >is the same as 1> ).
Also, you can combine file descriptors together: 2>&1 means «send standard error wherever standard output is going». That means that you get a single stream of output that includes both standard out and standard error intermixed with no way to separate them anymore, but it also means that you can include standard error in a pipe.
So the sequence >/dev/null 2>&1 means «send standard output to /dev/null » (which is a special device that just throws away whatever you write to it) «and then send standard error to wherever standard output is going» (which we just made sure was /dev/null ). Basically, «throw away whatever this command writes to either file descriptor».
When nohup detects that neither its standard error nor output is attached to a terminal, it doesn’t bother to create nohup.out , but assumes that the output is already redirected where the user wants it to go.
Why does ‘nohup command >& /dev/null’ seem to «work» in some shells?
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'
- 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
$ nohup gedit >& /dev/null & [1] 1223 $ ksh: /dev/null: bad file unit number
> 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?
nohup command , run independent tty your application.According to my memory, dash extended of ash , Debian ash , ash developed by OpenBSD 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.
@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?
@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.
You can use the following link for abstarct viewing of shells: unix.stackexchange.com/questions/45684/…
1 Answer 1
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 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.
redirects ls ‘s stdout and stderr to file , but if the file is 2 , you’ve got a problem as
means 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 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
How to Run Linux Shell Command / Script in Background
The usual style of executing a command on a Linux terminal is to simply run it and wait for it to gracefully exit. Once the command exits, you can then proceed to execute other commands in succession. This is what is known as running commands in the foreground. As the word suggests, you can visually see the output of the command on the terminal.
Sometimes, however, running commands in the foreground can present a set of challenges. The command can take too long to exit causing you to waste precious time and other times, it can be totally attached to the shell session leaving you stuck.
In such cases, running a command in the background is your best bet. You can send a command(s) to the background as you concurrently execute other commands in the foreground. This improves the efficiency of working on the terminal and saves you time.
In this guide, we focus on how you can run Linux shell command or script in the background.
Running shell command in background using (&) sign
To run a command or a script to the background, terminate it with an ampersand sign (&) at the end as shown.
NOTE: Ending the command with the ampersand sign does not detach the command from you. It merely sends it to the background of the current shell that you are using, the command will still print the output to STDOUT or STDERR which will prevent you from executing other commands on the terminal.
A better approach is to redirect the command to /dev/null and later append the ampersand sign at the end as shown
To confirm that the command was sent to the background, run the jobs command .
To terminate the background process, run the kill command followed by the PID of the process as follows. The -9 option terminates the process immediately.
Running shell command or script in background using nohup command
Another way you can run a command in the background is using the nohup command. The nohup command, short for no hang up, is a command that keeps a process running even after exiting the shell.
It does this by blocking the processes from receiving a SIGHUP (Signal Hang UP) signal which is a signal that is typically sent to a process when it exits the terminal.
To send a command or script in the background and keep it running, use the syntax:
$ nohup shell-script.sh &>/dev/null &
$ nohup ping google.com &>/dev/null &
Again, you can verify that the command is running in the background using the command:
Conclusion
In this guide, we have covered two ways of running commands or shell scripts in the background. We have seen how you can run commands in the background using the & sign and the nohup command.
How to run nohup and write its pid file in a single bash statement
You already have one ampersand after the redirect which puts your script in background. Therefore you only need to type the desired command after that ampersand, not prefixed by anything else:
nohup ./myprogram.sh > /dev/null 2>&1 & echo $! > run.pid
tried this, but getting a pidfile that’s 1 process behind for some odd reason. so if the pidfile says 123, the actual process ID is 124. Any ideas?
@Allen, because nohup forks and a new process is created for the actual command. And sometimes that may not be the exact next pid, e.g. during heavy forking of other processes.
@Zubair it’s basically suppressing all of the 1st command console messages by pointing both the error and the standard output to the null device. I’ve left it as it was there by the original request.
nohup ./myprogram.sh > /dev/null 2>&1 & echo $! > run.pid
@amit.codename13: Yes of course you can use it like nohup ./myprogram.sh > /dev/null 2>&1 & echo $! > run.pid I just placed it in 2 lines for understanding purpose only.
Grigor’s answer is correct, but not complete. Getting the pid directly from the nohup command is not the same as getting the pid of your own process.
root 31885 27974 0 12:36 pts/2 00:00:00 sudo nohup ./myprogram.sh root 31886 31885 25 12:36 pts/2 00:01:39 /path/to/myprogram.sh
To get the pid of your own process, you can use:
nohup ./myprogram.sh > /dev/null 2>&1 & echo $! > run.pid # allow for a moment to pass cat run.pid | pgrep -P $!
Note that if you try to run the second command immediately after nohup, the child process will not exist yet.