nohup command &
can keep a command running after closing the terminal.
I want to play all mp3 music in directory Music
.
ls Music/*mp3 |xargs -d "\n" mplayer
ls Music/*mp3
can list all mp3 files in directory Music
, send it via pipe with xargs, -d "\n"
is to treat blanks in the filenames.
I want to redirect all stdout
and stderr
into /dev/null
, and run it in the background.
ls Music/*mp3 |xargs -d "\n" mplayer > /dev/null 2>&1 &
This works fine, but I want it running after closing the terminal.
nohup ls Music/*mp3 | xargs -d "\n" mplayer > /dev/null 2>&1 &
ls Music/*mp3 | xargs -d "\n" nohup mplayer > /dev/null 2>&1 &
ls Music/*mp3 | nohup xargs -d "\n" mplayer > /dev/null 2>&1 &
When I close the terminal, the process running in the background ends.
Why does nohup
not take effect in any of the above three commands? How can I make it take effect?
disown
can solve the issue, but I would like a solution using nohup
.
ls Music/*mp3 | xargs -d "\n" mplayer > /dev/null 2>&1 & disown
nohup command syntax: & : nohup does not automatically put the command it runs in the background; you must do that explicitly, by ending the command line with an & symbol. exit : after nohup and & start the command in the background, you will still have to type exit or CTRL-D to go back to bash cursor.
The nohup command can also be used to run programs in the background after logging off. To run a nohup command in the background, add an & (ampersand) to the end of the command.
Run ping command with nohup command. Re-open the terminal and run pgrep command again. You will get the list of the process with process id which is running. You can stop any background process by running kill command.
When using nohup and you put the task in the background, the background operator ( & ) will give you the PID at the command prompt. If your plan is to manually manage the process, you can save that PID and use it later to kill the process if needed, via kill PID or kill -9 PID (if you need to force kill).
nohup command
means "run command
and ignore HUP signals".
So before we can effectively use nohup
we need to ask: when and how is SIGHUP
sent? As the Bash manual says, "Before exiting, an interactive shell resends the SIGHUP to all jobs, running or stopped.". It goes on to say that the proper way to suppress this behavior is with disown
. I realize you are asking about nohup
, but it's worth calling out that disown
is the intended and easier way to accomplish what you want. Note that disown
is not equivalent to nohup
.
The reason nohup
is tricky to work with here is because it applies to a single process, whereas &
creates a background job of a whole command pipeline, which can consist of multiple processes. This means you need to nohup
each command in the pipeline in order to ensure that the individual commands don't receive a SIGHUP, e.g.:
$ nohup ls Music/*mp3 2>/dev/null | nohup xargs -d "\n" nohup mplayer &> /dev/null &
This should work, though I haven't tested it with these specific commands. If it doesn't, it's likely another process that you aren't starting directly is still receiving a SIGHUP. This is harder to address, which is exactly why we have disown
.
manishg's suggestion is also reasonable; by moving the pipeline into a separate process you can nohup
that process, which should in turn prevent a SIGHUP from reaching its children when your shell closes.
All that said, you don't need ls
and xargs
here in the first place; find
can be used to similar effect and will simplify reasoning about the command. Try:
$ nohup find Music -maxdepth 1 -name '*mp3' -exec mplayer {} + &> /dev/null &
I want to play all mp3 music in directory Music.
Usually, you don't need ls
or xargs
for that.
You can simplify your whole pipeline to mplayer Music/*mp3
✱.
This is not only safer for special filenames, but also solves your problem with nohup
:
nohup mplayer Music/*mp3 &> /dev/null &
✱ There is only one case where this command fails and `ls * | xargs` succeeds. If you have a very large number of mp3 files you might run into the command line length limit. The limit in bytes is given by `getconf ARG_MAX`. On my system it is 2097152, meaning you would need at least 8000 files assuming a maximum file name length of 255 bytes. With shorter file names, you can have even more files. For instance, if your mp3 files are usually around 40 bytes long, you can use more than 44000 files.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With