如何读取stdin?一些代码高尔夫挑战需要使用stdin进行输入。


当前回答

我在读取通过管道连接到它的套接字时遇到了一些问题。当套接字关闭时,它开始在活动循环中返回空字符串。所以这是我的解决方案(我只在linux中测试过,但希望它能在所有其他系统中运行)

import sys, os
sep=os.linesep

while sep == os.linesep:
    data = sys.stdin.readline()               
    sep = data[-len(os.linesep):]
    print '> "%s"' % data.strip()

因此,如果您开始监听套接字,它将正常工作(例如在bash中):

while :; do nc -l 12345 | python test.py ; done

您可以使用telnet调用它,也可以将浏览器指向localhost:1245

其他回答

以下是学习Python的内容:

import sys
data = sys.stdin.readlines()
print "Counted", len(data), "lines."

在Unix上,您可以通过以下方式进行测试:

% cat countlines.py | python countlines.py 
Counted 3 lines.

在Windows或DOS上,您可以执行以下操作:

C:\> type countlines.py | python countlines.py 
Counted 3 lines.

从Python 3.8开始,您可以使用赋值表达式:

while (line := input()):
    print(line)

关于此:

对于sys.stdin中的行:

我只是在python2.7上尝试了它(按照其他人的建议),用于一个非常大的文件,我不推荐它,正是出于上述原因(很长一段时间没有发生任何事情)。

我最终得到了一个稍微更像蟒蛇的解决方案(它适用于更大的文件):

with open(sys.argv[1], 'r') as f:
    for line in f:

然后我可以在本地运行脚本:

python myscript.py "0 1 2 3 4..." # can be a multi-line string or filename - any std.in input will work

其他人提出的答案:

for line in sys.stdin:
  print line

是非常简单和Python化的,但必须注意的是,脚本将等待EOF,然后开始迭代输入行。

这意味着tail-f error_log | myscript.py不会按预期处理行。

这种用例的正确脚本是:

while 1:
    try:
        line = sys.stdin.readline()
    except KeyboardInterrupt:
        break

    if not line:
        break

    print line

更新从评论中可以看出,在python2上可能只涉及缓冲区,因此在发出打印调用之前,您最终会等待缓冲区填充或EOF。

当使用-c命令时,作为一种巧妙的方法,您可以将shell脚本命令放在以$符号开头的括号内的引号中,而不是读取stdin(在某些情况下更灵活)。

e.g.

python3 -c "import sys; print(len(sys.argv[1].split('\n')))" "$(cat ~/.goldendict/history)"

这将统计goldendict历史文件中的行数。