您如何从stdin阅读?

问题:您如何从stdin阅读?

我正在尝试挑战一些代码挑战,但是所有这些挑战都需要从输入stdin。我如何在Python中得到它?

I’m trying to do some of the code golf challenges, but they all require the input to be taken from stdin. How do I get that in Python?


回答 0

您可以使用以下fileinput模块:

import fileinput

for line in fileinput.input():
    pass

fileinput 将在输入中指定为命令行参数中指定的文件名的所有行,如果没有提供参数则返回标准输入。

注意:line将包含尾随换行符;删除它使用line.rstrip()

You could use the fileinput module:

import fileinput

for line in fileinput.input():
    pass

fileinput will loop through all the lines in the input specified as file names given in command-line arguments, or the standard input if no arguments are provided.

Note: line will contain a trailing newline; to remove it use line.rstrip()


回答 1

有几种方法可以做到。

  • sys.stdin是一个类似于文件的对象,可以在其上调用函数,read或者readlines如果要读取所有内容,或者要读取所有内容并自动按换行符将其拆分,则可以在其上调用。(您需要使它import sys起作用。)

  • 如果要提示用户输入,则可以raw_input在Python 2.X和inputPython 3中使用。

  • 如果您实际上只想阅读命令行选项,则可以通过sys.argv列表访问它们。

您可能还会发现有关I / O和Python的Wikibook这篇文章也是有用的参考。

There’s a few ways to do it.

  • sys.stdin is a file-like object on which you can call functions read or readlines if you want to read everything or you want to read everything and split it by newline automatically. (You need to import sys for this to work.)

  • If you want to prompt the user for input, you can use raw_input in Python 2.X, and just input in Python 3.

  • If you actually just want to read command-line options, you can access them via the sys.argv list.

You will probably find this Wikibook article on I/O in Python to be a useful reference as well.


回答 2

import sys

for line in sys.stdin:
    print(line)

请注意,这将在末尾包含换行符。要最后删除换行符,请使用line.rstrip()@brittohalloran所说的。

import sys

for line in sys.stdin:
    print(line)

Note that this will include a newline character at the end. To remove the newline at the end, use line.rstrip() as @brittohalloran said.


回答 3

Python还具有内置函数input()raw_input()。请参阅“ 内置函数”下的Python文档。

例如,

name = raw_input("Enter your name: ")   # Python 2.x

要么

name = input("Enter your name: ")   # Python 3

Python also has built-in functions input() and raw_input(). See the Python documentation under Built-in Functions.

For example,

name = raw_input("Enter your name: ")   # Python 2.x

or

name = input("Enter your name: ")   # Python 3

回答 4

来自学习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.

Here’s from Learning Python:

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

On Unix, you could test it by doing something like:

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

On Windows or DOS, you’d do:

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

回答 5

您如何从Python的stdin中读取信息?

我正在尝试进行一些代码挑战,但是它们都要求输入来自stdin。我如何在Python中得到它?

您可以使用:

  • sys.stdin-类似于文件的对象-调用sys.stdin.read()以读取所有内容。
  • input(prompt)-向其传递一个可选的提示以输出,它从stdin读取直到第一个换行符,然后将其剥离。您必须重复执行此操作才能获得更多行,在输入结束时会引发EOFError。(可能不适用于打高尔夫球。)在Python 2中,这是rawinput(prompt)
  • open(0).read()-在Python 3中,内置函数open接受文件描述符(代表操作系统IO资源的整数),而0是的描述符stdin。它返回类似文件的对象sys.stdin-可能是打高尔夫球的最佳选择。在Python 2中,这是io.open
  • open('/dev/stdin').read()-与相似open(0),适用于Python 2和3,但不适用于Windows(甚至Cygwin)。
  • fileinput.input()-在中列出的所有文件中的行上返回迭代器sys.argv[1:],如果未指定,则返回stdin。使用''.join(fileinput.input())

双方sysfileinput必须进口的,分别的,当然。

sys.stdin与Python 2和3,Windows,Unix兼容的快速示例

例如,如果您将数据通过管道传输到stdin,则只需要readfrom sys.stdin

$ echo foo | python -c "import sys; print(sys.stdin.read())"
foo

