Python'da kabuk komutlarını yürütün


65

Şu anda penetrasyon testi ve Python programlama okuyorum . Sadece Python'da bir Linux komutunu nasıl yürüteceğimi bilmek istiyorum. Çalıştırmak istediğim komutlar:

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

Sadece printPython'da kullanırsam ve terminalde çalıştırırsam, kendin yazıyormuş gibi yapıp basar Entermısın?


5
os.system bunu yapabilir.
fooot

2
ve ben bashşişirilmiş bir kabuk olduğunu düşündüm ...
mikeserv 23:15

3
Dokümanlar modülün os.systemkullanılmasını tavsiye eder subprocess.
jordanm

İptables çıktısına ihtiyacınız var mı?
Kira

3
Bu soru Stackoverflow'a taşınmalıdır.
www139

Yanıtlar:


106

Bunun gibi kullanabilirsiniz os.system():

import os
os.system('ls')

Veya senin durumunda:

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')

Daha da iyisi, alt işlemin çağrısını kullanabilirsiniz, daha güvenli, daha güçlü ve muhtemelen daha hızlı:

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

Veya, kabuk çağırmadan:

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

Çıktıyı yakalamak istiyorsanız, bunu yapmanın bir yolu şudur:

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))

Ben son derece bir ayar tavsiye timeoutin communicate, hem de onu çağrılırken alabilirsiniz istisnaları yakalamak için. Bu çok hataya açık bir koddur, bu nedenle hata oluşmasını beklemeli ve bunları uygun şekilde ele almalısınız.

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


23
2.6 sürümünden beri os.system kullanımdan kaldırılmıştır. Alt işlem, kullanılacak doğru modüldür.
binarysubstrate

@binarysubstrate, desteklenmiyor veya mevcut değil kullanımdan kaldırıldı mı? Son zamanlarda makinede 2.7 ile çalışıyorum (seçerek değil) ve os.systemhala çalışıyor.
openwonk

1
Ayrıca, subprocess.callönerilen şekilde kullanıyorsanız , belirtmeniz gerekebilir shell=True... burada
openwonk

Python 3.4 ile shell = True belirtilmelidir, aksi takdirde call komutu çalışmayacaktır. Varsayılan olarak arama, shell = True ayarlanmadıkça, dize tarafından belirtilen bir dosyayı açmaya çalışır. Ayrıca Python 3.5 çağrısı çalıştırma ile değiştirilmiş gibi görünüyor
DLH

Genel POSIX kodu muhtemelen ortam değişkeninden decode()karakter kümesi çağırmalıdır LC_CTYPE.
Mikko Rantalainen

29

İlk komut basitçe bir dosyaya yazar. Bunu bir kabuk komutu olarak çalıştırmazsınız çünkü pythonbir kabuk yardımı olmadan dosyaları okuyabilir ve yazabilir:

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

iptablesKomut harici olarak çalıştırmak isteyebilirsiniz şeydir. Bunu yapmanın en iyi yolu, alt işlem modülünü kullanmaktır .

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

Ayrıca bu yöntemin gereksiz ek yük olan bir kabuk kullanmadığını unutmayın.


13

En hızlı yol:

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

Bu en esnek yaklaşım değil; İşleminiz üzerinde "bir kez çalıştır, bitirmek ve çıkana kadar engellemek" den daha fazla kontrole ihtiyacınız varsa, subprocessbunun yerine modülü kullanmalısınız.


8

Genel bir kural olarak, mümkün olduğunda piton bağlarını daha iyi kullanmalısınız (diğer avantajların yanı sıra daha iyi İstisna yakalama).

İçin echokomuta, o @ jordanm yanıtında önerildiği şekilde dosyada yazmak için python kullanmak tabii ki daha iyidir.

İçin iptableskomuta, belki python-iptables( PyPi sayfa , açıklama ve doc ile GitHub sayfa ) Eğer (Ben özel komut kontrol etmedi) gerekenleri sağlayacak.

Bu sizi harici bir kütüphaneye bağımlı kılar, böylece faydaları değerlendirmek zorunda kalırsınız. Alt işlemi kullanmak işe yarar, ancak çıktıyı kullanmak istiyorsanız, kendiniz ayrıştırmanız ve gelecekteki iptablessürümlerde çıktı değişiklikleriyle uğraşmanız gerekir.


Unutulmaması gereken bir başka şey de subprocessçağrıları içeren birim test kodunun daha az kullanışlı olmasıdır. Evet, çağrıları alay edebilirsiniz, ancak testlerin dış aramalardaki sonuçlar hakkında varsayımlarda bulunması gerekir.
jordanm

Cevabınız daha çok tavsiye gibi. OP, python'dan linux sistem komutunu nasıl çalıştırabileceğini özellikle sordu.
kapad

@kapad Evet, fakat neden yapmak istediğini de belirtti ve ben bir alternatif önerdim.
Jérôme

2

Kabuğunun piton versiyonu. Dikkat et, test etmedim.

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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.