2015-12-15 100 views
0

我在写一个将参数传递给shell脚本的python程序。将参数传递给来自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但它没有帮助。

+2

你可以复制python本身的文件。 'shutil.copy2('/ home/pi/project/myPic.jpg','/home/pi/project/newImage.jpg')'。无需使子流程调用复杂化。 – tdelaney

回答

2

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

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

我也想提一提,因为你的脚本只是简单地调用在shell副本,你应该削减了中间商,只是使用Python直接的shutil.copy。这比为此任务运行子进程更合适。

1

的安全和可靠的方法是:

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

你的第一次尝试失败,因为字面字符串需要在Python的报价。第二个失败,因为Popen默认情况下不运行shell(您链接的问题设置Shell=true来执行此操作,但它很脆弱并且很糟糕)。

-1

当你拿到2个答案显示如何使用subprocess与可迭代的论点,我会推荐去的那些方式之一,为了完整性您可以使用包含完整的命令字符串,如果你指定shell=True,但你对所有引用以及类似于争论的所有内容负责。

Process=subprocess.Popen('./copyImage.sh %s' % shlex.quote("myPic.jpg"), shell=True) 

注意,除了加入shell=True我传递参数通过shlex.quote让它处理转义任何特殊字符,使之成为更加安全,如果文件名从用户输入进来,否则它可能包括一个;和例如,运行另一个命令。像myPic.jpg; rm -rf ~这样的输入在执行时会导致不好的事情发生。

如果您未指定shell=True,则subrpocess模块​​实际上将查找名为copyImage.sh myPic.jpg的可执行文件,其中空格和两个字都是要运行的可执行文件的名称。

还有两个注意事项,用于python 2而不是shlex.quote使用pipes.quote。而且,上面的shell脚本不会引用它的参数,所以不能使用带空格或其他特殊字符的名称。它应该被修改为引用它的变量(这是always a good idea):

#!/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上产生以下输出

Arg 1 is: This has ; bad stuff 
+0

由于您必须负责转义,您可以将其添加到示例中吗? –

+0

@thatotherguy我实际上在参数中引用了'%s',但我会更多地调用它,哎呀,这仍然不够好(请参阅此方法的问题)让我修复它以实际保护争论更恰当! –

+0

@thatotherguy好的,现在应该会更好,谢谢你的提示! –