将命令的输出管道到交互式Python会话中?

2 投票
3 回答
2436 浏览
提问于 2025-04-15 19:37

我想做的事情大概是这样的:

 $echo $PATH | python --remain-interactive "x = raw_input().split(':')"
 >>>
 >>> print x
 ['/usr/local/bin', '/usr/bin', '/bin']

我觉得用ipython来解决这个问题是最好的。如果这做不到,那你有什么建议可以处理来自其他命令的输出呢?我之前用过subprocess来解决这个问题,但那并不是最理想的办法。

更新:现在这个方案离我想要的结果越来越近了:

 echo $PATH > /tmp/stdout.txt; ipython -i -c 'stdout = open("/tmp/stdout.txt").read()'

那么我们该如何把它变成一个形式呢

 echo $PATH | pyout

pyout成为“解决我所有问题的魔法方案”。这可以是一个shell脚本,它写入管道输出,然后运行ipython。所有的尝试都因为bp说的原因而失败。

3 个回答

0

因为Python有个原则是“应该有一种明显的方法来做事情,而且最好只有一种”,所以我觉得没有比这个subprocess模块更好的方式来与其他进程互动了。

如果你能说说为什么下面这种方式“不是理想的”,那可能会更有帮助:

>>> process = subprocess.Popen(['cmd', '/c', 'echo %PATH%'], stdout=subprocess.PIPE)
>>> print process.communicate()[0].split(';')

(在你具体的例子中,你可以使用os.environ,但我知道这并不是你真正想问的。)

1

你想要的 --remain-interactive 选项其实是 -i。你还可以用 -c 选项来指定要执行的命令,比如 __import__("sys").stdin.read().split(":")。所以你可以尝试这样做:(别忘了处理字符串中的转义!)

echo $PATH | python -i -c x = __import__(\"sys\").stdin.read().split(\":\")

不过,这里只会显示这些内容:

>>>

那么,为什么不行呢?因为你在使用管道。Python 解释器试图从同一个 sys.stdin 中交互式地读取命令,而你正是从这里读取参数。由于 echo 已经执行完了,sys.stdin 被关闭了,所以就无法再输入了。

出于同样的原因,像这样的操作:

echo $PATH > spam
python -i -c x = __import__(\"sys\").stdin.read().split(\":\") < spam

...也会失败。

我会这样做:

echo $PATH > spam.bar
python -i my_app.py spam.bar

毕竟,open("spam.bar") 就像 sys.stdin 一样,都是文件对象 :)

2

在IPython中,你可以这样做

x = !echo $$$$PATH

不过,双重转义$确实让人头疼

我想你也可以这样做

PATH="$PATH"
x = !echo $PATH
x[0].split(":")

撰写回答