我们可以看到它sys.stdin处于默认文本模式:

>>> import sys
>>> sys.stdin
<_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>

文件示例

假设您有一个文件,inputs.txt我们可以接受该文件并将其写回:

python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt

更长的答案

这是一个完整的,易于复制的演示,使用两种方法,内建函数inputraw_input在Python 2中使用)和sys.stdin。数据未修改,因此处理是非操作。

首先,让我们为输入创建一个文件:

$ python -c "print('foo\nbar\nbaz')" > inputs.txt

并使用我们已经看到的代码,我们可以检查是否已创建文件:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt 
foo
bar
baz

这是sys.stdin.readPython 3 的帮助:

read(size=-1, /) method of _io.TextIOWrapper instance
    Read at most n characters from stream.

    Read from underlying buffer until we have n characters or we hit EOF.
    If n is negative or omitted, read until EOF.

内置函数inputraw_input在Python 2中)

内置函数input从标准输入读取到换行符,然后将其剥离(补码print,默认情况下会添加换行符)。此过程一直持续到得到EOF(文件结束)为止,此时它引发EOFError

因此,这是input在Python 3(或raw_inputPython 2)中用于从stdin读取的方法-因此我们创建了一个称为stdindemo.py的Python模块:

$ python -c "print('try:\n    while True:\n        print(input())\nexcept EOFError:\n    pass')" > stdindemo.py 

让我们将其打印出来,以确保它符合我们的预期:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < stdindemo.py 
try:
    while True:
        print(input())
except EOFError:
    pass

再次,input读取直到换行符,并从行中删除它。print添加换行符。因此,尽管它们都修改了输入,但它们的修改被取消了。(因此,它们本质上是彼此的补充。)

input获取文件结尾字符时,它将引发EOFError,我们将其忽略,然后从程序退出。

在Linux / Unix上,我们可以通过cat进行管道传输:

$ cat inputs.txt | python -m stdindemo
foo
bar
baz

或者我们可以从stdin重定向文件:

$ python -m stdindemo < inputs.txt 
foo
bar
baz

我们还可以将模块作为脚本执行:

$ python stdindemo.py < inputs.txt 
foo
bar
baz

这是inputPython 3 内置函数的帮助:

input(prompt=None, /)
    Read a string from standard input.  The trailing newline is stripped.

    The prompt string, if given, is printed to standard output without a
    trailing newline before reading input.

    If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.
    On *nix systems, readline is used if available.

sys.stdin

在这里,我们使用编写演示脚本sys.stdin。迭代类似文件的对象的有效方法是使用类似文件的对象作为迭代器。从此输入写入stdout的补充方法是简单地使用sys.stdout.write

$ python -c "print('import sys\nfor line in sys.stdin:\n    sys.stdout.write(line)')" > stdindemo2.py

重新打印出来以确保它看起来正确:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < stdindemo2.py 
import sys
for line in sys.stdin:
    sys.stdout.write(line)

并将输入重定向到文件中:

$ python -m stdindemo2 < inputs.txt
foo
bar
baz

打入命令:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt
foo
bar
baz

高尔夫的文件描述符

由于文件描述符stdinstdout为0和1分别,我们也可以通过那些open在Python 3(而不是2,请注意,我们仍然需要“W”写到标准输出)。

如果这在您的系统上有效,它将删除更多字符。

$ python -c "open(1,'w').write(open(0).read())" < inputs.txt
baz
bar
foo

Python 2 io.open也可以这样做,但是导入需要更多空间:

$ python -c "from io import open; open(1,'w').write(open(0).read())" < inputs.txt 
foo
bar
baz

解决其他意见和答案

有一条评论建议''.join(sys.stdin)打高尔夫球,但是实际上比sys.stdin.read()长-再加上Python必须在内存中创建一个额外的列表(str.join如果没有给出列表,这是如何工作的)-对比一下:

''.join(sys.stdin)
sys.stdin.read()

最高答案表明:

import fileinput

for line in fileinput.input():
    pass

但是,由于sys.stdin实现了文件API,包括迭代器协议,因此与此相同:

import sys

for line in sys.stdin:
    pass

