Python kodundan bir kabuk betiği nasıl çağırılır?


210

Python kodundan bir kabuk betiği nasıl çağırılır?

Yanıtlar:


252

Altişlem modülü size yardımcı olacaktır.

Açıkça önemsiz örnek:

>>> import subprocess
>>> subprocess.call(['./test.sh']) # Thanks @Jim Dennis for suggesting the []
0 
>>> 

Burada test.shbasit bir kabuk betiği ve 0bu çalışma için dönüş değeri.


11
Not: dize yerine subprocess.call () listesini iletmek tercih edilir (örnek ve nedenler için aşağıdaki Hugo24 komutuna bakın).
Jim Dennis

1
Eğiticiye bağlantı koptu.
Kshitij Saraogi

6
Bu şunu verir: OSError: [Errno 13] İzin reddedildi. betiğimin sudo ile çalışması gerekmez. @Manoj Govindan
alper

6
Bağımsız değişkenlerle: subprocess.call (['./ test.sh', 'param1', 'param2'])
Henry

2
@alper betiği yerleştirdiğiniz klasöre gidin ve komutu çalıştırın chmod +x script.sh. Not: script.sh betiğiniz için bir yer tutucudur, uygun şekilde değiştirin.
Tom J Muthirenthi

105

Modülü os.popen()veya tüm subprocessmodülü kullanmanın bazı yolları vardır , ancak bu yaklaşım

import os
os.system(command)

en kolay olanlardan biridir.


1
bu neden en güncel cevap değil? Bir modülü almak zorunda değilsiniz daha iyi çözüm? Burada bir dezavantaj olmalı mı?
boulder_ruby

6
İle subprocessgiriş / çıkış / hata borularını yönetebilirsiniz. Birçok argümanınız olduğunda da daha iyi olur - basit os.command()karakter subprocessargümanları ile birlikte, özel karakterlerden kaçan tüm komut satırını oluşturmanız gerekir . Ancak basit görevler için os.command() yeterli olabilir.
Michał Niklas

1
Bu bağlantıdan alıntı yapmak için:The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; *using that module is preferable to using this function.*
Maximilian

42

Kabuk betiğinize bazı parametreler iletmek isterseniz, shlex.split () yöntemini kullanabilirsiniz :

import subprocess
import shlex
subprocess.call(shlex.split('./test.sh param1 param2'))

ile test.shaynı klasörde:

#!/bin/sh
echo $1
echo $2
exit 0

Çıktılar:

$ python test.py 
param1
param2

Bu zarif.
caleb

20
import os
import sys

Test.sh komutunun yürütmek istediğiniz kabuk betiği olduğunu varsayarsak

os.system("sh test.sh")

15

Yukarıda belirtilen alt işlem modülünü kullanın.

Ben böyle kullanın:

subprocess.call(["notepad"])

13
Not: Bir listeyle alt süreci çağırmak daha güvenlidir, çünkü (potansiyel olarak onaylanmamış) dizeyi ayrıştırma / yorumlama için bir kabuktan geçirmeyi gerektirmez. Listedeki ilk öğe çalıştırılabilir ve diğer tüm öğeler bağımsız değişken olarak geçirilir.
Jim Dennis

13

Python 3.5 çalıştırıyorum ve subprocess.call (['./ test.sh']) benim için çalışmıyor.

Size üç çözüm veriyorum, çıktı ile ne yapmak istediğinize bağlı.

1 - çağrı komut dosyası. Terminalinizde çıktı göreceksiniz. çıktı bir sayıdır.

import subprocess 
output = subprocess.call(['test.sh'])

2 - çağrı ve yürütme ve hata dize dökümü. Yazdırmadan terminalinizde yürütme görmüyorsunuz (stdout). Shell = Popen'deki argüman benim için işe yaramıyor.

import subprocess
from subprocess import Popen, PIPE

session = subprocess.Popen(['test.sh'], stdout=PIPE, stderr=PIPE)
stdout, stderr = session.communicate()

if stderr:
    raise Exception("Error "+str(stderr))

3 - komut dosyasını çağırın ve temp.txt dosyasının echo komutlarını temp_file dosyasına dökün

import subprocess
temp_file = open("temp.txt",'w')
subprocess.call([executable], stdout=temp_file)
with open("temp.txt",'r') as file:
    output = file.read()
print(output)

Doküman alt işlemine bir göz atmayı unutmayın


1
Not stdout = PIPE veya stderr = PIPE ile birlikte kullanmayın subprocess.call. Alt işlem, borular okunmazken OS boru tamponunu doldurmak için bir boruya yeterli çıktı üretirse bloke olur.

4

Alt süreç modülü, alt süreçleri başlatmak için iyi bir modüldür. Kabuk komutlarını şu şekilde çağırmak için kullanabilirsiniz:

subprocess.call(["ls","-l"]);
#basic syntax
#subprocess.call(args, *)

Belgelerini burada görebilirsiniz .

Komut dosyanızı bazı .sh dosyalarında veya uzun bir dizede yazdıysanız, os.system modülünü kullanabilirsiniz. Oldukça basit ve aramak kolaydır:

import os
os.system("your command here")
# or
os.system('sh file.sh')

Bu komut, komut dosyasını bir kez çalıştıracak, tamamlanacak ve çıkana kadar engelleyecektir.


Sys'i de içe aktarmak zorunda değil misiniz?
ScottyBlades

Hayır. bir Python kabuğu açmayı ve bu pasajı çalıştırmayı dene
Descartes

4

Komut dosyasının birden fazla bağımsız değişkeni olması durumunda

#!/usr/bin/python

import subprocess
output = subprocess.call(["./test.sh","xyz","1234"])
print output

Çıktı durum kodunu verecektir. Komut dosyası başarıyla çalışırsa, aksi takdirde sıfır dışında bir tam sayı verir.

podname=xyz  serial=1234
0

Test.sh kabuk betiği aşağıdadır.

#!/bin/bash

podname=$1
serial=$2
echo "podname=$podname  serial=$serial"


2

Bu eski bir soru olduğunu biliyorum ama son zamanlarda bu tökezledi ve python 3.5 beri değişti gibi Altişlem API beri beni yanlış yönlendirdi .

Harici komut dosyalarını yürütmenin yeni yolu run, args tarafından açıklanan komutu çalıştıran işlevdir. Komutun tamamlanmasını bekler, ardından bir CompletedProcess örneği döndürür.

import subprocess

subprocess.run(['./test.sh'])

1

Kabuk komut dosyanızda yürütme izinleri yoksa, bunu aşağıdaki şekilde yapın.

import subprocess
subprocess.run(['/bin/bash', './test.sh'])

-9

Lütfen aşağıdaki kodları deneyin:

Import Execute 

Execute("zbx_control.sh")
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.