Python subprocess中gsutil cp管道命令生成空文件问题及优化咨询
问题解答:单条subprocess命令实现GS存储桶文件过滤上传
为什么原单条命令会导致空文件?
你原命令里用管道连接> filename和gsutil cp,bash中管道的各个命令是并行启动的——也就是说gsutil cp会在grep还没写完filename的时候就尝试读取这个文件,此时文件可能还没有内容,最终导致上传的文件为空。而拆分两条命令时,第一条执行完成(文件完全写入)后才会执行第二条,所以能正常工作。
怎么用单条subprocess实现正确操作?
有两种靠谱的实现方式:
用
&&串行执行命令(保留中间文件)
把管道换成&&,确保前一个命令执行完成且成功后,再执行后续的上传命令:subprocess.call("/usr/bin/gsutil cat infile | grep '|N|' > filename && /usr/bin/gsutil cp filename gs://destination_bucket/destination_folder/filename", shell=True, executable="/bin/bash")&&会等待前面的过滤写入操作完成,再启动gsutil cp,避免了文件未写完就读取的问题。直接用管道传递内容(无需中间文件,更高效)
完全跳过本地文件,把grep的输出直接传给gsutil cp,利用gsutil支持从标准输入读取内容的特性(用-表示标准输入):subprocess.call("/usr/bin/gsutil cat infile | grep '|N|' | /usr/bin/gsutil cp - gs://destination_bucket/destination_folder/filename", shell=True, executable="/bin/bash")这种方式不需要写入本地磁盘,减少了IO开销,是更优的实现。
单条调用比两条调用性能更优吗?
- 如果用上述第二种无中间文件的单条命令,性能会明显优于两条命令:因为省去了本地文件的写入和读取操作,减少了磁盘IO的开销,数据直接在管道中传递。
- 如果用第一种保留中间文件的单条命令(
&&方式),性能和两条命令几乎没有差别:虽然减少了一次subprocess的启动开销,但这个开销非常小,主要的耗时还是文件过滤、写入和上传,和拆分两条命令的流程一致。
内容的提问来源于stack exchange,提问作者ddss12
相关产品推荐
相关产品推荐

