在通过管道读取stdin的脚本中使用pdb.set_trace()
我有一个Python脚本,它通过管道读取标准输入,但我发现无法和pdb.set_trace()一起使用。
我的脚本是my_script.py:
#!/usr/bin/env python
import sys
import pdb
def main():
for line in sys.stdin:
print "Printing a line: " +line
if __name__=='__main__':
status = main()
假设tempfile.csv是一个包含两行内容的文件,
$ cat tempfile.csv
line1
line2
那么我可以这样运行我的脚本:
$ cat tempfile.csv | ./my_script.py,这样一切都正常:
$ cat tempfile.csv | ./my_script.py
Printing a line: line1
Printing a line: line2
但是,如果我在任何地方放入pdb.set_trace(),就会出现错误。例如,如果我把pdb.set_trace()放在def main()下面,就会出现
$ cat tempfile.csv | ./my_script.py
> /home/ilangmore/mobiuss/TM/branches/hadooprotype/my_script.py(7)main()
-> for line in sys.stdin:
(Pdb) *** NameError: name 'line1' is not defined
(Pdb) *** NameError: name 'line2' is not defined
(Pdb)
Traceback (most recent call last):
File "./my_script.py", line 11, in <module>
status = main()
File "./my_script.py", line 7, in main
for line in sys.stdin:
File "./my_script.py", line 7, in main
for line in sys.stdin:
File "/usr/lib/python2.7/bdb.py", line 48, in trace_dispatch
return self.dispatch_line(frame)
File "/usr/lib/python2.7/bdb.py", line 67, in dispatch_line
if self.quitting: raise BdbQuit
bdb.BdbQuit
请注意,我的问题可能和这个问题有关(也就是说,pdb默认是从标准输入读取的),但我需要更多的帮助。
6 个回答
5
使用 ripdb 这个模块(你可以通过 pip install ripdb
来安装)解决了我的问题。
5
问题是:cat
命令不会因为你的脚本正在调试而停止发送数据。当你开始追踪时,标准输入(stdin)仍然被 cat
和你的键盘输入占满。你需要选择其中一个。
你可以先读取整个标准输入,然后在调用 set_trace()
时,标准输入就不会再被占用了:
sys.stdin.read()
pdb.set_trace()
27
这是一个对我有用的例子:
import sys
import pdb
lines = sys.stdin.readlines()
sys.stdin = open("/dev/tty")
pdb.set_trace()
补充说明:从3.7版本开始,你不再需要导入 pdb
来使用 set_trace
,现在可以直接用 breakpoint
,所以上面的代码只需要导入 sys
。
import sys
lines = sys.stdin.readlines()
sys.stdin = open("/dev/tty")
breakpoint()
你可能想把上面的 sys.stdin.readlines()
替换成可迭代的 fileinput.input()
(如果 sys.argv[1:]
中的文件列表是空的,它会默认使用 sys.stdin
),可以这样做:
import fileinput
import sys
lines = fileinput.input()
sys.stdin = open("/dev/tty")
breakpoint()