在通过管道读取stdin的脚本中使用pdb.set_trace()

46 投票
6 回答
11006 浏览
提问于 2025-04-17 12:31

我有一个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()

撰写回答