我有一个程序,它可以生成有用的信息stdout
,也可以从中读取信息stdin
。我想将其标准输出重定向到一个文件,而不在标准输入上提供任何内容。到目前为止,一切顺利:我可以做到:
program > output
并且不要在 tty 中执行任何操作。
但是,问题是我想在后台执行此操作。如果我做:
program > output &
程序将被挂起(“挂起(tty 输入)”)。
如果我做:
program < /dev/null > output &
程序立即终止,因为它到达 EOF。
看来我需要的是通过管道输入program
一些在不确定的时间内不执行任何操作并且不读取的内容stdin
。以下方法有效:
while true; do sleep 100; done | program > output &
mkfifo fifo && cat fifo | program > output &
tail -f /dev/null | program > output &
然而,这一切都非常丑陋。那里有使用标准 Unix 实用程序,以一种优雅的方式“无限期地什么都不做”(释义man true
)。我怎样才能做到这一点? (我在这里优雅的主要标准:没有临时文件;没有忙等待或定期唤醒;没有奇异的实用程序;尽可能短。)
答案1
我不认为你会变得比
tail -f /dev/null
您已经建议了(假设这在内部使用 inotify,不应该有轮询或唤醒,所以除了看起来很奇怪之外,它应该足够了)。
您需要一个将无限期运行的实用程序,将保持其标准输出打开,但实际上不会向标准输出写入任何内容,并且在其标准输入关闭时不会退出。类似的东西yes
实际上写入了标准输出。 cat
将在其标准输入关闭时退出(或者您重定向到其中的任何操作完成)。我认为sleep 1000000000d
可能可行,但tail
显然更好。我的 Debian 盒子有一个tailf
可以稍微缩短命令的命令。
采取不同的策略,在 下运行程序怎么样screen
?
答案2
sleep infinity
是我所知道的最清晰的解决方案。
您可以使用infinity
,因为sleep
接受浮点数*,这可能是小数,十六进制,无穷, 或者南, 根据man strtod
。
* 这不是 POSIX 标准的一部分,因此不像tail -f /dev/null
.但是,它在 GNU coreutils (Linux) 和 BSD(在 Mac 上使用)中受支持(显然较新版本的 Mac 不支持 - 请参阅评论)。
答案3
sleep 2147483647 | program > output &
是的,2^31-1
是有限数量,并且不会运行永远,但当睡眠最终超时时我会给你 1000 美元。 (提示:到那时我们中的一个人就会死了。)
- 没有临时文件;查看。
- 没有忙等待或周期性唤醒;查看
- 没有外来的公用事业;查看。
- 尽可能短。好吧,还可以再短一点。
答案4
您可以创建一个可执行此操作的二进制文件:
$ echo 'main(){pause();}'| gcc -Wno-all -xc - -o pause
我觉得这很优雅,因为pause
系统调用实际上是一个系统调用,其唯一目的是永远不执行任何操作(或直到信号杀死进程)而无需忙等待,将其作为其他操作的副作用或不告诉父进程(父进程可以优雅地非阻塞地阻止waitpid
其子进程发出信号,许多(尤其是 shell)都这样做,而等待子进程在非信号引发的系统调用中被阻塞则相当困难) 。