我试图阻止上传到S3,以防任何先前的流水线命令失败,遗憾的是,这两种方法都没有按预期工作:
外壳管道
Collections.sort(list);
Collections.sort(list, new Comparator<String> (){
public int compare(String s1, String s2){
if(s1.toUpperCase().contains("DAY") && s2.toUpperCase().contains("DAY")
&& !s1.equalsIgnoreCase("DAY") && !s2.equalsIgnoreCase("DAY")){
try{
Integer i1 = Integer.valueOf(s1.split("\\/")[1]);
Integer i2 = Integer.valueOf(s2.split("\\/")[1]);
System.out.println(" s1 " + s1 +" and s2 "+ s2 +" compare --> "+s1.compareTo(s2));
if(s1.compareTo(s2) > 0){
return 1;
}else if(s1.compareTo(s2) < 0){
if(i1 > i2){
return 1;
}else{
return 0;
}
}else{
return 0;
}
}catch(Exception e){
return s1.compareTo(s2);
}
}else{
System.out.println("In else--");
return 0;
}
}
});
打开PIPE
for database in sorted(databases):
cmd = "bash -o pipefail -o errexit -c 'mysqldump -B {database} | gpg -e -r {GPGRCPT} | gof3r put -b {S3_BUCKET} -k {database}.sql.e'".format(database = database, GPGRCPT = GPGRCPT, S3_BUCKET = S3_BUCKET)
try:
subprocess.check_call(cmd, shell = True, executable="/bin/bash")
except subprocess.CalledProcessError as e:
print e
我试过这样的事情没有运气:
for database in sorted(databases):
try:
cmd_mysqldump = "mysqldump {database}".format(database = database)
p_mysqldump = subprocess.Popen(shlex.split(cmd_mysqldump), stdout=subprocess.PIPE)
cmd_gpg = "gpg -a -e -r {GPGRCPT}".format(GPGRCPT = GPGRCPT)
p_gpg = subprocess.Popen(shlex.split(cmd_gpg), stdin=p_mysqldump.stdout, stdout=subprocess.PIPE)
p_mysqldump.stdout.close()
cmd_gof3r = "gof3r put -b {S3_BUCKET} -k {database}.sql.e".format(S3_BUCKET = S3_BUCKET, database = database)
p_gof3r = subprocess.Popen(shlex.split(cmd_gof3r), stdin=p_gpg.stdout, stderr=open("/dev/null"))
p_gpg.stdout.close()
except subprocess.CalledProcessError as e:
print e
基本上....
if p_gpg.returncode == 0:
cmd_gof3r = "gof3r put -b {S3_BUCKET} -k {database}.sql.e".format(S3_BUCKET = S3_BUCKET, database = database)
p_gof3r = subprocess.Popen(shlex.split(cmd_gof3r), stdin=p_gpg.stdout, stderr=open("/dev/null"))
p_gpg.stdout.close()
...
即使有错误也会将数据流式传输到S3,例如当我故意更改gof3r
时 - > mysqldump
生成错误。
答案 0 :(得分:1)
管道中的所有命令同时运行,例如:
$ nonexistent | echo it is run
即使echo
命令不存在,nonexistent
也始终运行。
pipefail
会影响整个管道的退出状态 - 它不会让gof3r
退出errexit
无效,因为此处只有一个管道。如果您不想启动下一个管道,如果上一次迭代中的那个失败,则将break
放在异常处理程序中print e
之后。
p_gpg.returncode is None
正在运行时 gpg
。如果gof3r
失败则不希望gpg
运行,那么您必须首先将gpg的输出保存在其他位置,例如,在文件中:
filename = 'gpg.out'
for database in sorted(databases):
pipeline_no_gof3r = ("bash -o pipefail -c 'mysqldump -B {database} | "
"gpg -e -r {GPGRCPT}'").format(**vars())
with open(filename, 'wb', 0) as file:
if subprocess.call(shlex.split(pipeline_no_gof3r), stdout=file):
break # don't upload to S3, don't run the next database pipeline
# upload the file on success
gof3r_cmd = 'gof3r put -b {S3_BUCKET} -k {database}.sql.e'.format(**vars())
with open(filename, 'rb', 0) as file:
if subprocess.call(shlex.split(gof3r_cmd), stdin=file):
break # don't run the next database pipeline
答案 1 :(得分:0)
我有完全相同的问题,我用它来管理:
cmd = "cat file | tr -d '\\n'"
subprocess.check_call( [ '/bin/bash' , '-o' , 'pipefail' , '-c' , cmd ] )
回想一下,在我的代码中搜索,我也使用了另一种方法:
subprocess.check_call( "ssh -c 'make toto 2>&1 | tee log.txt ; exit ${PIPESTATUS[0]}'", shell=True )