在编写一个Linux shell脚本从终端安全地分离方案(On writing a Linux sh

2019-06-23 19:54发布

我试着写一个Linux shell脚本(最好是bash)的,按说命名detach.sh ,安全地分离从终端程序,使得:

  1. 调用: ./detach.sh prog [arg1 arg2 ...]

  2. exec -able,例如。 通过在shell中运行这个:

     exec ./detach.sh prog [arg1 arg2 ...] 
  3. 通过适当的引用(主要是处理含有空格参数)。

  4. 丢弃该输出(因为它们是不需要的)。

  5. 不使用screentmux等(同样的原因有4个,再加上无需额外的保姆的过程)。

  6. 用途(合理的),便携命令和程序,以及不一样的东西start-stop-daemon这是相当发行特定的。

我想到了几种方法(家当线#!/bin/bash忽视为了简洁起见):

  1. nohup

     nohup "$@" >& /dev/null & 
  2. disown

     "$@" >& /dev/null & disown 
  3. setsid

     setsid "$@" >& /dev/null & 
  4. 使用子shell:

     ("$@" >& /dev/null &) 
  5. nohup / setsid与子外壳组合:

     # Or alternatively: # (nohup "$@" >& /dev/null &) (setsid "$@" >& /dev/null &) 

当使用gedit作为测试程序(代替"$@"的部分),条件1可以得到满意的所有上述方法中,但条件2可以得到满意没有。

但是,如果一个任意程序(但不是shell内建)追加到脚本5,所有条件似乎成立时(至少对我来说在gedit的情况下)。 例如:

(setsid "$@" >& /dev/null &)
# Not just `true' because it is also a shell builtin.
/bin/true

任何有关上述现象的解释和如何正确地实现这些需求的想法?

编辑:

与条件2,我的意思是该程序应该从终端拆下但像往常一样运行,否则。 例如,用gedit情况下,条件如果失败gedit只是退出脚本的过程结束后,立即权利。

Answer 1:

经仔细调查,这些以前被忽视的事实被揭露:

  1. 这两个脚本3和5( setsid变体仅)将满足所有的条件,如果/bin/true被附加到该脚本。

  2. 这些脚本,其实1修改,也能发挥作用,如果/bin/true被替换for i in {0..9999}; do :; done for i in {0..9999}; do :; done for i in {0..9999}; do :; done

因此,我们可以得出这样的结论:

  • (来自实际上1)

    分离(如脚本5)的多层次是不必要的,关键是要使用正确的工具( setsid )。

  • (来自实际上2)

    庆典退出前的适当延时是必要的脚本的成功。 (调用外部程序/bin/true消耗一些时间,就像纯bash的时间消费for i in {0..9999}; do :; done 。)

    我没有看过的源代码,但我想一个可能的解释是,庆典之前可能会退出setsid完成配置要运行的程序,如果不施加适当延迟的执行环境。

最后,最佳的解决方案应该是

#!/bin/bash
setsid "$@" >& /dev/null &
sleep 0.01

编辑1:

延迟的必要性已经说明了这里 。 非常感谢@wilx!

编辑2:

(感谢@MateiDavid),我们似乎已经忘记了重定向标准输入,以及更好的方式是:

#!/bin/bash
setsid "$@" >& /dev/null < /dev/null &


Answer 2:

我认为你需要做setsid "$@" >& /dev/null & wait ,使之前的控制终端不会消失setsid管理到餐桌的孩子。

UPDATE

在我看来,这是双向的命令行和作为参数-c

(setsid tail -F /var/log/messages >& /dev/null) & disown


Answer 3:

您正在试图建立一个UNIX守护进程(即没有控制终端的过程,这是它自己的会议领导者)。 该setsid命令应该为你做这个,但你是负责关闭所有文件描述符你放弃终端上打开。 这可以通过将其重定向到完成/dev/null或使用shell的语法用于关闭文件描述符(例如, 2>&-0<&-在击)。



文章来源: On writing a Linux shell script to safely detach programs from a terminal