【问题标题】:Detect STDIN file and prevent user input in Python检测 STDIN 文件并阻止用户在 Python 中输入
【发布时间】:2019-01-31 01:10:49
【问题描述】:

我想编写一个可以在 Windows cmd.exe 提示符下使用 STDIN 语法调用的命令行 Python 程序,如果没有提供输入文件,我想将帮助文本打印到 STDOUT。

STDIN 语法与参数语法不同,是一种直接替代解决方案:

my_program.py < input.txt

这是我目前所拥有的:

import sys

# Define stdout with \n newline character instead of the \r\n default
stdout = open(sys.__stdout__.fileno(), 
              mode=sys.__stdout__.mode, 
              buffering=1, 
              encoding=sys.__stdout__.encoding, 
              errors=sys.__stdout__.errors, 
              newline='\n', 
              closefd=False)

def main(args):
    lines = ''.join([line for line in sys.stdin.readlines()])
    lines = lines.replace( '\r\n', '\n' ).replace( '\t', '    ' )    
    stdout.write(lines)

if __name__=='__main__':
    main(sys.argv)

我不知道如何检测文件是否已提供给 STDIN,如果没有则阻止提示用户输入。 sys.argv 不包含 STDIN。我可以将它包装在一个带有计时器的线程中并等待一些文件访问上限时间并确定没有提供文件可能,但我想看看是否有更好的方法。我在 SO 中搜索了这个问题,但找不到避免计时器的答案。

【问题讨论】:

  • 将输入数据发送到标准输入和输入/输出重定向是 POSIX 系统上的常见做法。一般来说,使用该程序的人负责正确使用它并将数据提供给标准输入或在没有发送任何内容时关闭管道。

标签: python stdin


【解决方案1】:

test.py:

import sys

if sys.__stdin__.isatty():
    print("stdin from console")
else:
    print("stdin not from console")

执行:

> test.py
stdin from console
> test.py <input.txt
stdin not from console

【讨论】:

  • 这很有趣(证明我错了,谢谢,我学到了一些东西)。你知道做出这个决定的确切原因吗?我注意到当我从 IDE 运行它而不用管道输入任何东西时它说“不是从控制台”,而当直接从命令行运行时它说“从控制台” - 尽管我希望它们是相同的?
  • 不,我没有;文档只是说“如果流是交互式的(即连接到终端/tty 设备),则返回 True。”没有什么关于如何做的。
  • 代码在github.com/python/cpython/blob/master/Modules/_io/iobase.c(搜索“_io._IOBase.isatty”)。不过,它需要的 Python 内部知识比我必须了解的要多。
【解决方案2】:

您正在使用的操作员将读取一个文件并在标准输入上为您的进程提供该文件的内容。这意味着您的脚本无法判断它是否正在输入文件的内容,或者是否有一个非常快速的打字员在键盘上输入与文件内容完全相同的一系列击键。

当你的脚本访问数据时,它只是一个字符流,它是一个文件这一事实只有你用来编写重定向的命令行界面才知道。

【讨论】:

  • 不完全正确,正如@codingatty 的回答所显示的那样 - 暂时将其留在这里讨论
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
相关资源
最近更新 更多