当ProgramA被外部进程(kill:9)杀死时,我无法重定向其输出(std / stderr)或将其保存到变量。
ProgramA:
select a.id as "a.id", a.name as "a.name", b.id as "b.id", b.name as "b.name"
from a left join b on a.id = b.id
['a.id', 'a.name', 'b.id', 'b.name']
未能保存到变量:
$ ./ProgramA arg1
This is on stderr
This is on stdout
Killed: 9
重定向到文件也不起作用:
$ ProgramA_Output=`ProgramA arg1`
$ echo "$ProgramA_Output"
$
保存/重定向输出的任何线索?
答案 0 :(得分:2)
这里最直接的原因是你的程序只是在输出到TTY时逐行刷新缓冲区;因此,当重定向到文件或FIFO时,在交付SIGKILL时它还没有刷新 - 并且由于SIGKILL无法被捕获或延迟,因此它没有机会执行刷新时间。
如果您使用的是GNU平台,则可以使用stdbuf
默认修改此行为:
stdbuf -o0 ./ProgramA arg1 >output.txt
...或...
output=$(stdbuf -o0 ./ProgramA arg1)
由于您知道在输出为tty时刷新(因为输出在没有重定向的情况下立即显示),您还可以使用unbuffer
(与expect
一起提供的工具)来模拟那个效果:
output=$(unbuffer ./ProgramA arg1)
但是,最可靠的做法是修改ProgramA
的源以在每次要确保完成的写操作之后显式执行刷新操作 - 并且在绝对需要时仅使用SIGKILL < / em>的。 (通常的做法是使用SIGTERM,等待相当长的一段时间,然后才使用SIGKILL)。