另一个答案确实表明了这一点。只要记住,如果你在解释这样做,你需要做的Ctrld如果你在Linux或Mac,或者Ctrlz在Windows上(后Enter),以结束文件的字符发送给该进程。此外,该答案还建议使用print(line)-最终会增加a-的'\n'使用print(line, end='')(如果在Python 2中,则需要from __future__ import print_function)。

真正的用例fileinput是读取一系列文件。

How do you read from stdin in Python?

I’m trying to do some of the code golf challenges, but they all require the input to be taken from stdin. How do I get that in Python?

You can use:

  • sys.stdin – A file-like object – call sys.stdin.read() to read everything.
  • input(prompt) – pass it an optional prompt to output, it reads from stdin up to the first newline, which it strips. You’d have to do this repeatedly to get more lines, at the end of the input it raises EOFError. (Probably not great for golfing.) In Python 2, this is rawinput(prompt).
  • open(0).read() – In Python 3, the builtin function open accepts file descriptors (integers representing operating system IO resources), and 0 is the descriptor of stdin. It returns a file-like object like sys.stdin – probably your best bet for golfing. In Python 2, this is io.open.
  • open('/dev/stdin').read() – similar to open(0), works on Python 2 and 3, but not on Windows (or even Cygwin).
  • fileinput.input() – returns an iterator over lines in all files listed in sys.argv[1:], or stdin if not given. Use like ''.join(fileinput.input()).

Both sys and fileinput must be imported, respectively, of course.

Quick sys.stdin examples compatible with Python 2 and 3, Windows, Unix

You just need to read from sys.stdin, for example, if you pipe data to stdin:

$ echo foo | python -c "import sys; print(sys.stdin.read())"
foo

We can see that sys.stdin is in default text mode:

>>> import sys
>>> sys.stdin
<_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>

file example

Say you have a file, inputs.txt, we can accept that file and write it back out:

python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt

Longer answer

Here’s a complete, easily replicable demo, using two methods, the builtin function, input (use raw_input in Python 2), and sys.stdin. The data is unmodified, so the processing is a non-operation.

To begin with, let’s create a file for inputs:

$ python -c "print('foo\nbar\nbaz')" > inputs.txt

And using the code we’ve already seen, we can check that we’ve created the file:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt 
foo
bar
baz

Here’s the help on sys.stdin.read from Python 3:

read(size=-1, /) method of _io.TextIOWrapper instance
    Read at most n characters from stream.

    Read from underlying buffer until we have n characters or we hit EOF.
    If n is negative or omitted, read until EOF.

Builtin function, input (raw_input in Python 2)

The builtin function input reads from standard input up to a newline, which is stripped (complementing print, which adds a newline by default.) This occurs until it gets EOF (End Of File), at which point it raises EOFError.

Thus, here’s how you can use input in Python 3 (or raw_input in Python 2) to read from stdin – so we create a Python module we call stdindemo.py:

$ python -c "print('try:\n    while True:\n        print(input())\nexcept EOFError:\n    pass')" > stdindemo.py 

And let’s print it back out to ensure it’s as we expect:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < stdindemo.py 
try:
    while True:
        print(input())
except EOFError:
    pass

Again, input reads up until the newline and essentially strips it from the line. print adds a newline. So while they both modify the input, their modifications cancel. (So they are essentially each other’s complement.)

And when input gets the end-of-file character, it raises EOFError, which we ignore and then exit from the program.

And on Linux/Unix, we can pipe from cat:

$ cat inputs.txt | python -m stdindemo
foo
bar
baz

Or we can just redirect the file from stdin:

$ python -m stdindemo < inputs.txt 
foo
bar
baz

We can also execute the module as a script:

$ python stdindemo.py < inputs.txt 
foo
bar
baz

Here’s the help on the builtin input from Python 3:

input(prompt=None, /)
    Read a string from standard input.  The trailing newline is stripped.

    The prompt string, if given, is printed to standard output without a
    trailing newline before reading input.

    If the user hits EOF (*nix: Ctrl-D, Windows: Ctrl-Z+Return), raise EOFError.
    On *nix systems, readline is used if available.

sys.stdin

Here we make a demo script using sys.stdin. The efficient way to iterate over a file-like object is to use the file-like object as an iterator. The complementary method to write to stdout from this input is to simply use sys.stdout.write:

