2016-11-17 1 views
3

내 우분투 터미널에서 실행 잘 작동물결표 (~)가 subprocess.Popen 작동하지 않습니다()

sudo dd if=/dev/sda of=~/file bs=8k count=200k; rm -f ~/file 

. 내가 비단뱀 subprocess.Popen()를 통해 실행하면

:

output, err = subprocess.Popen(['sudo', 'dd', 'if=/dev/' + disk, 'of=~/disk_benchmark_file', 'bs=8k', 'count=200k'], stderr=subprocess.PIPE).communicate() 
print err 

작동하지 않습니다. 내가 오류가 없습니다 :

DD는 '~/disk_benchmark_file'을 열지 못했습니다 : 그런 파일이나 디렉토리

나는 Popen() 호출 물결 ~/home/user에 변경하는 경우, 그것은 작동 !

왜 그렇게됩니까? 나에게 더 중요한 것은 어떻게 작동시킬 수 있습니까? 사용자 이름을 프로덕션에 사용할지 모르겠습니다.

+0

당신이'으로 시도 유무 :

['sudo', 'dd', 'if=/dev/' + disk, 'of=~/disk_benchmark_file', 'bs=8k', 'count=200k'] 

는 교체해야합니다 $ HOME'? – Will

답변

6

당신은 os.path.expanduser()와 그 경로 이름을 포장 할 필요가

['sudo', 'dd', 'if=/dev/' + disk, 'of=' + os.path.expanduser('~/disk_benchmark_file'), 'bs=8k', 'count=200k'] 
+0

이것은 정확하게 찾고 있던 것이 었습니다 :-) 그리고 그것은 효과가있었습니다! – RichArt

3

은 집의 쉘에있는 지름길입니다. 쉘이 명령을 해석하려면 Popen에 shell=True을 설정해야합니다.

셸 인수 (기본값은 False)는 셸을 실행할 프로그램으로 사용할 지 여부를 지정합니다. 쉘이 True 인 경우, 문자열로보다는 일련의

https://docs.python.org/2/library/subprocess.html

참고로 인수를 전달하는 것이 좋습니다,하지만이 일에 대한 몇 가지 경고가 있습니다.

+2

'shell = True'를 사용하지 마십시오. –

+1

좋은 설명 :-)'shell = True'가 권장되지 않으므로 해결책은 os.path.expand와 같을 것입니다. – RichArt

+0

감사합니다 @RichArt, 조심해서 사용하십시오. 그러나 대부분의 이유는 위생 보안 문제를 기반으로합니다. . 이것이 프로덕션 코드가 아니고 입력을 제어하는 ​​경우에는 잘해야합니다. 댄 D.와 같은 절대적인 것을 다루지 않는 한 – bravosierra99

4
import os 
import shlex 

outfile = os.path.expanduser('~/file') 
cmd_string = 'sudo dd if=/dev/sda of=%s bs=8k count=200k; rm -f %s' % (outfile, outfile) 
cmd_list = shlex.split(cmd_string) 

# Then use cmd_list as argument for Popen 

shlex.split은 표준 및 하위 프로세스에 command으로 사용되어야 목록을 생성하는 가장 안전한 방법입니다. 모든 예외를 처리하고 코드를 읽기 쉽도록 만들 수 있습니다.

을 사용하면 home을 찾을 수 있습니다.

>>> import os 
>>> os.path.expanduser('~/disk_benchmark_file') 
'/home/dan/disk_benchmark_file' 

을 코드에서의 발생을 :

+1

'os.path'는'expand' 메소드를 가지고 있지 않습니다. –

+1

나는 마음에 간다 .... :) –

+0

답장을 보내 주셔서 감사합니다. 멋지네요. – RichArt

관련 문제