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)


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,.


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)

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


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)

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"

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


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


Anda harus memahami arti sebenarnya darishell=True tapi ya, biasanya menghindarinya adalah permainan terbaik Anda.
tripleee
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.