$ python -c "print('import sys\nfor line in sys.stdin:\n    sys.stdout.write(line)')" > stdindemo2.py

Print it back out to make sure it looks right:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < stdindemo2.py 
import sys
for line in sys.stdin:
    sys.stdout.write(line)

And redirecting the inputs into the file:

$ python -m stdindemo2 < inputs.txt
foo
bar
baz

Golfed into a command:

$ python -c "import sys; sys.stdout.write(sys.stdin.read())" < inputs.txt
foo
bar
baz

File Descriptors for Golfing

Since the file descriptors for stdin and stdout are 0 and 1 respectively, we can also pass those to open in Python 3 (not 2, and note that we still need the ‘w’ for writing to stdout).

If this works on your system, it will shave off more characters.

$ python -c "open(1,'w').write(open(0).read())" < inputs.txt
baz
bar
foo

Python 2’s io.open does this as well, but the import takes a lot more space:

$ python -c "from io import open; open(1,'w').write(open(0).read())" < inputs.txt 
foo
bar
baz

Addressing other comments and answers

One comment suggests ''.join(sys.stdin) for golfing but that’s actually longer than sys.stdin.read() – plus Python must create an extra list in memory (that’s how str.join works when not given a list) – for contrast:

''.join(sys.stdin)
sys.stdin.read()

The top answer suggests:

import fileinput

for line in fileinput.input():
    pass

But, since sys.stdin implements the file API, including the iterator protocol, that’s just the same as this:

import sys

for line in sys.stdin:
    pass

Another answer does suggest this. Just remember that if you do it in an interpreter, you’ll need to do Ctrld if you’re on Linux or Mac, or Ctrlz on Windows (after Enter) to send the end-of-file character to the process. Also, that answer suggests print(line) – which adds a '\n' to the end – use print(line, end='') instead (if in Python 2, you’ll need from __future__ import print_function).

The real use-case for fileinput is for reading in a series of files.


回答 6

其他人提出的答案:

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

更新
从注释中可以看出,在python 2上仅可能涉及缓冲,因此您最终要在发出打印调用之前等待缓冲区填充或EOF。

The answer proposed by others:

for line in sys.stdin:
  print line

is very simple and pythonic, but it must be noted that the script will wait until EOF before starting to iterate on the lines of input.

This means that tail -f error_log | myscript.py will not process lines as expected.

The correct script for such a use case would be:

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

    if not line:
        break

    print line

UPDATE
From the comments it has been cleared that on python 2 only there might be buffering involved, so that you end up waiting for the buffer to fill or EOF before the print call is issued.


回答 7

这会将标准输入回显到标准输出:

import sys
line = sys.stdin.readline()
while line:
    print line,
    line = sys.stdin.readline()

This will echo standard input to standard output:

import sys
line = sys.stdin.readline()
while line:
    print line,
    line = sys.stdin.readline()

回答 8

如果使用sys.stdin,则还可以在所有变量上进行构建,如果至少存在一个自变量,则还可以执行以下操作从一个自变量文件中读取,否则返回标准输入:

import sys
f = open(sys.argv[1]) if len(sys.argv) > 1 else sys.stdin    
for line in f:
#     Do your stuff

并将其用作

$ python do-my-stuff.py infile.txt

要么

$ cat infile.txt | python do-my-stuff.py

甚至

$ python do-my-stuff.py < infile.txt

这将使你的Python脚本的行为像许多GNU / Unix程序,例如catgrepsed

Building on all the anwers using sys.stdin, you can also do something like the following to read from an argument file if at least one argument exists, and fall back to stdin otherwise:

import sys
f = open(sys.argv[1]) if len(sys.argv) > 1 else sys.stdin    
for line in f:
#     Do your stuff

and use it as either

$ python do-my-stuff.py infile.txt

or

$ cat infile.txt | python do-my-stuff.py

or even

$ python do-my-stuff.py < infile.txt

That would make your Python script behave like many GNU/Unix programs such as cat, grep and sed.


回答 9

argparse 是一个简单的解决方案

与Python第2版和第3版兼容的示例:

#!/usr/bin/python

import argparse
import sys

parser = argparse.ArgumentParser()

parser.add_argument('infile',
                    default=sys.stdin,
                    type=argparse.FileType('r'),
                    nargs='?')

