经过多年的 bash 脚本编写之后,我收到了修改 python 脚本的任务,以使其在满足某些条件时调用 shell 脚本。这部分还不错,但现在我试图从 python 脚本中向这个 shell 脚本发送一个变量,但我迷路了。
shell脚本采用stdin,这是我试图放置python变量值的地方,它只是一个整数。
我的代码(到目前为止)如下所示:
if VAR > NUMBER:
import os
bashCommand = "echo something | /path/to/script --args"
os.system(bashCommand)
而且效果很好。但我想做的是使 os.system(bashCommand) 等效于:
echo $VAR | /path/to/script --args
甚至
echo 'some text' $VAR | /path/to/script --args
考虑到 os.system 的工作方式,尽管我的做法似乎完全错误。
所以我想我的问题是如何将 VAR 的值传递给 bashCommand,最好作为标准输入?
答案1
不要使用os.system()
,它已被弃用,取而代之的是subprocess
模块。
在您的情况下,您可以subprocess
直接使用模块,最好不要使用该shell=True
参数,因为直接在 shell 中运行命令是不安全的。您需要的所有功能(例如管道)都可以由subprocess
模块模拟。
让我们看这个例子:
import subprocess
var = 'foobar'
first = subprocess.Popen(['/bin/echo', var], stdout=subprocess.PIPE)
second = subprocess.Popen(['bash', '/path/to/script', '--args'], stdin=first.stdout)
我们定义了一个 variable var
,然后我们使用该类来获取usingsubprocess.Popen
的值,然后将该值发送到管道。这是一个类的对象。var
/bin/echo
first
subprocess.Popen
然后我们使用via管道的STDOUTfirst
作为STDIN并相应地执行脚本。second
bash
如果您想将命令的输出保存为字符串,请使用subprocess.check_output
函数,例如:
second = subprocess.check_output(['bash', '/path/to/script', '--args'], stdin=first.stdout)
阅读subprocess模块的官方文档以获得更多想法。
答案2
Python 不像 bash 那样扩展字符串中的变量。如果你有VAR
python 并想将其传递给 bash 你可以这样做
subprocess.call('echo {} | /path/to/script --args'.format(VAR), shell=True)
如果VAR
在 python 中保存了您想要扩展的 bash 变量的名称,您可以执行类似的操作:
subprocess.call('echo "${}" | /path/to/script --args'.format(VAR), shell=True)
答案3
调用os.system()
已被弃用,但仍然有效。该功能将来可能会消失(很可能会消失),因此您可能需要认真考虑使用subprocess
模块重构这些调用,该模块有一种非常简单的方法可以将数据发送到子进程的 STDIN 并从其 STDOUT 读取。https://docs.python.org/2/library/subprocess.html
答案4
我认为好的做法是:
var = subprocess.Popen(['/bin/echo', var], stdout=subprocess.PIPE)
second = subprocess.Popen(['bash', '/path/to/script', '--args'],stdin=var.stdout, stdout=subprocess.PIPE)
var.stdout.close()
output = second.communicate()[0]
var.wait()