我用
myscript > my.log 2>&1 &
运行脚本并收集其输出 - 这样当我注销时 - 脚本仍将运行。我要启动它myscript &
- 它将在注销后立即终止。
但这是一个奇怪的效果:所做> my.log 2>&1 &
的只是将 stderr 重定向到 stdout...
为什么> my.log 2>&1 &
导致作业持续注销?
答案1
通常,如果您将某些内容放在后台,即使其父 shell 退出后,它也会继续运行。事实上,我可以创建一个这样的测试用例:
/bin/sh -c 'while true; do echo hi; sleep 5; done' &
然后退出外壳并使用ps
我可以看到它仍然在运行,永远,直到我杀死它。
重定向输出和不重定向输出之间有一个区别:如果您不重定向输出并退出 shell,则 stdout/stderr 文件描述符将关闭,下次尝试写入它们时,写入操作将失败。如果您的脚本正在检查这一点,或者在-e
设置(错误时退出)选项的情况下运行,那么您的脚本将停止。将上述行为与此版本进行比较:
/bin/sh -c 'while true; do echo hi || exit 1; sleep 5; done' &
或者
/bin/sh -ec 'while true; do echo hi; sleep 5; done' &
如果您让它继续运行,退出 shell,然后使用ps
您会看到,当它尝试运行时,它将echo
失败并退出。
如果您要将输出重定向到文件,那么显然写入将不再失败并且脚本将继续运行。
答案2
与此无关> my.log 2>&1
。相反, final 的&
作用是在后台运行进程。输入命令后返回的行应显示一个数字,即process id
(pid)。如果需要,您可以在之后使用该数字与命令一起kill
终止进程。
尽管如此,对于你的情况,我会在screen
.您可以使用以下命令启动屏幕
screen -S <name>
然后执行你的命令。要脱离屏幕(返回到初始终端),您需要按CTRL
和 按顺序按A
和D
。要重新连接屏幕,请键入:
screen -r <name>
像这样(在屏幕中运行任务),即使用户注销/断开连接它也会运行,最好的部分是您可以使用重新附加命令查看结果。
答案3
让我们将不朽进程与守护进程进行比较。守护进程不与任何用户或终端交互,并且当 init 终止时它也会终止(除非它被故意停止)。
您可以使用 nohup 并通过将 std.out 和 std.err 重定向到 /dev/null 来“创建守护程序”
nohup ping google.com 2> /dev/null > /dev/null - 这是不朽的。