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

Ume*_*cha 194 python shell

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

Man*_*dan 230

模块将帮助你.

公然琐碎的例子:

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

哪个test.sh是简单的shell脚本,并且0是此运行的返回值.

  • 注意:最好将subprocess.call()传递给一个列表而不是一个字符串(有关示例和原因,请参阅下面的Hugo24命令). (11认同)
  • 这给出了:OSError:[Errno 13]权限被拒绝.我的脚本不需要与sudo一起运行.@Manoj Govindan (5认同)
  • 带参数:subprocess.call(['./ test.sh','param1','param2']) (4认同)
  • 子进程 api 在 python 3.5 中已更改。新方法是 .run(args) 而不是 call (3认同)
  • @alper 转到放置脚本的文件夹并运行命令`chmod +x script.sh`。注意:script.sh 是您脚本的占位符,请相应地替换它。 (2认同)

Mic*_*las 92

有一些方法可以使用os.popen()(已弃用)或整个subprocess模块,但这种方法

import os
os.system(command)
Run Code Online (Sandbox Code Playgroud)

是最简单的之一.

  • 使用`subprocess`,您可以管理输入/输出/错误管道.当你有很多参数时也更好 - 使用`os.command()`你必须创建带有转义特殊字符的整个命令行,`subprocess`有简单的参数列表.但对于简单的任务,`os.command()`可能就足够了. (6认同)
  • 引用该链接:“子流程模块提供了更强大的工具来生成新流程并检索其结果;*使用该模块比使用此功能更好。*` (4认同)
  • 为什么这不是最受好评的答案?不必导入模块不是更好的解决方案吗?这里一定有什么缺点吗? (2认同)

Fra*_*urt 41

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

import subprocess
import shlex
subprocess.call(shlex.split('./test.sh param1 param2'))
Run Code Online (Sandbox Code Playgroud)

test.sh在同一文件夹中:

#!/bin/sh
echo $1
echo $2
exit 0
Run Code Online (Sandbox Code Playgroud)

输出:

$ python test.py 
param1
param2
Run Code Online (Sandbox Code Playgroud)


Sra*_*rta 20

import os
import sys
Run Code Online (Sandbox Code Playgroud)

假设test.sh是您想要执行的shell脚本

os.system("sh test.sh")
Run Code Online (Sandbox Code Playgroud)


hug*_*o24 15

使用上面提到的子进程模块.

我这样使用它:

subprocess.call(["notepad"])
Run Code Online (Sandbox Code Playgroud)

  • 注意:使用列表调用子进程更安全,因为它不需要通过shell传递(可能未经过未经过处理的)字符串来进行解析/解释.列表中的第一项将是可执行文件,所有其他项将作为参数传递. (13认同)

小智 13

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

我给你三个解决方案取决于你想要的输出.

1 - 调用脚本.您将在终端中看到输出.输出是一个数字.

import subprocess 
output = subprocess.call(['test.sh'])
Run Code Online (Sandbox Code Playgroud)

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))
Run Code Online (Sandbox Code Playgroud)

3 - 调用脚本并在temp_file中转储temp.txt的echo命令

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)
Run Code Online (Sandbox Code Playgroud)

不要忘记查看doc子流程

  • **注意** 不要将 stdout=PIPE 或 stderr=PIPE 与 ```subprocess.call``` 一起使用。如果子进程生成足够的输出到管道以填充操作系统管道缓冲区,因为管道未被读取,则子进程将阻塞。 (2认同)

Kév*_*oix 8

我知道这是一个老问题,但我最近偶然发现了这个问题,它最终误导了我,因为Subprocess API 自 python 3.5 以来发生了变化。

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

import subprocess

subprocess.run(['./test.sh'])
Run Code Online (Sandbox Code Playgroud)


Ris*_*sal 5

如果脚本有多个参数

#!/usr/bin/python

import subprocess
output = subprocess.call(["./test.sh","xyz","1234"])
print output
Run Code Online (Sandbox Code Playgroud)

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

podname=xyz  serial=1234
0
Run Code Online (Sandbox Code Playgroud)

下面是 test.sh shell 脚本。

#!/bin/bash

podname=$1
serial=$2
echo "podname=$podname  serial=$serial"
Run Code Online (Sandbox Code Playgroud)