Bash save/redirect 程序被杀死时的标准输出和标准错误
Bash save/redirect stdout and stderr when program is killed
当 ProgramA 被外部进程杀死(杀死:9)时,我无法重定向其输出(std/stderr)或将其保存到变量中。
程序A:
$ ./ProgramA arg1
This is on stderr
This is on stdout
Killed: 9
无法保存到变量:
$ ProgramA_Output=`ProgramA arg1`
$ echo "$ProgramA_Output"
$
重定向到文件也不起作用:
$ ProgramA arg1 > output.txt
$ cat ./output.txt
$
有任何保存/重定向输出的线索吗?
这里最可能的直接原因是您的程序仅在输出到 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 当绝对需要时。 (通常的做法是使用 SIGTERM,等待相当长的时间,然后才求助于 SIGKILL)。
当 ProgramA 被外部进程杀死(杀死:9)时,我无法重定向其输出(std/stderr)或将其保存到变量中。
程序A:
$ ./ProgramA arg1
This is on stderr
This is on stdout
Killed: 9
无法保存到变量:
$ ProgramA_Output=`ProgramA arg1`
$ echo "$ProgramA_Output"
$
重定向到文件也不起作用:
$ ProgramA arg1 > output.txt
$ cat ./output.txt
$
有任何保存/重定向输出的线索吗?
这里最可能的直接原因是您的程序仅在输出到 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 当绝对需要时。 (通常的做法是使用 SIGTERM,等待相当长的时间,然后才求助于 SIGKILL)。