[英]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''
output
是b''
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
方法的原因,该方法可一次提供所有输入,然后再获取stdout
和stderr
。
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.