从python中运行bash脚本


104

我的以下代码有问题:

callBash.py:

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

sleep.sh:

sleep 10

我希望10秒钟后打印“结束”。(我知道这是一个愚蠢的示例,我可以简单地在python中睡眠,但是这个简单的sleep.sh文件只是一个测试)


我还尝试了“ $!bin / bash;睡眠10;”
user1638145

目前尚不清楚这个探访者试图问什么问题,但是这个问题可能仍然存在,因为它已经积累了一个或多或少的好猜测作为答案的历史记录。大概也搜索特定的错误,和/或念想相关问题stackoverflow.com/questions/4256107/...
tripleee

Answers:


90

使sleep.sh可执行并添加shell=True到参数列表中(如先前答案中所建议)可以正常工作。根据搜索路径,您可能还需要添加./或其他合适的路径。(即,更改"sleep.sh""./sleep.sh"。)

shell=True不需要的参数,如果bash脚本的第一行是一个外壳的路径(一个Posix的系统如Linux下); 例如,#!/bin/bash


47

如果sleep.sh具有shebang #!/bin/sh并且它具有适当的文件权限-运行chmod u+rx sleep.sh以确保它已经在其中,$PATH则您的代码应按原样工作:

import subprocess

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

如果脚本不在PATH中,则指定它的完整路径,例如,如果它在当前工作目录中:

from subprocess import call

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

如果脚本没有shebang,则需要指定shell=True

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

如果脚本没有可执行权限,并且您无法更改它(例如,通过运行),os.chmod('sleep.sh', 0o755)则可以将脚本作为文本文件读取,然后将字符串传递给subprocess模块:

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

33

实际上,您只需要添加shell=True参数即可:

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

但要注意-

警告如果与不受信任的输入结合使用,使用shell = True调用系统外壳可能会带来安全隐患。有关详细信息,请参见“常用参数”下的警告。

资源


1
如果sleep.sh不在,它将无法正常工作PATH。而如果在路径,它具有正确的家当,那么你就不需要shell=True。看到我的答案
jfs

16

如果有人希望通过参数调用脚本

import subprocess

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

请记住在传递之前使用str(arg)将args转换为字符串。

这可以用来传递任意多个参数:

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

10

确保sleep.sh具有执行权限,并使用来运行它shell=True

#!/usr/bin/python

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

所以那是我错过的shell = True。您能否解释一下,为什么在sh脚本的第一行中设置#!bin / bash不够?
user1638145

3
中的错误#!bin/bash丢失了/#!/bin/bash正如我在答案中指出的那样工作。
James Waldby-jwpat7

9

如果chmod不起作用,那么您也可以尝试

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

由我测试谢谢


os.system文档特别建议您避免使用subprocess(这些天为subprocess.run())。如果您无法subprocess上班,则很可能也会遇到麻烦os.system()
6

3

添加一个答案是因为询问了如何从python运行bash脚本后我被定向到了这里。OSError: [Errno 2] file not found如果您的脚本接受参数,则会收到错误消息。假设您的脚本输入了一个sleep time参数:subprocess.call("sleep.sh 10")将无法工作,您必须将其作为数组传递:subprocess.call(["sleep.sh", 10])


您必须了解的实际含义,shell=True但是可以,通常避免它是您的最佳选择。
6
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.