3

我最近在 python 中做了大量的工作,并希望能够使用它的功能而不是 shell/bash 内置/shell 脚本。

所以对于这样的 shell 管道:

echo -e "Line One\nLine Two\nLine Three" | (cat<<-HERE | python
import sys
print 'stdout hi'
for line in sys.stdin.readlines():
  print ('stdout hi on line: %s\n' %line)
HERE
) | tee -a tee.out

打印的所有内容都是“stdout hi”

这里需要修复什么?

谢谢!

4

1 回答 1

6

如果你能解释一下你对这个结构的目标是什么,那就更好了。也许它可以简化?

问题在于这个脚本,它echo转到stdin(...)符号启动的封装外壳。但是在 shell 内部,stdin 被重新定义为通过管道传输到,因此它从 stdin 读取脚本,该脚本现在来自管道。

所以你尝试这样的事情:

echo -e "Line One\nLine Two\nLine Three" |  python <(cat <<HERE
import sys
print "stdout hi"
for line in sys.stdin:
  print line.rstrip()
print "stdout hi"
HERE
)

输出:

stdout hi
Line One
Line Two
Line Three
stdout hi

现在脚本是从 读取的/dev/fd/<filehandle>,所以stdin可以被echo' 管道使用。

解决方案#2

还有另一种解决方案。该脚本可以作为这里的文档发送到的标准输入,但是输入管道必须重定向到另一个文件描述符。为此fdopen(3),必须在脚本中使用 like 函数。我对不熟悉,所以我展示了一个示例:

exec 10< <(echo -e "Line One\nLine Two\nLine Three")

perl <<'XXX'
print "stdout hi\n";
open($hin, "<&=", 10) or die;
while (<$hin>) { print $_; }
print "stdout hi\n";
XXX

这里echo重定向到文件句柄 10,它在脚本中打开。

但是echo可以fork使用另一个删除该部分(-1) :

exec 10<<XXX
Line One
Line Two
Line Three
XXX

多行脚本

-c或者简单地使用以下选项输入一个多脚本:

echo -e "Line One\nLine Two\nLine Three"|python -c 'import sys
print "Stdout hi"
for line in sys.stdin:
  print line.rstrip()
print "Stdout hi"'
于 2013-06-13T22:22:22.780 回答