在编写一个Linux shell脚本从终端安全地分离方案 [英] On writing a Linux shell script to safely detach programs from a terminal
问题描述
我试图写一个Linux shell脚本(preferably的bash)
据称名为 detach.sh
,安全地从终端分离方案,
使得:
I'm trying to write a Linux shell script (preferably bash),
supposedly named detach.sh
, to safely detach programs from a terminal,
such that:
-
调用:
./ detach.sh PROG [ARG1 ARG2 ...]
是 EXEC
-able,例如。通过在shell中运行这样的:
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).
不使用屏幕
, TMUX
等。
(同样的原因有4个,再加上无需额外保姆的过程)。
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 &
不认
:
"$@" >& /dev/null &
disown
setsid
:
setsid "$@" >& /dev/null &
使用子shell:
Using a subshell:
("$@" >& /dev/null &)
的nohup
/ setsid
合并子shell:
nohup
/setsid
combined with subshell:
# Or alternatively:
# (nohup "$@" >& /dev/null &)
(setsid "$@" >& /dev/null &)
在使用的gedit
作为测试程序(代替$ @
部分),
条件1能够满足上述所有方法,
但条件2都能得到满意的没有。
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.
然而,如果一个任意的节目(但不是壳内建)将被附加到脚本5,
所有的条件似乎满足(至少对我来说在的gedit
情况)。
例如:
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?
编辑:
使用条件2,我的意思是程序应该从终端拆下但像往常一样,否则运行。例如,在的gedit
情况下,状态如果的gedit
恰到好处后脚本的进程立即退出失败结束了。
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.
推荐答案
经仔细调查,这些previously被忽视的事实被揭露:
Upon closer investigation, these previously unnoticed facts were revealed:
-
这两个脚本3和5(
setsid
变种只)会
满足所有条件,如果/斌/真
追加到该脚本。
Both scripts 3 and 5 (the
setsid
variant only) will satisfy all the conditions if a/bin/true
is appended to the script.
这些脚本,其实1修改,将工作,以及如果 /斌/真
替换为我在{0..9999};这样做:;做
。
These scripts, as modified in fact 1, will work as well if
/bin/true
is replaced with for i in {0..9999}; do :; done
.
因此,我们可以得出这样的结论:
Therefore we can conclude that:
-
(从事实1)
(From fact 1)
分离的多级(如在脚本5)是不必要的,
关键是要使用正确的工具( setsid
)。
Multiple levels of detaching (as in script 5) is unnecessary,
and the key is to use the right utility (setsid
).
(从事实2)
庆典退出前的适当延时是必要的脚本的成功。
(调用外部程序 /斌/真
消耗一定的时间,
就像纯bash的时间消费为我在{0..9999};这样做:;做
)
A suitable delay before bash exit is necessary for the success of the script.
(Calling external program /bin/true
consumes some time,
just like the pure-bash time consumer for i in {0..9999}; do :; done
.)
我没有看过源$ C $ C,但我想一个可能的解释
是的bash之前可能 setsid
退出完成配置执行
该方案的环境下运行,如果不施加适当的延迟
I have not looked at the source code, but I guess a possible explanation
is that bash may exit before setsid
finishes configuring the execution
environment of the program to run, if an appropriate delay is not applied.
最后,最佳的解决方案应
And finally, an optimal solution should be
#!/bin/bash
setsid "$@" >& /dev/null &
sleep 0.01
修改
一个延迟的必要性已经在这里解释。非常感谢@wilx!
The necessity of a delay has been explained here. Many thanks to @wilx!
这篇关于在编写一个Linux shell脚本从终端安全地分离方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!