Menjalankan skrip bash dari dalam python

105

Saya punya masalah dengan kode berikut:

callBash.py:

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

sleep.sh:

sleep 10

Saya ingin "akhir" dicetak setelah 10 detik. (Saya tahu bahwa ini adalah contoh yang bodoh, saya bisa saja tidur dalam python, tetapi file sleep.sh sederhana ini hanya sebagai tes)

pengguna1638145
sumber
Saya juga mencobanya dengan "$! Bin / bash; sleep 10;"
user1638145
Tidak jelas masalah apa yang coba ditanyakan oleh questien ini, tetapi pertanyaan itu mungkin harus tetap ada karena telah memperoleh kantong sejarah dengan tebakan yang kurang lebih bagus sebagai jawaban. Mungkin juga mencari kesalahan spesifik Anda, dan / atau membaca pertanyaan terkait seperti stackoverflow.com/questions/4256107/…
tripleee

Jawaban:

91

Membuat sleep.sh dapat dieksekusi dan menambahkan shell=Trueke daftar parameter (seperti yang disarankan dalam jawaban sebelumnya) berfungsi dengan baik. Bergantung pada jalur pencarian, Anda mungkin juga perlu menambahkan ./atau jalur lain yang sesuai. (Yaitu, ganti "sleep.sh"ke "./sleep.sh".)

The shell=Trueparameter tidak diperlukan (di bawah sistem POSIX seperti Linux) jika baris pertama script bash adalah jalan untuk shell; misalnya #!/bin/bash,.

James Waldby - jwpat7
sumber
48

Jika sleep.shmemiliki shebang #!/bin/shdan memiliki izin file yang sesuai - jalankan chmod u+rx sleep.shuntuk memastikan dan sudah masuk $PATHmaka kode Anda harus berfungsi sebagaimana mestinya:

import subprocess

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

Jika skrip tidak ada di PATH, tentukan jalur lengkapnya, misalnya, jika ada di direktori kerja saat ini:

from subprocess import call

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

Jika skrip tidak memiliki shebang maka Anda perlu menentukan shell=True:

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

Jika skrip tidak memiliki izin yang dapat dieksekusi dan Anda tidak dapat mengubahnya, misalnya dengan menjalankannya, os.chmod('sleep.sh', 0o755)Anda dapat membaca skrip sebagai file teks dan meneruskan string ke subprocessmodul sebagai gantinya:

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

Sebenarnya, Anda hanya perlu menambahkan shell=Trueargumen:

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

Tapi waspadalah -

Peringatan Memanggil shell sistem dengan shell = True bisa menjadi bahaya keamanan jika digabungkan dengan input yang tidak tepercaya. Lihat peringatan di bawah Argumen yang Sering Digunakan untuk detailnya.

sumber

zenpoy
sumber
1
Ini tidak akan berhasil jika sleep.shtidak ada di PATH. Dan jika sudah di jalur dan memiliki shebang yang benar maka Anda tidak perlu shell=True. Lihat jawaban saya
jfs
16

Jika seseorang mencari memanggil skrip dengan argumen

import subprocess

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

Ingatlah untuk mengonversi args menjadi string sebelum meneruskan, menggunakan str (arg).

Ini dapat digunakan untuk meneruskan argumen sebanyak yang diinginkan:

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

Pastikan itu sleep.shmemiliki izin eksekusi, dan jalankan dengan shell=True:

#!/usr/bin/python

import subprocess
print "start"
subprocess.call("./sleep.sh", shell=True)
print "end"
Adam Matan
sumber
jadi itu cangkangnya = Benar aku merindukan. Bisakah Anda menjelaskan, mengapa tidak cukup mengatur #! Bin / bash di baris pertama sh scricpt?
pengguna1638145
3
Kesalahan dalam #!bin/bashhilang /. #!/bin/bashberfungsi seperti yang saya catat dalam sebuah jawaban.
James Waldby - jwpat7
9

Jika chmod tidak berfungsi maka Anda juga mencoba

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

uji oleh saya terima kasih

Harry1992
sumber
The os.systemdokumentasi khusus menganjurkan untuk menghindari itu mendukung subprocess(hari ini, subprocess.run()). Jika Anda tidak bisa subprocessbekerja, kemungkinan besar Anda juga akan kesulitan os.system().
tripleee
3

Menambahkan jawaban karena saya diarahkan ke sini setelah menanyakan cara menjalankan skrip bash dari python. Anda menerima kesalahan OSError: [Errno 2] file not foundjika skrip Anda memasukkan parameter. Katakanlah misalnya skrip Anda mengambil parameter waktu tidur: subprocess.call("sleep.sh 10")tidak akan berfungsi, Anda harus meneruskannya sebagai array:subprocess.call(["sleep.sh", 10])

Matthew Lang
sumber
Anda harus memahami arti sebenarnya darishell=True tapi ya, biasanya menghindarinya adalah permainan terbaik Anda.
tripleee