420

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?

alexwlchan
  • 5,699
  • 7
  • 38
  • 49
Ofer
  • 4,879
  • 6
  • 20
  • 26

9 Answers9

842

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 >/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 disowned 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.)

Explanation:

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<infile reads standard input from the file named infile, while 2>>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.

The /dev/null device works for input, too; if you run a command with </dev/null, then any attempt by that command to read from standard input will instantly encounter end-of-file. Note that the merge syntax won't have the same effect here; it only works to point a file descriptor to another one that's open in the same direction (input or output). The shell will let you do >/dev/null <&1, but that winds up creating a process with an input file descriptor open on an output stream, so instead of just hitting end-of-file, any read attempt will trigger a fatal "invalid file descriptor" error.

Mark Reed
  • 91,912
  • 16
  • 138
  • 175
  • 1
    Regarding `nohup`, " if the process later tries to read anything from standard input, it will pause, waiting for you to bring it back to the foreground and type something." seems incorrect. Instead, `nohup` [closes standard input (the program will not be able to read any input, even if it is run in the foreground. it is not halted, but will receive an error code or EOF).](http://unix.stackexchange.com/a/148698/674) – Tim Mar 01 '16 at 04:27
  • 2
    @Tim - that answer is correct for Linux, but not for BSD or OS X, on which `nohup` does *not* close standard input automatically. Note that `nohup` is not a shell builtin but a binary utility. – Mark Reed Mar 01 '16 at 04:52
  • nohup is part of coreutils. Do you mean the implementation of `nohup` is different for linux and for BSD or OS X? – Tim Mar 01 '16 at 05:01
  • 2
    Yes. The name "coreutils" refers to a GNU package. But BSD, OS X, SmartOS/Illumos, and many commercial Unixes - basically, those that have been around longer than GNU - have non-GNU core utilities. `awk` is different, `sed` is different, `nohup` is different... – Mark Reed Mar 01 '16 at 05:15
  • Why did you write "extra safe" by `/dev/null` http://unix.stackexchange.com/a/266247/ – Tim Mar 01 '16 at 06:12
  • I just meant "Extra sure to detach from the terminal". As for `0>/dev/null`, it will generally have the same effect as `>/dev/null <&1`, which I mentioned. – Mark Reed Mar 09 '16 at 04:56
  • "..completely detached from terminal": I run `soffice -invisible` from my script using the mentioned syntax and then sleep for 10. If I hit Ctrl-C during that period soffice stops. Replacing nohup with setsid made it work. – Marinos An Mar 21 '17 at 18:56
  • It's only detached from terminal if the program doesn't go out of its way to attach itself to the terminal. If the program explicitly opens `/dev/tty`, it can talk to the terminal regardless of where `stdin`, `stdout`, and `stderr` are pointed.In this case, though, since `setsid` fixes it, it sounds like it's attached to the process group containing your shell, rather than the terminal. – Mark Reed Mar 22 '17 at 02:04
  • 2
    This is the best. Works each of 3 ways perfectly ecplained for each own needs. THx – Kangarooo Jul 15 '17 at 00:53
91
nohup some_command > /dev/null 2>&1&

That's all you need to do!

11101101b
  • 7,679
  • 2
  • 42
  • 52
17

Have you tried redirecting all three I/O streams:

nohup ./yourprogram > foo.out 2> foo.err < /dev/null &
Aziz Shaikh
  • 16,245
  • 11
  • 62
  • 79
  • 2
    Shouldn't it be **`>`** /dev/null rather than < /dev/null? – Scott Chu Nov 24 '16 at 01:18
  • 3
    @ScottChu `< /dev/null` redirects the standard input for `nohup`. Linux does not require this but POSIX allows behavior where `nohup` cannot run on the background if it's standard input is connected to terminal. Examples of such systems are BSD and OS X. – Mikko Rantalainen Jan 25 '18 at 17:59
13

You might want to use the detach program. You use it like nohup but it doesn't produce an output log unless you tell it to. Here is the man page:

NAME
       detach - run a command after detaching from the terminal

SYNOPSIS
       detach [options] [--] command [args]

       Forks  a  new process, detaches is from the terminal, and executes com‐
       mand with the specified arguments.

OPTIONS
       detach recognizes a couple of options, which are discussed below.   The
       special  option -- is used to signal that the rest of the arguments are
       the command and args to be passed to it.

       -e file
              Connect file to the standard error of the command.

       -f     Run in the foreground (do not fork).

       -i file
              Connect file to the standard input of the command.

       -o file
              Connect file to the standard output of the command.

       -p file
              Write the pid of the detached process to file.

EXAMPLE
       detach xterm

       Start an xterm that will not be closed when the current shell exits.

AUTHOR
       detach was written by Robbert Haarman.  See  http://inglorion.net/  for
       contact information.

Note I have no affiliation with the author of the program. I'm only a satisfied user of the program.

Dan D.
  • 73,243
  • 15
  • 104
  • 123
7

Following command will let you run something in the background without getting nohup.out:

nohup command |tee &

In this way, you will be able to get console output while running script on the remote server: enter image description here

Clownfish
  • 97
  • 1
  • 3
4
sudo bash -c "nohup /opt/viptel/viptel_bin/log.sh $* &> /dev/null"  &

Redirecting the output of sudo causes sudo to reask for the password, thus an awkward mechanism is needed to do this variant.

samayo
  • 16,163
  • 12
  • 91
  • 106
Kjeld Flarup
  • 1,471
  • 10
  • 15
4

If you have a BASH shell on your mac/linux in-front of you, you try out the below steps to understand the redirection practically :

Create a 2 line script called zz.sh

#!/bin/bash
echo "Hello. This is a proper command"
junk_errorcommand
  • The echo command's output goes into STDOUT filestream (file descriptor 1).
  • The error command's output goes into STDERR filestream (file descriptor 2)

Currently, simply executing the script sends both STDOUT and STDERR to the screen.

./zz.sh

Now start with the standard redirection :

zz.sh > zfile.txt

In the above, "echo" (STDOUT) goes into the zfile.txt. Whereas "error" (STDERR) is displayed on the screen.

The above is the same as :

zz.sh 1> zfile.txt

Now you can try the opposite, and redirect "error" STDERR into the file. The STDOUT from "echo" command goes to the screen.

zz.sh 2> zfile.txt

Combining the above two, you get:

zz.sh 1> zfile.txt 2>&1

Explanation:

  • FIRST, send STDOUT 1 to zfile.txt
  • THEN, send STDERR 2 to STDOUT 1 itself (by using &1 pointer).
  • Therefore, both 1 and 2 goes into the same file (zfile.txt)

Eventually, you can pack the whole thing inside nohup command & to run it in the background:

nohup zz.sh 1> zfile.txt 2>&1&
Thyag
  • 1,217
  • 13
  • 14
1

You can run the below command.

nohup <your command> & >  <outputfile> 2>&1 &

e.g. I have a nohup command inside script

./Runjob.sh > sparkConcuurent.out 2>&1
Keet Sugathadasa
  • 11,595
  • 6
  • 65
  • 80
Prem S
  • 217
  • 3
  • 8
1

You can also write a handy script to run any program with any amount of arguments with nohup in the background:

#!/bin/bash

nohup "$@" > /dev/null 2>&1 &

Imagine the script name is nobg.sh you can execute the command then with:

./nobg.sh some-command -a -b some_arg

You can also move the script to a directory which is in the PATH and leave out the file extension to get the feel of a real Linux command:

nobg some-command -a -b some_arg

CRYTeX
  • 11
  • 2