如何从python代码调用Shell脚本?


Answers:


252

模块将帮助你。

显而易见的例子:

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

其中test.sh是一个简单的shell脚本,0它是此运行的返回值。


11
注意:最好传递subprocess.call()一个列表而不是一个字符串(有关示例和原因,请参见下面对Hugo24的命令)。
吉姆丹尼斯

1
教程的链接已断开。
Kshitij Saraogi's

6
这给出:OSError:[Errno 13]权限被拒绝。我的脚本不需要与sudo一起运行。@Manoj Govindan
alper

6
带有参数:subprocess.call(['./ test.sh','param1','param2'])
亨利

2
@alper转到放置脚本的文件夹并运行命令 chmod +x script.sh。注意:script.sh是脚本的占位符,请相应地替换它。
汤姆·J·穆蒂朗西

105

有一些使用os.popen()(不推荐使用)或整个subprocess模块的方法,但是这种方法

import os
os.system(command)

是最简单的之一。


1
为什么这不是最受好评的答案?不必导入模块是更好的解决方案吗?这里一定有缺点吗?
boulder_ruby

6
通过subprocess它可以管理输入/输出/错误管道。当您有很多参数时,这也更好- os.command()您将必须创建带有转义特殊字符的整个命令行,并subprocess具有简单的参数列表。但是对于简单的任务os.command() 可能就足够了。
米哈尔尼克拉斯

1
引用该链接的内容: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

如果要将一些参数传递给Shell脚本,可以使用shlex.split()方法:

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

test.sh在同一文件夹:

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

输出:

$ python test.py 
param1
param2

真优雅
caleb


15

如上所述,使用子流程模块。

我这样使用它:

subprocess.call(["notepad"])

13
注意:使用列表调用子进程比较安全,因为它不需要通过外壳程序传递(可能未过滤的)字符串进行解析/解释。列表中的第一项将是可执行文件,所有其他项将作为参数传递。
Jim Dennis 2010年

13

我正在运行python 3.5,subprocess.call(['./ test.sh'])对我不起作用。

我给你三种解决方案,取决于你想对输出做些什么。

1-通话脚本。您将在终端中看到输出。输出是一个数字。

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

2-调用和转储执行并将错误转换为字符串。除非您打印(stdout),否则您不会在终端中看到执行。Shell = True在Popen中作为参数对我不起作用。

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-调用脚本并将temp.txt的echo命令转储到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)

不要忘了看一下doc子流程


1
注意 请勿将stdout = PIPE或stderr = PIPE与一起使用subprocess.call。如果子进程向管道生成足够的输出以填充OS管道缓冲区,则该子进程将阻塞,因为未从中读取管道。

4

子流程模块是启动子流程的好模块。您可以使用它来调用shell命令,如下所示:

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

您可以在此处查看其文档

如果您的脚本是用.sh文件或长字符串编写的,则可以使用os.system模块。调用起来非常简单容易:

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

该命令将运行脚本一次,直到完成,然后阻塞直到退出。


您也不必导入sys吗?
ScottyBlades

不,你不会;尝试打开Python Shell并运行此代码段
笛卡尔(Descartes)

4

如果脚本有多个参数

#!/usr/bin/python

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

输出将给出状态码。如果脚本成功运行,它将给出0,否则为非零整数。

podname=xyz  serial=1234
0

下面是test.sh shell脚本。

#!/bin/bash

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


2

我知道这是一个老问题,但是最近我偶然发现了这个问题,由于Subprocess API自python 3.5以来发生了变化,最终导致了我的误解

执行外部脚本的新方法是使用run函数,该函数运行args描述的命令。等待命令完成,然后返回CompletedProcess实例。

import subprocess

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

1

如果您的Shell脚本文件没有执行权限,请按照以下方式进行操作。

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

-9

请尝试以下代码:

Import Execute 

Execute("zbx_control.sh")
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.