为什么 `> my.log 2>&1 &` 导致作业持续注销?

为什么 `> my.log 2>&1 &` 导致作业持续注销?

我用

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和 按顺序按AD。要重新连接屏幕,请键入:

screen -r <name>

像这样(在屏幕中运行任务),即使用户注销/断开连接它也会运行,最好的部分是您可以使用重新附加命令查看结果。

答案3

让我们将不朽进程与守护进程进行比较。守护进程不与任何用户或终端交互,并且当 init 终止时它也会终止(除非它被故意停止)。

您可以使用 nohup 并通过将 std.out 和 std.err 重定向到 /dev/null 来“创建守护程序”

nohup ping google.com 2> /dev/null > /dev/null - 这是不朽的。

相关内容