从Python传递参数到shell脚本

时间:2015-12-15 00:31:30

标签: python linux shell

我正在编写一个python程序,它将参数传递给shell脚本。

这是我的python代码:

import subprocess

Process=subprocess.Popen('./copyImage.sh %s' %s str(myPic.jpg))

我的“copyImage.sh”:

#!/bin/sh

cp /home/pi/project/$1 /home/pi/project/newImage.jpg

我可以在终端上运行脚本而不会出现问题。但是当执行python代码时,终端返回"NameError: name 'myPic' is not defined"

如果我将语法更改为

Process=subprocess.Popen('./copyImage.sh %s' %s "myPic.jpg")

然后终端返回"OSError: [Errno 2] No such file or directory"

我遵循了这个:Python: executing shell script with arguments(variable), but argument is not read in shell script但它没有帮助。

4 个答案:

答案 0 :(得分:4)

使用os.system调用是这样的方式:

  1. os.system确实在环境中找到您的Shell脚本
  2. 您可以根据需要在目标Shell脚本中附加任意数量的参数

示例:

os.system('myshellscript1 ' + arg1 + ' ' + arg2)

答案 1 :(得分:2)

subprocess模块需要一个参数列表,而不是一个以空格分隔的字符串。你尝试的方式导致python寻找一个名为"copyImage.sh myPic.jpg"的程序并且不带参数调用它,而你想要查找一个名为copyImage.sh的程序并用一个参数调用它。

subprocess.check_call(['copyImage.sh', 'myPic.jpg'])

我还想提一下,因为你的脚本只是在shell中调用copy,你应该切断中间人并直接使用python的shutil.copy。它比为此任务运行子进程更合适。

答案 2 :(得分:1)

安全可靠的方式是:

subprocess.Popen(["./copyImage.sh", "myPic.jpg"])

您的第一次尝试失败,因为字符串文字在Python中需要引号。第二个失败是因为Popen默认情况下没有运行shell(你链接的问题设置Shell=true来执行此操作,但它很脆弱且不好)。

答案 3 :(得分:-1)

虽然你有两个答案显示如何使用subprocess和参数的迭代,我建议你选择其中一种方法,为了完整性你可以使用包含完整命令的字符串,如果你指定{{ 1}},但是你负责所有的引用和所有类似的参数。

shell=True

请注意,除了添加Process=subprocess.Popen('./copyImage.sh %s' % shlex.quote("myPic.jpg"), shell=True) 之外,我通过shlex.quote传递参数,让它处理转义任何特殊字符,以便在文件名来自用户输入时使其更安全一些,否则它可以例如,包括shell=True和另一个要运行的命令。像;这样的输入会在执行时导致坏事发生。

如果您没有指定myPic.jpg; rm -rf ~,则subrpocess模块​​实际上将查找名为shell=True的可执行文件,其中包含空格和两个单词作为要运行的可执行文件的名称。

另外两个注释,对于python 2而不是copyImage.sh myPic.jpg使用shlex.quote。此外,上面的shell脚本不引用其参数,因此不能使用带空格或其他特殊字符的名称。应修改它以引用其变量(always a good idea):

pipes.quote

脚本略有不同:

#!/bin/sh

cp /home/pi/project/"$1" /home/pi/project/newImage.jpg

我们可以看到这项工作如下:

#!/bin/bash
printf 'Arg 1 is: %s\n' "$1"

subprocess.check_call("./demoScript.sh %s" % shlex.quote("This has ; bad stuff"), shell=True)

上产生以下输出
stdout