I'd like to run and configure a process similarly to a daemon from a script.
My shell is zsh emulated under Cygwin and the daemon is SFK, a basic FTP server.
For what matters here, the script startserv.sh
can be drafted as follows:
#!/bin/sh
read -s -p "Enter Password: " pw
user=testuser
share=/fshare
cmd="sfk ftpserv -user=$user -pw=$pw -usedir $share=$share"
$cmd &
After running the script startserv.sh
, it stops (ends?) without showing any prompt, then:
-
CTRL+C ends both the script and the background job process;
-
Hitting Enter the script ends the process remains in the background.
Anyway I can see it only via ps
and not jobs
, so, when I want to close the process, I have to send a brutal kill -9
signal, which is something I'd like to avoid in favour of CTRL+C.
An alternative would be running the whole script in background. 'Would be', but the read
command is unable get the user input if the script is run as startserv.sh &
.
Note that I need an ephemeral server, not a true daemon: that is, I want the server process to run in the background, after the script ends, to perform simple interactive shell tasks (with a virtual machine guest), but I don't need the process to survive the shell; therefore nohup
seems not appropriate.
Best Answer
Almost! Actually, the script has already exited by the time you press Enter. However, that's how you can get your prompt back (because your shell prints its
$PS1
all over again).The reason why hitting Ctrl + C terminates both of them is because the two of them are linked. When you execute your script, your shell initiates a subshell in which to run it. When you terminate this subshell, your background process dies, probably from a
SIGHUP
signal.Separate the script, the background process and the subshell
Using
nohup
, you might be able to get rid of this little inconvenience.The
disown
alternativeIf you can switch from
/bin/sh
to/bin/bash
, you can give a try todisown
as well. To know more, just typehelp disown
in abash
instance.Killing the background process "nicely"
Now, when it comes to killing your process, you can perfectly do a "Ctrl + C" using
kill
. Just don't send a brutalSIGKILL
. Instead, you could use:Which will send a nice
SIGINT
(2) orSIGTERM
(15) to your process. You may also want to print the PID value after starting the process:... or even better, make the script wait for a
SIGINT
, and send it back to the background process (this will keep your script in the foreground though):If a
SIGINT
isn't enough, just use aSIGTERM
instead (15) :This way, when your script receives a
SIGINT
(Ctrl + C,kill -2
) or aSIGTERM
whilewait
ing for the background process, it'll just relay the signals to it. If these signals do kill thesfk
instance, then thewait
call will return, therefore terminating your script as well :)