Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用subprocess.Popen()将bashshell转换为python3_Python_Bash_Shell_Subprocess_Popen - Fatal编程技术网

使用subprocess.Popen()将bashshell转换为python3

使用subprocess.Popen()将bashshell转换为python3,python,bash,shell,subprocess,popen,Python,Bash,Shell,Subprocess,Popen,我正在努力从bashshell转换到python3 下面是我要转换为python的shell命令: 我已经使用了subprocess.call(),它确实有效,但我想知道如何使用Popen()实现它 以下是我的代码,但它不起作用: import subprocess import glob filePath = outDir + 'aDir/*' outFilePath = outDir + '/outFile.txt' fileList = [] for files in glob.glo

我正在努力从bashshell转换到python3

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

我已经使用了
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
是有害的吗?我在很多答案中都看到了,但不知道为什么


谢谢。

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

应该成为

subprocess.Popen(['cat'] + [fileList], stdout=subprocess.PIPE)
因此,不再需要
infle

总而言之

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)

使用
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()
或者,更简单地说(谢谢!):


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

解释了为什么要避免
shell=True
@tripleee:and(如果没有不受信任的输入,那么在使用
subprocess.Popen
重新实现shell管道时,由于简单shell命令的不兼容性而导致错误的可能性更大)问题不在于它是无用的,而在于使用它需要理解。不幸的是,shell有幸拥有比PHP和VBscript加起来还要多的用户,他们甚至连基本知识都不懂。(这个问题在这方面明显高于平均水平。)如果中的
包含时髦的东西,您需要执行额外的步骤来将其从shell解释中转义出来。
打开(文件,'r')如果
文件
是一个列表,则只会抛出一个错误。一旦您解决了这些问题,
子流程.Popen
就是不方便的;使用
子流程。调用
。抱歉,
中的
应该是每个OP的示例的
文件路径
。还添加了
调用()
,非常好,谢谢!
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()
subprocess.call("cat {} | cut -f2 | sort -u > '{}'".format(filePath, outFilePath), shell=True)