2011-01-25 70 views
2

我遇到了子进程和打印引号的问题。python子进程调用bash脚本 - 也需要打印报价

我的Python脚本需要用户输入,将它篡改一下 - 我需要它以这种方式将结果发送到bash脚本。

myscript.sh 'var1 == a var2 == b; othervar == c' /path/to/other/files 

我挂断的地方是单引号。 Python试图将它们撕掉。

我把这个用于我的测试。

subprocess.Popen([myscript.sh 'var=11; ignore all' /path/to/files], shell=True, executable="/bin/bash") 

它返回无效语法指向第二个单引号。我也尝试了上面没有括号和外部使用单引号和内部双引号等。

其他 - 似。

正如我上面说的'var == a var == b; othervar == c'是从python脚本(以字符串格式)派生的 - 我需要在子进程中调用它,像这样。

subprocess.Popen([myscript.sh myvariables /path/to/files], shell=True, executable="/bin/bash") 

我只需要像第一个例子一样把单引号放在myvariables的值周围。

任何指针,我要去哪里正确的方法?

谢谢。

+0

我想我们今天有这个错误。是什么让人们认为这是远程有效的语法?列表项目用逗号分隔。而一个空白的“foo”与字符串“foo”无关。 (另外:我不能罚你引用的例子,你介意给出一个行号?) – delnan 2011-01-25 20:17:37

回答

6

当壳=真传递给POPEN,你通过任何你想做的发送命令行。这意味着你的列表应该只有一个元素。因此,例如:

subprocess.Popen(['myscript.sh "var=11; ignore all" /path/to/files'], shell=True, executable="/bin/bash") 

或者,如果/路径/到/文件是在你的Python环境变量:

subprocess.Popen(['myscript.sh "var=11; ignore all" %s' % path_to_files], shell=True, executable="/bin/bash") 

说了这么多我强烈建议您不要使用shell的说法。原因是脆弱。你会得到做这样的一个更可靠的方法:

subprocess.Popen(["/bin/bash", "myscript.sh", "var=11; ignore all", path_to_files]) 

注意,“VAR = 11;忽略所有”作为一个参数传送给脚本传递。如果这些是单独的参数,请将它们分隔列表元素。

0

这是一个列表,这些都是它的字符串,所以他们需要报价:

["myscript.sh", "var=11; ignore all", "/path/to/files"] 

这应该工作。如果你的脚本真的不知何故依赖于报价,那就试试这个(我不知道如何子工程的详情):

["myscript.sh", "'var=11; ignore all'", "/path/to/files"] 
+0

我相信`subprocess`负责在必要时添加引号 - 如果它根本就没有通过shell(我认为有一些方法可以调用程序并指定不需要将可执行文件名和参数粘合到一个大字符串被一些shell解析;)) – delnan 2011-01-25 20:25:16

+0

@delnan:是的,我认为你是对的。更新。 – 2011-01-25 20:27:10

2

我还没有检查为什么这个工作,但它并且没有需要shell = True。

subprocess.Popen(["/bin/bash", "myscript.sh", '""' + string_to_be_quoted + '""', path_to_files])