简体   繁体   English

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

[英]Pass variable to bash command with Python

I have the next code: 我有下一个代码:

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)

The output is b'' outputb''

Is there any way to pass a variable to the bash command p.stdin.write(b"cd " + path) 有什么办法可以将变量传递给bash命令p.stdin.write(b"cd " + path)

I ask because the way it is written above don't work. 我问,因为上面的写法行不通。 Output is null, just like Cygwin started and nothing else. 输出为空,就像Cygwin启动一样,什么也没有。

EDIT 编辑

As long as I see the question is not so clear, I'll add this scenario: 只要我看到的问题不是很清楚,我就添加这种情况:

I am on Windows and I am using Python 3.6. 我在Windows上,并且正在使用Python 3.6。 I have a bash cmd that requieres Cygwin to be executed. 我有一个bash cmd,要求执行Cygwin。 This cmd may have a variable in his string, which will change after every execution. 此cmd的字符串中可能有一个变量,该变量将在每次执行后更改。 Immagine a for loop which executes a command. 想象一个执行命令的for循环。

For example (an ImageMagick command): 例如(一个ImageMagick命令):

convert image.jpg -resize 1024x768 output_file.jpg

How can I execute this cmd from Python with output_file.jpg as variable ? 如何使用output_file.jpg作为变量从Python执行此cmd?

Bash doesn't run in interactive mode by default unless it detects that standard input and output are connected to a terminal. Bash默认情况下不会以交互方式运行,除非它检测到标准输入和输出已连接到终端。 You PIPE d these in, therefore they're definitely not connected to a terminal. 您将它们插入PIPE ,因此它们肯定没有连接到终端。

Bash does not display any prompts in non-interactive mode, hence you see nothing. Bash在非交互模式下不显示任何提示,因此您什么也看不到。 You can force it to be interactive with -i switch. 您可以强制它与-i开关交互。

However, even then, it is not going to write to stdout but stderr ; 但是,即使那样,它也不会写到stdout而是写到stderr you can try piping stderr to stdout 您可以尝试将stderr管道连接到stdout

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

and you will capture the prompts and such. 您将捕获提示等。

Or use your original approach with a command that does produce output - here pwd that prints the current working directory: 或将原始方法与产生输出的命令一起使用-在这里pwd打印当前工作目录:

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

It is tricky to talk to an interactive process like this though - read too little => deadlock. 但是,与这样的交互过程进行交谈是棘手的-读得太少=>死锁。 Write too much => deadlock. 写太多=>死锁。 This is why Popen has the .communicate method for providing all of input at once and getting the stdout and stderr afterwards. 这就是Popen具有.communicate方法的原因,该方法可一次提供所有输入,然后再获取stdoutstderr

As it seems you are using the Cygwin python, than you should use proper Posix paths and not Windows-like ones 看来您正在使用Cygwin python,而不是应该使用正确的Posix路径而不是Windows路径

Instead of 代替

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

use 采用

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM