파이썬에서 쉘 명령 실행


65

현재 침투 테스트 와 Python 프로그래밍을 공부하고 있습니다. 파이썬에서 Linux 명령을 실행하는 방법을 알고 싶습니다. 실행하려는 명령은 다음과 같습니다.

echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080

난 그냥 사용하는 경우 print당신은 스스로를 입력하고 눌러 것처럼 그것을 실행과 동일 할 것 터미널에서 파이썬과 실행 Enter?


5
os.system 이이를 수행 할 수 있습니다.
fooot

2
그리고 나는 bash부풀어 오른 껍질 이라고 생각했다 ...
mikeserv

3
모듈 os.system사용 을 권장하는 문서 subprocess
jordanm

iptables의 출력이 필요합니까?
Kira

3
이 질문은 Stackoverflow로 마이그레이션해야합니다.
www139

답변:


106

다음 os.system()과 같이 사용할 수 있습니다 .

import os
os.system('ls')

또는 귀하의 경우 :

os.system('echo 1 > /proc/sys/net/ipv4/ip_forward')
os.system('iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080')

더 나은 아직, 당신은 하위 프로세스의 호출을 사용할 수 있습니다, 그것은 더 안전하고 강력하며 아마 빠릅니다.

from subprocess import call
call('echo "I like potatos"', shell=True)

또는 쉘을 호출하지 않고 :

call(['echo', 'I like potatos'])

출력을 캡처하려는 경우이를 수행하는 한 가지 방법은 다음과 같습니다.

import subprocess
cmd = ['echo', 'I like potatos']
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

o, e = proc.communicate()

print('Output: ' + o.decode('ascii'))
print('Error: '  + e.decode('ascii'))
print('code: ' + str(proc.returncode))

나는 매우 의 설정 추천 timeout에를 communicate, 또한 그것을 호출 할 때 얻을 수있는 예외를 포착 할 수 있습니다. 이것은 오류가 발생하기 쉬운 코드이므로 오류가 발생할 것으로 예상하고 적절하게 처리해야합니다.

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


23
os.system은 버전 2.6부터 사용되지 않습니다. 하위 프로세스는 사용하기에 적합한 모듈입니다.
binarysubstrate

@binarysubstrate, 지원되지 않거나 사용할 수없는 것으로 더 이상 사용되지 않습니까? 나는 최근에 2.7 (선택이 아닌)으로 컴퓨터에서 작업하고 있으며 os.system여전히 작동합니다.
openwonk

1
또한 subprocess.call권장대로 사용 하는 경우 다음을 지정해야 할 수도 shell=True있습니다. 여기를
openwonk

Python 3.4에서는 shell = True를 지정해야합니다. 그렇지 않으면 호출 명령이 작동하지 않습니다. shell = True가 설정되어 있지 않으면 기본적으로 호출은 문자열로 지정된 파일을 열려고 시도합니다. 또한 파이썬 3.5에서는 호출이 다음과 같이 실행되는 것으로 보입니다.
DLH

일반 POSIX 코드는 아마도 환경 변수의 decode()문자셋으로 호출해야 LC_CTYPE합니다.
Mikko Rantalainen

29

첫 번째 명령은 단순히 파일에 씁니다. 쉘 python의 도움없이 파일을 읽고 쓸 수 있기 때문에 쉘 명령으로 실행하지 않을 것입니다 .

with open('/proc/sys/net/ipv4/ip_forward', 'w') as f:
    f.write("1")

iptables명령은 외부에서 실행할 수 있습니다. 이를 수행하는 가장 좋은 방법은 하위 프로세스 모듈 을 사용하는 것 입니다.

import subprocess
subprocess.check_call(['iptables', '-t', 'nat', '-A',
                       'PREROUTING', '-p', 'tcp', 
                       '--destination-port', '80',
                       '-j', 'REDIRECT', '--to-port', '8080'])

이 방법은 또한 불필요한 오버 헤드 인 셸을 사용하지 않습니다.


13

가장 빠른 방법 :

import os
os.system("your command here")

이것은 가장 유연한 접근 방식이 아닙니다. "한 번 실행, 완료 및 종료 될 때까지 차단"보다 프로세스에 대한 제어가 더 필요한 경우 subprocess대신 모듈을 사용해야합니다 .


8

일반적으로 가능하면 파이썬 바인딩을 사용하는 것이 좋습니다 (다른 장점 중에서도 예외 잡기가 더 낫습니다).

echo명령의 경우 @jordanm의 답변에서 제안한대로 파이썬을 사용하여 파일에 쓰는 것이 좋습니다.

를 들어 iptables명령, 어쩌면 python-iptables( PyPi 페이지 , 설명 및 문서와 GitHub의 페이지 ) 당신이 (내가 특정 명령을 확인하지 않았다) 필요한 것을 제공 할 것이다.

이렇게하면 외부 라이브러리에 의존하게되므로 이점을 평가해야합니다. 하위 프로세스를 사용하는 것이 좋지만 출력을 사용하려면 직접 구문 분석하고 향후 iptables버전의 출력 변경 사항을 처리해야합니다 .


주목해야 할 또 다른 사항은 subprocess호출이 있는 단위 테스트 코드 가 덜 유용하다는 것입니다. 예, 통화를 조롱 할 수 있지만 테스트는 외부 통화의 결과에 대해 가정해야합니다.
jordanm

당신의 대답은 조언과 같습니다. OP는 구체적으로 파이썬에서 리눅스 시스템 명령을 실행하는 방법을 물었습니다.
kapad

@kapad 예, 그러나 그는 왜 그렇게하고 싶었는지 지정하고 대안을 제안했습니다.
Jérôme

2

쉘의 파이썬 버전. 테스트하지 않았으므로주의하십시오.

from subprocess import run

def bash(command):
        run(command.split())

>>> bash('find / -name null')
/dev/null
/sys/fs/selinux/null
/sys/devices/virtual/mem/null
/sys/class/mem/null
/usr/lib/kbd/consoletrans/null

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