将命令的输出管道到交互式Python会话中?
我想做的事情大概是这样的:
$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(":")