args = parser.parse_args()

data = args.infile.read()

您可以通过多种方式运行此脚本:

1.使用 stdin

echo 'foo bar' | ./above-script.py

  或更短一些,只需替换echo此处的 字符串

./above-script.py <<< 'foo bar'

2.使用文件名参数

echo 'foo bar' > my-file.data
./above-script.py my-file.data

3. stdin通过特殊文件名使用-

echo 'foo bar' | ./above-script.py -

argparse is an easy solution

Example compatible with both Python versions 2 and 3:

#!/usr/bin/python

import argparse
import sys

parser = argparse.ArgumentParser()

parser.add_argument('infile',
                    default=sys.stdin,
                    type=argparse.FileType('r'),
                    nargs='?')

args = parser.parse_args()

data = args.infile.read()

You can run this script in many ways:

1. Using stdin

echo 'foo bar' | ./above-script.py

  or shorter by replacing echo by here string:

./above-script.py <<< 'foo bar'

2. Using a filename argument

echo 'foo bar' > my-file.data
./above-script.py my-file.data

3. Using stdin through the special filename -

echo 'foo bar' | ./above-script.py -

回答 10

以下代码芯片将为您提供帮助(它将把所有的stdin阻塞读EOF入到一个字符串中):

import sys
input_str = sys.stdin.read()
print input_str.split()

The following chip of code will help you (it will read all of stdin blocking unto EOF, into one string):

import sys
input_str = sys.stdin.read()
print input_str.split()

回答 11

令我惊讶的是,到目前为止,还没有人提到此黑客:

python -c "import sys; set(map(sys.stdout.write,sys.stdin))"

在python2中,您可以删除set()呼叫,但是它将以任何一种方式发出提示

I am pretty amazed no one had mentioned this hack so far:

python -c "import sys; set(map(sys.stdout.write,sys.stdin))"

in python2 you can drop the set() call, but it would word either way


回答 12

尝试这个:

import sys

print sys.stdin.read().upper()

并使用以下命令进行检查:

$ echo "Hello World" | python myFile.py

Try this:

import sys

print sys.stdin.read().upper()

and check it with:

$ echo "Hello World" | python myFile.py

回答 13

您可以从stdin读取内容,然后将输入存储到“数据”中,如下所示:

data = ""
for line in sys.stdin:
    data += line

You can read from stdin and then store inputs into “data” as follows:

data = ""
for line in sys.stdin:
    data += line

回答 14

Windows读取sys.stdin,但是要读取Windows上的二进制数据,您需要格外小心,因为sys.stdin在文本模式下打开了二进制数据\r\n用替换它们会损坏\n

解决方案是,如果检测到Windows + Python 2,则将模式设置为二进制,并在Python 3上使用sys.stdin.buffer

import sys

PY3K = sys.version_info >= (3, 0)

if PY3K:
    source = sys.stdin.buffer
else:
    # Python 2 on Windows opens sys.stdin in text mode, and
    # binary data that read from it becomes corrupted on \r\n
    if sys.platform == "win32":
        # set sys.stdin to binary mode
        import os, msvcrt
        msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
    source = sys.stdin

b = source.read()

Read from sys.stdin, but to read binary data on Windows, you need to be extra careful, because sys.stdin there is opened in text mode and it will corrupt \r\n replacing them with \n.

The solution is to set mode to binary if Windows + Python 2 is detected, and on Python 3 use sys.stdin.buffer.

import sys

PY3K = sys.version_info >= (3, 0)

if PY3K:
    source = sys.stdin.buffer
else:
    # Python 2 on Windows opens sys.stdin in text mode, and
    # binary data that read from it becomes corrupted on \r\n
    if sys.platform == "win32":
        # set sys.stdin to binary mode
        import os, msvcrt
        msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
    source = sys.stdin

b = source.read()

回答 15

我使用以下方法,它从stdin返回一个字符串(我将其用于json解析)。它适用于Windows上的管道和提示(尚未在Linux上进行测试)。提示时,两个换行符指示输入结束。

def get_from_stdin():

  lb = 0
  stdin = ''

  for line in sys.stdin:
    if line == "\n":
        lb += 1
        if lb == 2:
            break
    else:
        lb = 0
        stdin += line

  return stdin

