python子进程调用bash脚本 - 也需要打印引号

5 投票
3 回答
24442 浏览
提问于 2025-04-16 10:36

我在使用子进程和打印引号时遇到了问题。

我的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”作为一个参数传给了你的脚本。如果这些是不同的参数,记得把它们分开成不同的列表元素。

撰写回答