异步运行时进程挂起

异步运行时进程挂起

我有一个想要开始的流程,但后来忘记了。同步运行时,看起来像

sudo -E lein run

这运行得很好,无限期。它是非交互式的。它在端口 80 启动一个 Web 服务器。但是当我运行时:

sudo -E lein run &

终端输出:

[4] 30236

几秒钟后:

[4] + 30236 suspended (tty input) sudo -E ../bin/lein run

我的进程应该在端口 80 启动 Web 服务器,但没有显示服务器。

问题: 我如何诊断发生了什么?我不认为标准输出和标准错误被打印,但我可能是错的。为什么进程会暂停?我可以lein run以另一种方式异步运行吗?

答案1

sudo命令期望能够通过 tty 与用户交谈。当您将其推入后台时,它会停止,因为它期望对 tty 进行独占访问,但不再具有独占访问权限。 (这是一个安全界面,可能需要密码,并且肯定会运行对用户帐户具有不同访问权限的程序。重要的是它对用户具有独占访问权限。)

您可以在 下运行您的程序screen,这给它一个虚拟 tty,不一定与“真实”tty 关联。

screen -md sudo -E lein run

答案2

后台进程无法从终端读取数据。如果它们尝试读取数据,则会被 SIGTTIN 暂停(t埃勒t类型放)信号。这一功能的原因是,如果多个进程尝试从终端读取数据,则每个字符基本上会随机进入其中一个进程,这不是有用的行为。因此,前台进程获取输入,而后台进程则不获取输入。

(我简化了一点。阅读控制终端终端访问控制如果您想要更精确的规范,但您很少会遇到需要比我上面写的更深入挖掘的情况。)

如果 sudo 尝试从终端读取数据以提示输入密码,它将被挂起。需要在前台运行sudo,然后切换到后台。

通常,您可以运行 shell,然后告诉它在后台执行命令。例如,对于su,您会这样做su -c 'lein run &'。但 sudo 的作者知道这是一个常见问题,因此有一个选项:-b选项传递给sudo

sudo -b -E lein run

类似地,ssh您可以-f在提示输入密码后使用进入后台。请注意,如果您这样做,您的后台进程将不再是 shell 作业。如果您想在后台运行该程序并忘记它,那就完美了。

相关内容