I use the following method, it returns a string from stdin (I use it for json parsing). It works with pipe and prompt on Windows (not tested on Linux yet). When prompting, two line breaks indicate end of input.

def get_from_stdin():

  lb = 0
  stdin = ''

  for line in sys.stdin:
    if line == "\n":
        lb += 1
        if lb == 2:
            break
    else:
        lb = 0
        stdin += line

  return stdin

回答 16

我的解决方案有问题

import sys

for line in sys.stdin:
    print(line)

如果您不向stdin传递任何数据,它将永远阻塞。这就是为什么我喜欢这个答案:为什么先检查stdin上是否有一些数据,然后再读取它。这就是我最终要做的事情:

import sys
import select

# select(files to read from, files to write to, magic, timeout)
# timeout=0.0 is essential b/c we want to know the asnwer right away
if select.select([sys.stdin], [], [], 0.0)[0]:
    help_file_fragment = sys.stdin.read()
else:
    print("No data passed to stdin", file=sys.stderr)
    sys.exit(2)

The problem I have with solution

import sys

for line in sys.stdin:
    print(line)

is that if you don’t pass any data to stdin, it will block forever. That’s why I love this answer: check if there is some data on stdin first, and then read it. This is what I ended up doing:

import sys
import select

# select(files to read from, files to write to, magic, timeout)
# timeout=0.0 is essential b/c we want to know the asnwer right away
if select.select([sys.stdin], [], [], 0.0)[0]:
    help_file_fragment = sys.stdin.read()
else:
    print("No data passed to stdin", file=sys.stderr)
    sys.exit(2)

回答 17

使它工作以读取通过管道连接到它的套接字时,我遇到了一些问题。当套接字关闭时,它开始在活动循环中返回空字符串。因此,这就是我的解决方案(我仅在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:12345

I had some issues when getting this to work for reading over sockets piped to it. When the socket got closed it started returning empty string in an active loop. So this is my solution to it (which I only tested in linux, but hope it works in all other systems)

import sys, os
sep=os.linesep

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

So if you start listening on a socket it will work properly (e.g. in bash):

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

And you can call it with telnet or just point a browser to localhost:12345


回答 18

关于此:

for line in sys.stdin:

我只是在python 2.7上尝试了一个很大的文件(遵循别人的建议),但出于上述原因(长时间未发生任何事情),我不建议这样做。

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

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

Regarding this:

for line in sys.stdin:

I just tried it on python 2.7 (following someone else’s suggestion) for a very large file, and I don’t recommend it, precisely for the reasons mentioned above (nothing happens for a long time).

I ended up with a slightly more pythonic solution (and it works on bigger files):

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

Then I can run the script locally as:

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

回答 19

对于Python 3,应为:

# Filename e.g. cat.py
import sys

for line in sys.stdin:
    print(line, end="")

这基本上是cat(1)的一种简单形式,因为它不会在每行之后添加换行符。您可以使用它(在将文件标记为可执行文件后,使用chmod +x cat.py诸如:

echo Hello | ./cat.py

For Python 3 that would be:

# Filename e.g. cat.py
import sys

for line in sys.stdin:
    print(line, end="")

This is basically a simple form of cat(1), since it doesn’t add a newline after each line. You can use this (after You marked the file executable using chmod +x cat.py such as:

echo Hello | ./cat.py

回答 20

os.read(0, x) 从0表示标准输入读取xbytes。这是一个无缓冲的读取,比sys.stdin.read()的级别低。

There is os.read(0, x) which reads xbytes from 0 which represents stdin. This is an unbuffered read, more low level than sys.stdin.read()


回答 21

使用-c命令时,以一种棘手的方式,您无需阅读stdin(在某些情况下更为灵活),就可以通过将sell命令放在以引号开头的括号内的引号中来将Shell脚本命令传递给python命令$

例如

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

这将计算goldendict的历史记录文件中的行数。

When using -c command, as a tricky way, instead of reading the stdin (and more flexible in some cases) you can pass a shell script command as well to your python command by putting the sell command in quotes within a parenthesis started by $ sign.

e.g.

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

This will count the number of lines from goldendict’s history file.