파이썬 스크립트에서 bash 명령을 실행하는 방법


답변:


16

@milne의 답변은 효과가 있지만 subprocess.call()약간의 피드백을 제공합니다.

나는 subprocess.check_output()stdout에 인쇄 된 것을 분석 할 수 있도록 사용하는 것을 선호합니다 .

 import subprocess
 res = subprocess.check_output(["sudo", "apt", "update"])
 for line in res.splitlines():
     # process the output line by line

check_output 호출 된 명령을 0으로 종료하면 오류가 발생합니다.

함수에 키워드 인수를 bash지정 하지 않으면 (이것도 shell마찬가지이며 subprocess.call(), 보안 위험을 부과하므로 필요하지 않아야하지는 않습니다) 직접 호출합니다. 명령.

파이썬에서 많은 (다른) 명령 호출을 발견하면 plumbum 을보고 싶을 것 입니다. 이를 통해 (IMO)를 더 읽기 쉽게 할 수 있습니다.

from plumbum.cmd import sudo, apt, echo, cut

res = sudo[apt["update"]]()
chain = echo["hello"] | cut["-c", "2-"]
chain()

( os.popen또는 os.system) 를 사용하는 것이 좋습니다 . 예 : res = os.popen('sudo apt update').read()? @Anthon
alper

1
@alper 0324 python.org/dev/peps/pep-0324를 읽으십시오 . 즉 만들기위한 이론적 설명하고 subprocess있지만 os.systemos.popen이미 존재합니다. 이러한 PEP는 사소한 것이 아닙니다. 여러 사람이 당신이나 내가 할 것보다 훨씬 더 많은 생각을했습니다. 그리고 subprocess2003 년 이후, 다른 사람은 단지 거기에 여전히 이전 버전과의 호환성을 위해 있습니다 향상되었습니다. 당신은 빨간색이 os.system매뉴얼 페이지 : 서브 프로세스 모듈은 새로운 프로세스를 산란하고 결과를 검색하기위한보다 강력한 기능을 제공합니다; 이 기능을 사용하는 것보다 해당 모듈을 사용하는 것이 좋습니다.
Anthon

1
@alper 네 가능합니다. 내가 지적한 바와 같이 잠재적 인 보안 위험이므로 권장되는 이유를 모르겠습니다. 그리고 호출 sudo은 더 심각하게 만들 것입니다. 어쩌면 python-apt를 사용하는 것이 더 좋은 해결책 일 것입니다 (나는 직접 보지 않았습니다).
Anthon

1
이 경우에서 심각한 표정 걸릴 @alper 납을 , 그와 속도를 점점 가치입니다.
Anthon

1
@alper Python3에 있다면 Python2에서는 그렇지 않습니다. 여기의 주석을 채팅 시스템으로 사용하지 마십시오. 질문이 있으시면 게시하십시오.
Anthon

8

bash를 명령으로 실행하기 위해 매개 변수 -c와 함께 프로그램으로 사용할 수 있습니다.

예:

bashCommand = "sudo apt update"
output = subprocess.check_output(['bash','-c', bashCommand])

7

서브 프로세스 모듈은이 작업을 수행 할 수 있도록 설계되었습니다 :

import subprocess
subprocess.call(["sudo", "apt", "update"])

명령이 실패하면 스크립트를 종료 check_call()하려면 리턴 코드를 직접 구문 분석하는 대신 사용하는 것이 좋습니다.

subprocess.check_call(["sudo", "apt", "update"])

이것은 나에게 다음 역 추적을 주었다 Traceback (most recent call last): File "/home/Dremor/test.py", line 3, in <module> subprocess.call('sudo', 'yum', 'update') File "/usr/lib64/python3.4/subprocess.py", line 537, in call with Popen(*popenargs, **kwargs) as p: File "/usr/lib64/python3.4/subprocess.py", line 767, in __init__ raise TypeError("bufsize must be an integer") TypeError: bufsize must be an integer (I 메인 OS로 페도라를 사용하고 나는이 yum을 사용하고 있습니다)
Dremor

3
당신은 대괄호를 잊었다
Milind Dumbare

1
또한 subprocess.call()차단하는 subprocess.Popen()것은 비 차단입니다 ..
heemayl

"차단"은 무슨 뜻입니까? @heemayl
alper

2

또한 'os.popen'을 사용할 수 있습니다.

예:

import os

command = os.popen('ls -al')
print(command.read())
print(command.close())

산출:

total 16
drwxr-xr-x 2 root root 4096 ago 13 21:53 .
drwxr-xr-x 4 root root 4096 ago 13 01:50 ..
-rw-r--r-- 1 root root 1278 ago 13 21:12 bot.py
-rw-r--r-- 1 root root   77 ago 13 21:53 test.py

None

0

서브 프로세스 모듈 사용

import subprocess
command = 'sudo apt update'
subprocess.check_call(command.split())

내가 그것을 사용할 때 왜 오류가 발생합니까
aquagremlin

subprocess.check_call ([ "sudo", "apt", "update"])
aquagremlin

CalledProcessError Traceback (가장 최근 호출) <module> () ---->의 1 개의 <ipython-input-21-33ce645708e7> subprocess.check_call ([ "sudo", "apt", "update"]) / usr / check_call (* popenargs, ** kwargs)의 lib / python2.7 / subprocess.pyc cmd가 없음 인 경우 188 : 189 cmd = popenargs [0]-> 190 raise CalledProcessError (retcode, cmd) 191 return 0 192 CalledProcessError : Command '['sudo ','apt ','update ']'는 0이 아닌 종료 상태 1을 반환했습니다.
aquagremlin

이 오류는 jupyter 노트북에서 실행할 때만 발생합니다
aquagremlin

어쩌면 나는 새로운 질문을 시작합니다 어쩌면
aquagremlin
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.