我已经编写了一个依赖于其他服务器响应的脚本(使用 wget
来提取数据),我希望它始终在后台运行,毫无疑问。我知道一种解决方案是只编写一个包装器脚本,它将调用我的脚本并附加一个 &
,但我想避免这种困惑。
有没有办法让 bash(或 zsh)脚本确定它是否被调用 ./foo.sh &
,如果没有,退出并重新启动自己?
最佳答案
后台进程的定义(我认为)是它有一个控制终端,但它不是该终端的前台进程组的一部分。我不认为任何 shell,甚至 zsh,都可以让您通过内置函数访问该信息。
在 Linux(可能还有其他 unices)上,ps
的 STAT
列包含一个 +
当进程是其终端前台的一部分时进程组。因此,对您的问题的字面答案是,您可以将脚本的内容放在 main
函数中并使用以下命令调用它:
case $(ps -o stat= -p $$) in
*+*) main "$@" &;;
*) main "$@";;
esac
但是您还是可以运行main "$@"&
。在 Unix 上,fork 很便宜。
但是,我强烈建议不要按照您的建议去做。这使得某人不可能运行您的脚本然后再做其他事情——人们希望能够编写 your_script; my_postprocessing
或 your_script && my_postprocessing
,但是 fork 脚本的主要任务使这成为不可能。考虑到调用脚本时有时会节省一个字符,因此不值得以这种方式显着降低脚本的用处。
如果您真的想让脚本在后台运行以便用户可以关闭他的终端,您将需要做更多的工作 — 您需要守护进程脚本,这不仅包括后台,还包括关闭所有打开终端的文件描述符,使进程成为 session 领导者等等。我认为这需要将您的脚本拆分为守护进程包装器脚本和主脚本。但是守护进程通常是为那些除非明确停止就永远不会终止的程序完成的,这不是您描述的行为。
关于bash - 可以检查它是否在调用时后台运行的 Shell 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3609999/