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的值周围。
有没有什么建议,告诉我哪里走错了方法?
谢谢。
3 个回答
0
那是一个列表,里面是字符串,所以需要用引号包起来:
["myscript.sh", "var=11; ignore all", "/path/to/files"]
这样应该可以。如果你的脚本确实依赖于引号的话,那就试试这个(我对subprocess是怎么工作的细节不太了解):
["myscript.sh", "'var=11; ignore all'", "/path/to/files"]
2
我还没搞清楚为什么这样能工作,但确实能,而且不需要设置shell=True。
subprocess.Popen(["/bin/bash", "myscript.sh", '""' + string_to_be_quoted + '""', path_to_files])
11
当你在Popen中使用shell=True时,你需要传入你在命令行上会输入的内容。这意味着你的列表应该只有一个元素。比如说:
subprocess.Popen(['myscript.sh "var=11; ignore all" /path/to/files'], shell=True, executable="/bin/bash")
或者如果/path/to/files是你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; ignore all”作为一个参数传给了你的脚本。如果这些是不同的参数,记得把它们分开成不同的列表元素。