Python:使用参数(变量)执行shell脚本,但是在shell脚本中未读取参数

18

我正在尝试从Python中执行一个shell脚本(而不是命令):

main.py
-------
from subprocess import Popen

Process=Popen(['./childdir/execute.sh',str(var1),str(var2)],shell=True)

execute.sh
----------

echo $1 //does not print anything
echo $2 //does not print anything

var1和var2是我作为输入用于shell脚本的某些字符串。我是否漏掉了什么或是否有其他方法可以做到这一点?

参考:如何在Python中使用subprocess popen

3个回答

19
问题出在shell=True上。要么删除该参数,要么将所有参数作为字符串传递,如下所示:
Process=Popen('./childdir/execute.sh %s %s' % (str(var1),str(var2),), shell=True)

当你使用Popen的第一个参数传递参数时,shell仅会将你提供的参数传递给进程,因为shell自己解释参数。在这里可以看到类似问题的解答:这里。实际上发生的是您的shell脚本没有收到任何参数,所以$1和$2为空。

Popen将从python脚本继承stdout和stderr,因此通常不需要为Popen提供stdin=stderr=参数(除非您使用输出重定向,例如>)。只有在需要在python脚本中读取输出并对其进行某些操作时,才应该这样做。

如果您只需要获取输出(并且不介意同步运行),我建议尝试check_output,因为它比Popen更容易获取输出:

output = subprocess.check_output(['./childdir/execute.sh',str(var1),str(var2)])
print(output)

请注意,check_outputcheck_callshell=参数规则与Popen相同。

如果它解决了你的问题,你应该接受它(点击复选标记),并考虑点赞。 - SethMMorton
在这种情况下不应使用shell=True,但如果您使用它,则应使用shlex.quote()转义var1var2output = check_output("./childdir/execute.sh " + " ".join(pipes.quote(str(v)) for v in [var1, var2]), shell=True) - jfs
请注意,输出类型为bytes,在使用之前可能需要转换为str,例如: output.decode("utf-8") - Gogowitsch

3

实际上你正在发送参数...如果你的 shell 脚本写了一个文件而不是打印输出,你会看到它。为了查看脚本的输出,需要与其通信...

from subprocess import Popen,PIPE

Process=Popen(['./childdir/execute.sh',str(var1),str(var2)],shell=True,stdin=PIPE,stderr=PIPE)
print Process.communicate() #now you should see your output

2
此外,如果他们只想查看输出,他们可以使用 subprocess.call(['./childdir/execute.sh',str(var1),str(var2)],shell=True) - SethMMorton
@Joran:我能够通过shell=True看到shell脚本的输出。我能够看到$0('./childdir/execute.sh')即正在执行的脚本,但是无法看到参数var1、var2等。 - creativeDrive
也许在shell脚本的顶部加上shebang会有所帮助,它可能并不在bash中运行,但我保证您已经发送了参数(也许这些参数并不是您想要的)。 - Joran Beasley
@SethMMorton:我尝试了两个选项,但是我收到了错误信息(./execute.sh:权限被拒绝)。虽然我已经给予执行权限(chmod +x execute.sh)。 - creativeDrive
@Joran 我也试过使用shebang...为了调试,我创建了两个小脚本来检查这个问题,但是当我打印process.communicate()时,它会打印(None.[])。 - creativeDrive
尝试运行以下内容 pythscr.py -------------------------------- #!/usr/bin/env python from subprocess import Popen, PIPE var1="1000" var2="2000" print var1 print var2 process=Popen(['bash shellscr.sh',str(var1),str(var2)],shell=True,stdin=PIPE,stderr=PIPE) print process.communicate()

shellscr.sh

#!/bin/bash echo $0 echo $1 echo $2
- creativeDrive

3
如果你想以简单的方式从 Python 脚本向 shell 脚本发送参数,你可以使用 Python 的 os 模块:
import os  
os.system(' /path/shellscriptfile.sh {} {}' .format(str(var1), str(var2)) 

如果您有更多的参数..增加大括号并添加参数.. 在shell脚本文件中..这将读取参数,您可以相应地执行命令

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接