If you just want to write a single y
to the stdin of the process, you can do this:
(echo y | nohup myprocess) &
If you want to keep writing y
for every prompt that comes up, the coreutil yes
exists for exactly this purpose -- it will keep writing whatever you tell it to to stdout. Its default is to output "y", so you can just:
(yes | nohup myprocess) &
but if you need something else you can pass it as an argument
remote log in to linux over the network via SSH ... log out of linux; type exit
in the putty SSH terminal
Can someone give me a practical scenario where nohup
would be used?
Sure. Assuming your shell is bash (see below why), instead of typing exit
or ^D
, type ~.
at the beginning of a line, which will cause your ssh client to disconnect:
$ ssh localhost
ssh$ sleep 3600 &
[1] 5765
ssh$ ~.
ssh$ Connection to localhost closed.
$ ps 5765
PID TTY STAT TIME COMMAND
You can use your program instead of sleep
; and instead of disconnecting via ~.
, you can kill your ssh client or crash the machine it runs on. You want your process to survive this? Use nohup
;-)
Breaking the connection will cause the server process which manages its other end to exit, causing the kernel (any Unix/Linux kernel) to tear down the pseudo-terminal ssh had created, and to send a SIGHUP
signal to the session leader (the bash shell), which according to the bash manual:
The shell exits by default upon receipt of a SIGHUP
. Before exiting,
an interactive shell resends the SIGHUP
to all jobs, running or
stopped. Stopped jobs are sent SIGCONT
to ensure that they receive the
SIGHUP
.
Many people confuse this bash feature with a) the regular job control thing implemented by the kernel, which will only send a SIGCONT
/SIGHUP
pair to the stopped, not to the running jobs [1] and b) another bash feature (shopt -s huponexit
) which causes a login bash shell to send a SIGHUP
to its jobs even when exiting normally (eg. via exit
).
[1] a stopped job is a job (= process group) which contains at least one stopped process. A process is stopped as an effect of the default action of a signal like SIGTSTP
, SIGSTOP
, SIGTTIN
or SIGTTOU
. Processes which are "sleeping" on a blocking system call like read
, nanosleep
, select
, etc are not considered stopped, but running.
Why nohup
may not always help
nohup
just sets the disposition of SIGHUP
to ignore and does some redirections, it does not guarantee that the process will not be killed by other ways.
a) If the nohup ..
job is stopped, an interactive bash will also send it a SIGTERM
signal, not just a SIGHUP
/SIGCONT
pair:
If an attempt to exit bash is made while jobs are stopped [...] the shell prints a warning message [...] If a second attempt to exit is made without an intervening command, the shell does not print another warning, and any stopped jobs are terminated.
[terminated = sent a SIGTERM
signal; this is another ksh/bash feature, not present in all shells]
All this can be worked around by simple tricks like double-forks and by creating a new session with setsid(1)
, but
b) systemd
may also "clean up" a logged-out session by forcefully killing (with SIGTERM
followed by SIGKILL
) any left-over processes if its KillUserProcesses
setting is on, which is the default in some distros.
Best Answer
nohup
runs an executable. You need to pass it an external command, i.e. an executable file. You can't callnohup
on a shell construct such as an alias, function or builtin.nohup
runs a new process, it doesn't run something inside the existing shell process (sincenohup
itself is a separate process), sonohup . …
doesn't make sense.nohup ./test.sh
is the correct way to run a shell script with nohup. Make sure that the script properly starts with a shebang line (#!/bin/sh
) and that the file is executable (chmod +x ./test.sh
).