Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
262 views
in Technique[技术] by (71.8m points)

python - Use pdb.set_trace() in a script that reads stdin via a pipe

I have a python script that reads stdin via a pipe, and I cannot seem to use it with 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()

Suppose tempfile.csv is some file with two lines,

$ cat tempfile.csv 
line1
line2

then I can run my script with: $ cat tempfile.csv | ./my_script.py, and everything is fine:

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

Printing a line:  line2

On the other hand, if I put pdb.set_trace() anywhere then I get an error. For example, putting pdb.set_trace() below def main(), then I get

$ 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

Note that my question is probably related to this question (i.e. pdb by default reads from stdin), but I need more help.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here's an example of what worked for me:

import sys
import pdb

lines = sys.stdin.readlines()
sys.stdin = open("/dev/tty")
pdb.set_trace()

Edit: since 3.7 you no longer need to import pdb for set_trace, it is available as breakpoint, so the above only requires a sys import.

import sys

lines = sys.stdin.readlines()
sys.stdin = open("/dev/tty")
breakpoint()

You may wish to replace sys.stdin.readlines() above with the iterable fileinput.input() (which defaults to sys.stdin if the list of files in sys.argv[1:] is empty) like so:

import fileinput
import sys

lines = fileinput.input()
sys.stdin = open("/dev/tty")
breakpoint()

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...