将空 STDIN 模拟为分离命令

Asa*_*vic 4 nohup stdin

我想用'command &'最后或'nohup command &'来分离命令,但它在分离后立即停止。

命令很少具体,如果它在输入时收到 eof,它会中断,因此 /dev/null 作为输入将导致结束和通常有效的解决方案:

$ command < /dev/null > /dev/null 2>&1 &
Run Code Online (Sandbox Code Playgroud)

不工作...

unix/linux 中是否有其他设备可以替换 /dev/null 并表现得像空输入,但不发送 eof。

(顺便说一句,命令是非常有用的多播工具emcast,我可以尝试自己修补它,或者为此目的找到修补版本......但似乎问题可以在外面解决)

我正在添加此 EDIT 以使我的问题更清楚。我制作了 2 行完美运行的 C 程序:程序名称是“donothing”

#include <unistd.h>
int main() {  while (1)  { sleep(10); } return 0; }
Run Code Online (Sandbox Code Playgroud)

这就是我正在寻找的,一些设备/程序,什么都不做,但保持其标准输出打开。两者(“command & ... disown”和“nohup command &”)都有效。

$ donothing | mycommand >/dev/null & 
$ disown %1
Run Code Online (Sandbox Code Playgroud)

效果很好,所以现在的问题只是:什么 unix 设备/程序表现得像我的“无所事事”。

Sté*_*las 9

为了您的命令检测eof,它必须从标准输入读取。所以大概它期待一些输入。所以听起来你需要的不是一个空的输入(/dev/null正是为此),而是永远不会出现的输入。

它可以用一个管道模拟,没有人会在另一端写入,例如:

sleep 999999999 | the-command
Run Code Online (Sandbox Code Playgroud)

或者为了避免运行额外的sleep命令,可以使用命名管道来完成:

fifo=$(mktemp -u) &&
  mkfifo "$fifo" &&
  (rm "$fifo" && the-command <&3 3<&- &) 3<> "$fifo"
Run Code Online (Sandbox Code Playgroud)

这里使用一个中间文件描述符来解决这样一个事实,即/dev/null当您启动命令时,shell隐式地将 stdin 连接到&(除非您像我们<&3在这里添加一个显式的 stdin 重定向)。

在 Linux 上(可能只在 Linux 上),您还可以执行以下操作:

the-command < /dev/fd/1 3>&1 > /dev/null | :
Run Code Online (Sandbox Code Playgroud)

/dev/fd/1其中 fd 1 连接到管道,在 Linux 上,其行为类似于命名管道。也就是说,当您以读取模式打开它时,您将获得管道的读取端。

因此,上面的 fd 0 将连接到管道的读取端,该管道的另一端位于 的 fd 3 上the-command。因为the-command不会在其 fd 3 上写入任何内容,所以read对 fd 0 的任何尝试都将被阻塞(或者非阻塞读取将返回但没有任何内容可读取,或者选择/轮询将不会返回任何可读取的内容,就像the-command可能正在做的那样如果它正在做其他事情而不是等待永远不会到来的输入)。