2014-12-04 114 views
5

有人可以解释为什么这短短的bash/python的命令不输出“你好”读取标准输入在bash

$ echo hello | python - <<END 
import sys 
for line in sys.stdin: 
    print line 
END 

如果我在我的python脚本保存到一个文件,如预期该命令的作品。

在script.py

import sys 
for line in sys.stdin: 
    print line 
END 

$回声 “你好” |蟒蛇script.py

“你好”

回答

4

因为python << END重定向标准输入读取程序。你也不能从stdin上的echo上读取这条线。

3

哦,男孩,这很合理!在过去的一个小时里我一直在努力,最后我明白了,谢谢你们。

要为原始程序提供一个工作选择,你可以做这样的事情:

$ echo hello | python <(cat <<END 
import sys 
for line in sys.stdin: 
    print line 
END 
) 

但要小心!如果你把它放在一个文件中,最后的END需要触摸左边的水槽(没有空格)。否则,它不会解析“文件的意外结束,同时寻找匹配的字符”错误或类似的东西(实际上,这使我花了两个多小时才找出答案)。

解释的代码,正在发生的事情是,<<END ... END<(cat ...)联合创建一个文件(在/dev/fd),以便它可以供给到python,就好像它是一个真正的文件。引用this关于<(...)的说明:

这是过程替换。它将命令的输出送入一个 FIFO,它可以像普通文件一样读取。

有关于这个话题here另一个有趣的答案。

+0

这是一个创新,但仍然从根本上[无用的'猫'](http://www.iki.fi/era/unix/award.html)。尽管构造避免了捆绑标准输入(shell基本上使得流程替换的输出可用作命名临时文件),但shell在进程替换中不需要'cat'的帮助,即可将此文档提供给Python, 。 – tripleee 2017-09-26 04:40:37

3

它不工作的原因是你有冲突的重定向。 echo | python尝试将标准输入连接到echo的管道,而python - <<HERE尝试将标准输入连接到here文档。你不能拥有两个。 (这里的文档是赢的。)

但是,真的没有理由想在标准输入上管脚本身。

bash$ echo hello | python -c ' 
> import sys 
> for line in sys.stdin: 
> print line' 
hello