如何从命令行分离控制终端?

如何从命令行分离控制终端?

我知道nohup它不会做我想要的事情:

例子:

$ nohup sleep 600 2>/dev/null >/dev/null </dev/null&
[1] 21844
$ ps -ef | fgrep -e 'sleep
> TTY'
UID        PID  PPID  C STIME TTY          TIME CMD
me       21844 19313  0 09:37 pts/9    00:00:00 sleep 600

如您所见,sleep 仍然具有pts/9控制终端。我不希望它有任何控制终端。部分原因是我想要使用的程序(sleep如果您还没猜到的话,它不是)尝试打开控制终端来向我提问,我想看看如果不能打开控制终端会如何表现。我该如何实现这一点?

答案1

这是一个 FreeBSD 解决方案,但也许类似的技术也适用于您的操作系统。

我知道 cron 并不是真正的命令行,但如果您想要运行特定的命令列表,cron 可以做到这一点。您可能希望避免让 cron 重复运行该作业,也许可以通过围绕所需的命令列表制作包装器来实现,例如:

#!/bin/sh
[ -f /tmp/my-semaphore-file ] || {
  touch /tmp/my-semaphore-file
  my_command_stack > /dev/null 2>&1
}

对于生产用途来说,这可能不够优雅,但如果您只是想在没有控制终端的情况下测试命令堆栈的执行情况,那么这样做就足够了。包装器将不允许 cron 再次运行命令,直到您执行以下操作:

rm /tmp/my-semaphore-file

at(1)也是一种选择,并且“几乎”是一个命令行解决方案:

echo 'my_command_stack > /dev/null 2>&1' | at now+1 minute

答案2

Linux 上的实用程序可以做到这一点。在 Fedora 上,setsid它是软件包的一部分。这是包含诸如、、和其他类似内容util-linux的同一软件包。mountmkfs/usr/bin/kill

答案3

您还需要使用disown来将进程从 tty 中分离。

https://unix.stackexchange.com/questions/3886/difference-between-nohup-disown-and

尝试运行 nohup sleep 600 2>/dev/null >/dev/null </dev/null& disown并查看是否能得到期望的结果。

相关内容