如果有*任何*标准输入,我该如何解决程序失败的问题?

如果有*任何*标准输入,我该如何解决程序失败的问题?

例如,以下工作正常:

/usr/bin/program

它产生一些输出,并得到结果。

但如果我像这样调用它:

echo -n | /usr/bin/program

或这个

echo -n | bash -c "/usr/bin/program"

甚至这个:

echo -n | bash -c "wc -c; /usr/bin/program"

它产生一些输出行,然后失败。我无法访问该程序的源代码,因此我什至无法查看可能导致此行为的原因。

当我尝试从 python 脚本调用它时,我得到了同样的东西:

echo | python -c 'from subprocess import call; call("/usr/bin/program", shell=True)'

(没有“echo”前缀的版本工作正常)

我什至不知道为什么会发生这种情况。即使我没有明确指定程序应该从哪里读取,标准输入也会打开,所以这不应该是原因。

有什么办法可以解决这个问题吗?

编辑:

输出的最后四行strace- 唯一不同的行:

# without echo
select(1, [0], NULL, NULL, {0, 0})      = 0 (Timeout)
select(1, [0], NULL, NULL, {0, 0})      = 0 (Timeout)
select(1, [0], NULL, NULL, {0, 0})      = 0 (Timeout)
select(1, [0], NULL, NULL, {0, 0})      = 0 (Timeout)
...

# with echo
select(1, [0], NULL, NULL, {0, 0})      = 1 (in [0], left {0, 0})
write(4, "\0\0\0j\0\0\0\3\0\0\0\4\0\0\0\0\377\377\377\377", 20) = 20
write(3, "\0\0\0j\0\0\0\3\0\0\0\4\0\0\0\0\377\377\377\377", 20) = 20
exit_group(1)                           = ?

部分解决方案:

sleep 20 | /usr/bin/program

似乎program等待 stdin 发生某些事情,如果遇到换行符或 EOF 则退出(我们可以从selectstrace 输出中的调用中看到它 - 如果输入来自“真实”用户,它就会超时)。因此,我们需要一个程序,它不会向标准输入写入任何内容,同时仍保持打开状态 -sleep完成这项工作。

答案1

这是一个 Perl 单行代码,可以满足您的要求:

perl -e '$SIG{CHLD} = sub{exit 0}; open $fh, "|-", @ARGV or die; sleep 20 while 1;' /usr/bin/program

它本质上与神话*相同sleep forever | /usr/bin/program,除了它还监视程序完成,并在完成时立即退出。如果 /usr/bin/program 需要任何参数,您可以将它们添加到该行的末尾。

*sleep forever不起作用,但 GNU sleep 将永远休眠,如果你sleep inf!

相关内容