使用subprocess.Popen()从bash shell转换为python3

时间:2016-06-03 01:51:50

标签: python bash shell subprocess popen

我正在努力将bash shell转换为python3。

这是我要转换为python的shell命令:

cat $outDir/aDir/* | cut -f2 | sort -u > $outDir/outFile.txt

我已经使用subprocess.call()并且它有效但我想知道如何使用Popen()。

这是我的代码无效:

import subprocess
import glob

filePath = outDir + 'aDir/*'
outFilePath = outDir + '/outFile.txt'

fileList = []
for files in glob.glob(filePath):
    fileList.append(files)
with open(files, 'r') as inFile, open(outFilePath, 'w') as outFile : 
  p = subprocess.Popen(['cat'], stdin=inFile, stdout=subprocess.PIPE)   
  p2 = subprocess.Popen(['cut', '-f2'], stdin = p1.stdout, stdout=subprocess.PIPE)
  p3 = subprocess.Popen(['sort', '-u'], stdin = p2.stdout, stdout = outFile)

你能解释为什么shell=True有害吗?我在许多答案中看到了它,但不知道为什么......

谢谢。

2 个答案:

答案 0 :(得分:2)

您需要将文件列表传递给cat 所以

subprocess.Popen(['cat'], stdin=inFile, stdout=subprocess.PIPE)

应该成为

subprocess.Popen(['cat'] + [fileList], stdout=subprocess.PIPE)

因此不再需要inFile

所以,总而言之

import subprocess
import glob

filePath = outDir + '/aDir/*'
outFilePath = outDir + '/outFile.txt'

fileList = glob.glob(filePath)
with open(outFilePath, 'w') as outFile: 
  subprocess.Popen(['cat'] + [fileList], stdout=subprocess.PIPE)
  p2 = subprocess.Popen(['cut', '-f2'], stdin = p1.stdout, stdout=subprocess.PIPE)
  p3 = subprocess.Popen(['sort', '-u'], stdin = p2.stdout, stdout = outFile)

答案 1 :(得分:0)

如何使用shell=True并保留管道?

with open(files, 'r') as inFile, open(outFilePath, 'w') as outFile : 
  p = subprocess.Popen('cut -f2 | sort -u', shell=True, stdin=filePath, stdout=subprocess.PIPE)
  p.communicate()

甚至更简单:

p = subprocess.Popen("cat {} | cut -f2 | sort -u > '{}'".format(filePath, outFilePath), shell=True)
p.communicate()

或者,甚至 more 简单(感谢@tripleee!):

subprocess.call("cat {} | cut -f2 | sort -u > '{}'".format(filePath, outFilePath), shell=True)

对于shell=True,唯一的危险是如果您的输入不安全。我建议用单引号引用所有输入,并转义并清理所有输入。