以下的想法是使用Bash从Python中选择,例如:使用Bash select来获取用户的输入,与Bash脚本通信以获取用户选择并在Python代码中使用它。请告诉我它是否至少可能。
拥有以下简单的Bash脚本:
#!/bin/bash -x
function select_target {
target_list=("Target1" "Target2" "Target3")
PS3="Select Target: "
select target in "${target_list[@]}"; do
break
done
echo $target
}
select_target
它独立运作 现在我试着用Python调用它:
import tempfile
import subprocess
select_target_sh_func = """
#!/bin/bash
function select_target {
target_list=(%s)
PS3="Select Target: "
select target in "${target_list[@]}"; do
break
done
echo $target
}
select_target
"""
target_list = ["Target1", "Target2", "Target3"]
with tempfile.NamedTemporaryFile() as temp:
temp.write(select_target_sh_func % ' '.join(map(lambda s : '\"%s\"' % str(s),target_list)))
subprocess.call(['chmod', '0777', temp.name])
sh_proc = subprocess.Popen(["bash", temp.name], stdout=subprocess.PIPE)
(output, err) = sh_proc.communicate()
exit_code = sh_proc.wait()
print output
它什么都不做。没有输出,没有选择。 我正在使用High Sierra MacOS,PyCharm和Python 2.7。
PS 经过一些阅读和实验后,结果如下:
with tempfile.NamedTemporaryFile() as temp:
temp.write(select_target_sh_func % ' '.join(map(lambda s : '\"%s\"' % str(s),target_list)))
temp.flush()
# bash: /var/folders/jm/4j4mq_w52bx2l5qwg4gt44580000gn/T/tmp00laDV: Permission denied
subprocess.call(['chmod', '0500', temp.name])
sh_proc = subprocess.Popen(["bash", "-c", temp.name], stdout=subprocess.PIPE)
(output, err) = sh_proc.communicate()
exit_code = sh_proc.wait()
print output
它的行为与我预期的一样,用户可以选择'目标'只需输入数字即可。我的错误是我忘记了冲洗。
PPS 该解决方案适用于MacOS X High Sierra,遗憾的是它不适用于Debian Jessie抱怨以下内容:
bash: /tmp/tmpdTv4hp: Text file busy
我相信这是因为`用tempfile.NamedTemporaryFile'保持临时文件打开,这以某种方式阻止Bash使用它。这使得整个想法毫无用处。
答案 0 :(得分:0)
Python正在您的终端或控制台和您正在启动的(非交互!)Bash进程之间。此外,您无法将标准输出管道定向到任何位置,因此subprocess.communicate()
实际上无法捕获标准错误(如果可能,您将无法看到脚本的菜单)。
以编程方式运行交互式流程是一个非常重要的场景;你会想看看pexpect
或者只是在Python中实现你自己的select
命令 - 我怀疑这将是最简单的解决方案(如果你能找到一个现有的库,那将是非常简单的)