使用Python将变量传递给bash命令

时间:2018-10-23 20:00:44

标签: python bash variables cygwin

我有下一个代码:

from subprocess import Popen, PIPE

p = Popen("C:/cygwin64/bin/bash.exe", stdin=PIPE, stdout=PIPE)

path = "C:/Users/Link/Desktop/folder/"

p.stdin.write(b"cd " + str.encode(path)))

p.stdin.close()
out = p.stdout.read()
print(out)

outputb''

有什么方法可以将变量传递给bash命令p.stdin.write(b"cd " + path)

我问,因为上面的写法不起作用。输出为空,就像Cygwin启动一样,

编辑

只要我认为问题不太清楚,就添加这种情况:

我在Windows上并且正在使用Python 3.6。 我有一个bash cmd,要求执行Cygwin。此cmd的字符串中可能有一个变量,该变量将在每次执行后更改。想象一个执行命令的for循环。

例如(ImageMagick命令):

convert image.jpg -resize 1024x768 output_file.jpg

如何使用output_file.jpg作为变量从Python执行此cmd?

2 个答案:

答案 0 :(得分:0)

Bash默认情况下不会以交互模式运行,除非它检测到标准输入和输出已连接到终端。您PIPE将它们插入其中,因此它们肯定没有连接到终端。

Bash在非交互模式下不显示任何提示,因此您什么也看不到。您可以强制使其与-i开关进行交互。

但是,即使那样,它也不会写到stdout,而是写到stderr;您可以尝试将stderr传递到stdout

from subprocess import Popen, PIPE, STDOUT
p = Popen(["C:/cygwin64/bin/bash.exe", "-i"], stdin=PIPE, stdout=PIPE, stderr=STDOUT)

,您将捕获提示等。

或者将原始方法与产生输出的命令结合使用-在这里pwd会打印当前工作目录:

p.stdin.write(b"cd " + path.encode() + b"\n")
p.stdin.write(b"pwd")

尽管如此,与这样的交互过程进行对话非常棘手-读得太少=>死锁。写太多=>死锁。这就是Popen具有.communicate方法的原因,该方法可以一次提供所有输入,然后再获取stdoutstderr

答案 1 :(得分:0)

似乎您使用的是Cygwin python,所以应该使用适当的 Posix路径而不是类似Windows的路径

代替

p = Popen("C:/cygwin64/bin/bash.exe", stdin=PIPE, stdout=PIPE)

使用

p = Popen("/bin/bash.exe", stdin=PIPE, stdout=PIPE)