失败时杀死管道中的下一个命令 [英] Kill next command in pipeline on failure
问题描述
我有一个流式备份脚本,其运行如下:
I have a streaming backup script which I'm running as follows:
./backup_script.sh | aws s3 cp - s3://bucket/path/to/backup
aws
命令以原子方式将stdin流传输到云存储.如果在没有EOF的情况下中断了该过程,则上传将中止.
The aws
command streams stdin to cloud storage in an atomic way. If the process is interrupted without an EOF, the upload is aborted.
如果 ./backup_script.sh
以非零退出代码退出,我希望 aws
进程被终止.
I want the aws
process to be killed if ./backup_script.sh
exits with a non-zero exit code.
是否有执行此操作的bash技巧?
Any bash trick for doing this?
您可以使用以下脚本测试解决方案:
You can test your solution with this script:
#!/usr/bin/env python
import signal
import sys
import functools
def signal_handler(signame, signum, frame):
print "Got {}".format(signame)
sys.exit(0)
signal.signal(signal.SIGTERM, functools.partial(signal_handler, 'TERM'))
signal.signal(signal.SIGINT, functools.partial(signal_handler, 'INT'))
for i in sys.stdin:
pass
print "Got EOF"
示例:
$ grep --bla | ./sigoreof.py
grep: unrecognized option `--bla'
usage: grep [-abcDEFGHhIiJLlmnOoqRSsUVvwxZ] [-A num] [-B num] [-C[num]]
[-e pattern] [-f file] [--binary-files=value] [--color=when]
[--context[=num]] [--directories=action] [--label] [--line-buffered]
[--null] [pattern] [file ...]
Got EOF
我希望 ./sigoreof.py
以信号终止.
推荐答案
使用进程替换而不是命名管道的简短脚本为:
A short script which uses process substitution instead of named pipes would be:
#!/bin/bash
exec 4> >( ./second-process.sh )
./first-process.sh >&4 &
if ! wait $! ; then echo "error in first process" >&2; kill 0; wait; fi
它与fifo的工作原理非常相似,基本上是将fd用作IPC的信息载体,而不是文件名.
It works much like with a fifo, basically using the fd as the information carrier for the IPC instead of a file name.
两句话:我不确定是否需要关闭fd 4;我假设脚本退出后,外壳程序将关闭所有打开的文件.
Two remarks: I wasn't sure whether it's necessary to close fd 4 ; I would assume that upon script exit the shell closes all open files.
我无法弄清楚如何在流程替换中获取流程的PID(有人吗?至少在我的cygwin上,通常的 $!
无法正常工作.)因此,我求助于杀死组中的所有进程,这可能不是很理想的(但是我不确定语义).
And I couldn't figure out how to obtain the PID of the process in the process substitution (anybody? at least on my cygwin the usual $!
didn't work.) Therefore I resorted to killing all processes in the group, which may not be desirable (but I'm not entirely sure about the semantics).
这篇关于失败时杀死管道中的下一个命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!