程序被杀死时,Bash保存/重定向stdout和stderr

时间:2016-08-08 16:39:39

标签: bash redirect stdout

当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"

$

保存/重定向输出的任何线索?

1 个答案:

答案 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)。