将输入传递给脚本并随后获取用户输入
假设我想把一些输入通过管道传给一个Python程序,然后再在命令行上让用户输入一些东西。
echo http://example.com/image.jpg | python solve_captcha.py
而文件 solve_captcha.py
的内容是:
import sys
image_url = sys.stdin.readline()
# Download and open the captcha...
captcha = raw_input("Solve this captcha:")
# do some processing...
这样做会导致一个错误,叫做 EOFError: EOF when reading a line
。
我还试着加了一行 sys.stdin.close()
,结果出现了另一个错误,叫 ValueError: I/O operation on closed file
。
请问,能不能先把信息通过 stdin
传入,然后再让用户输入呢?
注意: 这是一个简化的例子 - 请不要回答说“你为什么想这么做”,这真的让我很沮丧。我只是想知道,能不能把信息传给 stdin
,然后再让用户输入。
5 个回答
你可以先关闭标准输入,然后再重新打开它来读取用户输入。
import sys, os
data = sys.stdin.readline()
print 'Input:', data
sys.stdin.close()
sys.stdin = os.fdopen(1)
captcha = raw_input("Solve this captcha:")
print 'Captcha', captcha
bash有一个叫做进程替换的功能,它可以创建一个FIFO(先进先出队列),你可以把它当作一个文件来使用。所以你可以不必这样写:
echo http://example.com/image.jpg | python solve_captcha.py
而是可以这样写:
python solve_capcha.py <(echo http://example.com/image.jpg)
你可以把solve_capcha.py的第一个参数当作一个文件来打开,我想sys.stdin仍然可以用来从键盘读取输入。
补充一下:如果你不使用bash,你可以用mkfifo
在任何POSIX系统上实现同样的功能:
mkfifo my_pipe
echo "http://example.com/image.jpg" > my_pipe
python solve_captcha.py my_pipe
这个FIFO会阻塞(等待而不关闭)输出。
这个问题没有一个通用的解决办法。最好的资源似乎是这个邮件列表的讨论。
简单来说,把数据通过管道传给一个程序,就是把这个程序的 stdin
(标准输入)连接到那个管道,而不是连接到终端。
邮件列表的讨论中有几个相对简单的解决方案,适用于 *nix 系统:
打开 /dev/tty 来替代 sys.stdin:
sys.stdin = open('/dev/tty')
a = raw_input('Prompt: ')
在运行你的脚本时,把标准输入重定向到另一个文件句柄,并从那个文件读取:
sys.stdin = os.fdopen(3)
a = raw_input('Prompt: ')
$ (echo -n test | ./x.py) 3<&0
还有使用 curses 的建议。请注意,这个邮件列表的讨论是很久以前的内容,所以你可能需要根据你选择的解决方案进行一些修改。