Bash betiğini python içinden çalıştırma


114

Aşağıdaki kodla ilgili bir sorunum var:

callBash.py:

import subprocess
print "start"
subprocess.call("sleep.sh")
print "end"

sleep.sh:

sleep 10

"Son" un 10 saniye sonra basılmasını istiyorum. (Bunun aptalca bir örnek olduğunu biliyorum, basitçe python içinde uyuyabilirim, ancak bu basit sleep.sh dosyası sadece bir test gibiydi)


Ayrıca "$! Bin / bash; uyku 10;" ile
denedim

Bu araştırmacının hangi sorunu sormaya çalıştığı belli değil, ancak soru muhtemelen kalmalı çünkü cevap olarak az çok iyi tahminlerin olduğu tarihsel bir kapma çantası biriktirdi. Muhtemelen belirli bir hatayı da araştırın ve / veya stackoverflow.com/questions/4256107/…
08'de üçlü

Yanıtlar:


96

Sleep.sh'i çalıştırılabilir hale shell=Truegetirmek ve parametre listesine eklemek (önceki cevaplarda önerildiği gibi) sorunsuz çalışıyor. Arama yoluna bağlı olarak, eklemeniz ./veya başka bir uygun yol yapmanız gerekebilir . (Yani, değiştirmek "sleep.sh"için "./sleep.sh").

shell=TrueParametre darbe komut ilk satırı bir kabuğa bir yol ise, (Linux gibi Posix sisteminde) gerekli değildir; örneğin #!/bin/bash,.


52

Eğer sleep.shshebang sahiptir #!/bin/shve uygun dosya izinlerine sahip - çalıştırmak chmod u+rx sleep.shemin olmak için ve içinde bulunduğu $PATHolarak çalışması gerekir .kodunuz o zaman:

import subprocess

rc = subprocess.call("sleep.sh")

Komut dosyası PATH içinde değilse, tam yolunu belirtin, örneğin, mevcut çalışma dizininde ise:

from subprocess import call

rc = call("./sleep.sh")

Komut dosyasında hiç shebang yoksa şunu belirtmeniz gerekir shell=True:

rc = call("./sleep.sh", shell=True)

Komut dosyasının çalıştırılabilir izni yoksa ve örneğin çalıştırarak değiştiremiyorsanız os.chmod('sleep.sh', 0o755), komut dosyasını bir metin dosyası olarak okuyabilir ve subprocessbunun yerine dizeyi modüle iletebilirsiniz :

with open('sleep.sh', 'rb') as file:
    script = file.read()
rc = call(script, shell=True)

35

Aslında, sadece shell=Trueargümanı eklemelisiniz :

subprocess.call("sleep.sh", shell=True)

Ama dikkat et -

Uyarı Sistem kabuğunu shell = True ile çağırmak, güvenilmeyen girdilerle birleştirilirse bir güvenlik tehlikesi olabilir. Ayrıntılar için Sık Kullanılan Bağımsız Değişkenler altındaki uyarıya bakın.

kaynak


1
Eğer işe yaramaz sleep.shdeğildir PATH. O eğer olduğunu yolunda ve doğru shebang vardır o zaman gerek yok shell=True. Cevabımı
jfs

19

Bağımsız değişkenler içeren bir komut dosyası aramak isteyen biri

import subprocess

val = subprocess.check_call("./script.sh '%s'" % arg, shell=True)

Str (arg) kullanarak değiştirmeden önce argümanları dizeye dönüştürmeyi unutmayın.

Bu, istenen sayıda argüman iletmek için kullanılabilir:

subprocess.check_call("./script.ksh %s %s %s" % (arg1, str(arg2), arg3), shell=True)

12

sleep.shYürütme izinlerine sahip olduğundan emin olun ve aşağıdakilerle çalıştırın shell=True:

#!/usr/bin/python

import subprocess
print "start"
subprocess.call("./sleep.sh", shell=True)
print "end"

bu yüzden kabuk oldu = Doğru Kaçırdım. Sh scricpt'in ilk satırına #! Bin / bash koymanın neden yeterli olmadığını açıklayabilir misiniz?
user1638145

4
İçindeki hata #!bin/basheksiktir /. #!/bin/bashbir cevapta not ettiğim gibi çalışıyor.
James Waldby - jwpat7

10

Chmod çalışmıyorsa, siz de deneyin

import os
os.system('sh script.sh')
#you can also use bash instead of sh

benim tarafımdan test et teşekkürler


os.systemBelgeler, lehine bundan kaçınır önerir subprocess(bu günlerde subprocess.run()). subprocessİşe gidemezsen , muhtemelen senin de sorun os.system()yaşarsın.
üçlü

3

Python'dan bir bash betiğinin nasıl çalıştırılacağını sorduktan sonra buraya yönlendirildiğim için bir cevap ekleniyor. OSError: [Errno 2] file not foundKomut dosyanız parametreleri alırsa bir hata alırsınız . Örneğin, betiğinizin bir uyku süresi parametresi aldığını varsayalım: subprocess.call("sleep.sh 10")çalışmayacak, onu bir dizi olarak iletmelisiniz:subprocess.call(["sleep.sh", 10])


Bunun gerçek anlamınıshell=True anlamalısınız ama evet, genellikle bundan kaçınmak en iyi oyununuzdur.
üçlü
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.