Làm thế nào để gọi một kịch bản shell từ mã python?


210

Làm thế nào để gọi một kịch bản shell từ mã python?

Câu trả lời:


252

Các mô-đun quy trình con sẽ giúp bạn ra ngoài.

Ví dụ tầm thường:

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

Trường hợp test.shmột tập lệnh shell đơn giản và 0là giá trị trả về của nó cho lần chạy này.


11
Lưu ý: tốt nhất là nên truyền sub process.call () một danh sách thay vì một chuỗi (xem lệnh cho Hugo24 bên dưới để biết ví dụ và lý do).
Jim Dennis

1
Liên kết đến hướng dẫn bị hỏng.
Kshitij Saraogi

6
Điều này mang lại: OSError: [Errno 13] Quyền bị từ chối. kịch bản của tôi không bắt buộc phải chạy với sudo. @Manoj Govindan
alper

6
Với các đối số: sub process.call (['./ test.sh', 'param1', 'param2'])
Henry

2
@alper đi đến thư mục mà bạn đã đặt tập lệnh và chạy lệnh , chmod +x script.sh. Lưu ý: script.sh là một trình giữ chỗ cho tập lệnh của bạn, thay thế nó cho phù hợp.
Tom J Muthirenthi

105

Có một số cách sử dụng os.popen()(không dùng nữa) hoặc toàn bộ subprocessmô-đun, nhưng cách tiếp cận này

import os
os.system(command)

là một trong những dễ nhất


1
Tại sao đây không phải là câu trả lời được đánh giá cao nhất? Không phải nhập mô-đun là giải pháp tốt hơn? Phải có một số nhược điểm ở đây?
boulder_ruby

6
Với subprocessbạn có thể quản lý đường ống đầu vào / đầu ra / lỗi. Nó cũng tốt hơn khi bạn có nhiều đối số - với os.command()bạn sẽ phải tạo toàn bộ dòng lệnh với thoát các ký tự đặc biệt, với subprocessdanh sách các đối số đơn giản. Nhưng đối với các nhiệm vụ đơn giản os.command() có thể là vừa đủ.
Michał Niklas

1
Để trích dẫn từ liên kết đó: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

Trong trường hợp bạn muốn truyền một số tham số cho tập lệnh shell của mình, bạn có thể sử dụng phương thức shlex.split () :

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

với test.shtrong cùng một thư mục:

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

Đầu ra:

$ python test.py 
param1
param2

Đây là thanh lịch.
caleb

20
import os
import sys

Giả sử test.sh là tập lệnh shell mà bạn muốn thực thi

os.system("sh test.sh")

15

Sử dụng mô đun quy trình con như đã đề cập ở trên.

Tôi sử dụng nó như thế này:

subprocess.call(["notepad"])

13
Lưu ý: gọi quy trình con với một danh sách sẽ an toàn hơn vì nó không bắt buộc phải chuyển chuỗi (có khả năng không được xác thực) thông qua trình bao để phân tích / giải thích. Mục đầu tiên trong danh sách sẽ là tệp thực thi và tất cả các mục khác sẽ được chuyển qua làm đối số.
Jim Dennis

13

Tôi đang chạy python 3.5 và sub process.call (['./ test.sh']) không hoạt động với tôi.

Tôi cung cấp cho bạn ba giải pháp phụ thuộc vào những gì bạn muốn làm với đầu ra.

1 - kịch bản cuộc gọi. Bạn sẽ thấy đầu ra trong thiết bị đầu cuối của bạn. đầu ra là một con số.

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

2 - thực hiện cuộc gọi và kết xuất và lỗi thành chuỗi. Bạn không thấy thực thi trong thiết bị đầu cuối của bạn trừ khi bạn in (thiết bị xuất chuẩn). Shell = Đúng như đối số trong Popen không hoạt động đối với tôi.

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 - gọi tập lệnh và kết xuất các lệnh echo của temp.txt trong temp_file

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)

Đừng quên xem quy trình con doc


1
Lưu ý Không sử dụng stdout = PIPE hoặc stderr = PIPE với subprocess.call. Quá trình con sẽ chặn nếu nó tạo ra đầu ra đủ cho một đường ống để lấp đầy bộ đệm ống hệ điều hành vì các đường ống không được đọc từ đó.

4

Mô-đun quy trình là một mô-đun tốt để khởi chạy các quy trình con. Bạn có thể sử dụng nó để gọi các lệnh shell như sau:

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

Bạn có thể xem tài liệu của nó ở đây.

Nếu bạn có tập lệnh được viết bằng một số tệp .sh hoặc một chuỗi dài, thì bạn có thể sử dụng mô-đun os.system. Nó khá đơn giản và dễ gọi:

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

Lệnh này sẽ chạy tập lệnh một lần, để hoàn thành và chặn cho đến khi thoát.


Bạn không phải nhập sys quá?
ScottyBlades

Không, bạn không; hãy thử mở một vỏ Python và chạy đoạn trích này
Descartes

4

Trong trường hợp tập lệnh có nhiều đối số

#!/usr/bin/python

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

Đầu ra sẽ cho mã trạng thái. Nếu tập lệnh chạy thành công, nó sẽ cho 0 nếu không là số nguyên khác không.

podname=xyz  serial=1234
0

Dưới đây là kịch bản shell test.sh.

#!/bin/bash

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

2

Quá trình con là tốt nhưng một số người có thể thích scriptine hơn. Scriptine có tập hợp các phương thức mức cao hơn như shell.call (args) , path.rename (new_name)path.move (src, dst) . Scriptine dựa trên quy trình con và những thứ khác.

Hai nhược điểm của scriptine:

  • Cấp độ tài liệu hiện tại sẽ toàn diện hơn mặc dù nó là đủ.
  • Không giống như quy trình con, gói scriptine hiện không được cài đặt theo mặc định.

2

Tôi biết đây là một câu hỏi cũ nhưng tôi stumbled khi này thời gian gần đây và nó đã kết thúc misguiding tôi kể từ khi trình con API như thay đổi kể từ python 3.5.

Cách mới để thực thi các tập lệnh bên ngoài là với runhàm, chạy lệnh được mô tả bởi args. Chờ lệnh hoàn thành, sau đó trả về một thể hiện CompleteedProcess.

import subprocess

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

1

Nếu tệp kịch bản lệnh shell của bạn không có quyền thực thi, hãy thực hiện theo cách sau.

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

-9

Vui lòng thử các mã sau:

Import Execute 

Execute("zbx_control.sh")
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.