2016-06-03 9 views
2

나는 bash 셸에서 python3으로 변환하는 데 어려움을 겪고 있습니다.subprocess.Popen()을 사용하여 bash 셸에서 python3으로 변환

는 여기에 내가 파이썬로 변환 할 쉘 명령입니다 :

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가 해로운 이유를 설명 할 수 :

다음은 작동하지 않았다 내 코드입니까? 나는 많은 해답에서 그것을 보았다. 그러나 이유를 모른다. ...

고맙다.

+1

http://stackoverflow.com/questions/3172470/actual-meaning-of-shell-true-in-subprocess는 왜 'shell = True'를 피하기를 원하는지 설명합니다. – tripleee

+0

@ 삼자 : 그리고 [이것은'shell = True'가 유용 할 수 있음을 보여줍니다.] (http://stackoverflow.com/q/295459/4279) (신뢰할 수없는 입력이 없다면 실수를 범할 확률이 더 높습니다 'subprocess.Popen'을 사용하여 쉘 파이프 라인을 직접 구현하는 것은 간단한 쉘 명령어의 비 호환성으로 인해 에러를 얻습니다). – jfs

+0

문제는 그것이 쓸모가 없다는 것입니다.하지만 그것을 사용하려면 이해가 필요합니다. 쉘은 심지어 PHP와 VBscript를 합친 것보다 절대적인 기초조차 모르게 더 많은 사용자를 비례하여 사용하는 불행한 영광을 안고 있습니다. (이 문제는 그 점에서 평균 이상으로 뚜렷하게 나타납니다.) – tripleee

답변

2

당신은 그래서

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

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

를가되어야 cat 에 파일의 목록을 통과해야 그리고 결과적으로 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) 
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() 

또는 심지어 단순히 (감사 @tripleee!) :

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

이 유일한 위험이 정말 경우입니다 귀하의 의견은 안전하지 않습니다. 작은 따옴표로 모든 입력을 인용하고 모든 입력을 이스케이프하고 소독하는 것이 좋습니다.

+0

'in'에 펑키 한 내용이 포함되어 있다면 쉘 해석에서 벗어나기 위해 추가 단계를 수행해야합니다. – tripleee

+0

'파일 (','r ')'은'files'가리스트 인 경우 오류를 던집니다. – tripleee

+0

그리고 일단 이러한 것들을 수정하면'subprocess.Popen'은 불편할뿐입니다. 대신'subprocess.call'을 사용하십시오. – tripleee