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

Ian*_*ore 33 python

我有一个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()
Run Code Online (Sandbox Code Playgroud)

假设tempfile.csv是一个有两行的文件,

$ cat tempfile.csv 
line1
line2
Run Code Online (Sandbox Code Playgroud)

然后我可以运行我的脚本:$ cat tempfile.csv | ./my_script.py,一切都很好:

$ cat tempfile.csv | ./my_script.py 
Printing a line:  line1

Printing a line:  line2
Run Code Online (Sandbox Code Playgroud)

另一方面,如果我把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
Run Code Online (Sandbox Code Playgroud)

请注意,我的问题可能与此问题有关(即pdb默认从stdin读取),但我需要更多帮助.

Car*_*ith 19

这是一个对我有用的例子:

lines = sys.stdin.readlines()
sys.stdin = open('/dev/tty')
pdb.set_trace()
Run Code Online (Sandbox Code Playgroud)

  • Pdb从stdin读取是交互式的; 所以要使用pdb,你必须首先读取所有stdin,然后将stdin设置为电传打字机接口,或者换句话说将它连接回终端和键盘而不是shell管道.那时你可以像普通一样启动pdb(并使用它) (4认同)
  • 我用过:`import sys; sys.stdin = open('/ dev/tty'); import pdb; pdb.set_trace()` (3认同)

tit*_*ito 5

问题是:cat因为您的脚本当前正在调试,所以不会停止发送数据.当你要追踪时,stdin仍然被cat你的键盘填满.你需要选择其中一个.

你可以读取整个stdin,然后,set_trace()将不会被stdin填充:

sys.stdin.read()
pdb.set_trace()
Run Code Online (Sandbox Code Playgroud)

  • 这似乎有所帮助,但并不完全.我把sys.stdin.read()放在几个地方,pdb.set_trace()放在下面,我不再得到NameError.但是,pdb没有打开...它只是退出(与上面相同的消息,没有NameError) (3认同)

C. *_*eed 5

使用ripdb模块 ( pip install ripdb) 为我解决了这个问题。