पायथन में शेल कमांड निष्पादित करें


65

मैं वर्तमान में पैठ परीक्षण और पायथन प्रोग्रामिंग का अध्ययन कर रहा हूं । मैं सिर्फ यह जानना चाहता हूं कि मैं पायथन में एक लिनक्स कमांड निष्पादित करने के बारे में कैसे जाऊंगा। जिन आदेशों को मैं निष्पादित करना चाहता हूं वे हैं:

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 ऐसा कर सकता है।
फूंक दें

2
और मुझे लगा bashकि एक फूला हुआ खोल था ...
mikeserv

3
मॉड्यूल os.systemका उपयोग करने की अनुशंसा के लिए डॉक्स subprocess
जोर्डनम

क्या आपको iptables के आउटपुट की आवश्यकता है?
किरा

3
इस प्रश्न को स्टैकओवरफ़्लो में स्थानांतरित किया जाना चाहिए।
21:39 पर 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
ओएस.सिस्टम 2.6 संस्करण के बाद से हटा दिया गया है। उपप्रकार का उपयोग करने के लिए सही मॉड्यूल है।
बाइनरीसुब्रेटेट

@binarysubstrate, समर्थित नहीं या उपलब्ध नहीं के रूप में पदावनत? मैं हाल ही में 2.7 (पसंद से नहीं) के साथ मशीन पर काम कर रहा हूं, और os.systemअभी भी काम करता हूं ।
ओपनवॉन्क

1
इसके अलावा, यदि subprocess.callअनुशंसित के रूप में उपयोग किया जाता है, तो आपको निर्दिष्ट करने की आवश्यकता हो सकती है shell=True... यहां
ओपनवाकोंक

पायथन 3.4 के साथ शेल = ट्रू को बताना होगा अन्यथा कॉल कमांड काम नहीं करेगा। डिफ़ॉल्ट कॉल द्वारा स्ट्रिंग द्वारा निर्दिष्ट फ़ाइल को खोलने का प्रयास करेंगे जब तक कि शेल = ट्रू सेट न हो। यह भी दिखता है कि पायथन 3.5 कॉल में रन
डीएलएच

जेनेरिक POSIX कोड को संभवतः पर्यावरण चर decode()से charset के साथ कॉल करना चाहिए LC_CTYPE
मिकको रेंटालिनेन

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कॉल के साथ यूनिट परीक्षण कोड कम उपयोगी है। हां, आप कॉल को मॉक कर सकते हैं, लेकिन परीक्षणों को बाहरी कॉल पर परिणामों के बारे में धारणा बनानी होगी।
जोर्डनम

आपका जवाब सलाह की तरह है। ओपी ने विशेष रूप से पूछा है कि वह अजगर से एक लिनक्स सिस्टम कमांड कैसे चला सकता है।
kapad

@kapad हां, लेकिन उन्होंने यह भी निर्दिष्ट किया कि वह ऐसा क्यों करना चाहते हैं और मैंने एक विकल्प प्रस्तावित किया।
जेरोमे

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

0

यदि आप SSH के बाद किसी अन्य सिस्टम में इस कमांड को निष्पादित करना चाहते हैं तो आपको Paramiko नाम के मॉड्यूल का उपयोग करना पड़ सकता है। यह वास्तव में उपयोगी है।

यदि कमांड निष्पादन स्थानीय मशीन से किया जाना है तो ओएस मॉड्यूल फ़ंक्शन सहायक होंगे।

होमपेज: https://www.paramiko.org/

विकास: https://github.com/paramiko/paramiko

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.