I'm trying to write a Linux shell script (preferably bash),
supposedly named detach.sh
, to safely detach programs from a terminal,
such that:
Invocation: ./detach.sh prog [arg1 arg2 ...]
.
Is exec
-able, eg. by running this in your shell:
exec ./detach.sh prog [arg1 arg2 ...]
With proper quoting (mainly handling of arguments containing whitespaces).
Discards the outputs (since they are unneeded).
Does not use screen
, tmux
, etc.
(same reason with 4, plus no need for an extra babysitting process).
Uses (reasonably) portable commands and programs,
and no things like start-stop-daemon
which is quite distro-specific.
I have thought of several ways (shebang lines #!/bin/bash
neglected
for the sake of briefness):
nohup
:
nohup "$@" >& /dev/null &
disown
:
"$@" >& /dev/null &
disown
setsid
:
setsid "$@" >& /dev/null &
Using a subshell:
("$@" >& /dev/null &)
nohup
/setsid
combined with subshell:
# Or alternatively:
# (nohup "$@" >& /dev/null &)
(setsid "$@" >& /dev/null &)
When using gedit
as the test program (substituting the "$@"
part),
condition 1 can be satisfied with all the above methods,
but condition 2 can be satisfied with none.
However, if an arbitrary program (but not a shell builtin) is appended to script 5,
all the conditions seem to be satisfied (at least for me in the gedit
case).
For example:
(setsid "$@" >& /dev/null &)
# Not just `true' because it is also a shell builtin.
/bin/true
Anyone with an idea about an explanation of the above phenomenons
and how to correctly implement the requirements?
EDIT:
With condition 2, I mean the program should be detached from the terminal but runs as usual otherwise. For example, with the gedit
case, the condition fails if gedit
just exits immediately right after the process of the script has ended.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…