whe*_*den 20 python stdin command-line-interface command-line-tool pdb
我正在尝试调试我编写的Python CLI,它可以从stdin获取其参数.一个简单的测试用例将具有输出
echo "test" | python mytool.py
Run Code Online (Sandbox Code Playgroud)
相当于.的输出
python mytool.py test
Run Code Online (Sandbox Code Playgroud)
我想用这个工具调试一些问题,所以我试着运行它:
echo "test" | pdb mytool.py
Run Code Online (Sandbox Code Playgroud)
但我得到这个输出,然后pdb退出:
> /path/to/mytool.py(5)<module>()
-> '''
(Pdb) *** NameError: name 'test' is not defined
(Pdb)
Run Code Online (Sandbox Code Playgroud)
当我添加-m python到shebang时,如果我pdb.set_trace()在脚本中运行,则会发生同样的事情.
这里发生了什么?
dmo*_*eno 13
另一种选择是创建自己的Pdb对象,并在那里设置stdin和stdout.我的概念证明涉及2个终端,但肯定有些工作可以合并某种非常不安全的网络服务器.
创建两个fifos:
mkfifo fifo_stdin
mkfifo fifo_stdout
在一个终端中,在后台打开stdout,并写入stdin:
cat fifo_stdout &
cat > fifo_stdin
import pdb
mypdb=pdb.Pdb(stdin=open('fifo_stdin','r'), stdout=open('fifo_stdout','w'))
...
mypdb.set_trace()
...
您应该能够在第一个控制台上使用pdb.
唯一的缺点是必须使用你的自定义pdb,但在init(PYTHONSTARTUP或类似的)一些猴子修补可以帮助:
import pdb
mypdb=pdb.Pdb(stdin=open('fifo_stdin','r'), stdout=open('fifo_stdout','w'))
pdb.set_trace=mydbp.set_trace
你的控制 TTY 仍然是一个终端,对吗?使用这个代替pdb.set_trace.
def tty_pdb():
from contextlib import (_RedirectStream,
redirect_stdout, redirect_stderr)
class redirect_stdin(_RedirectStream):
_stream = 'stdin'
with open('/dev/tty', 'r') as new_stdin, \
open('/dev/tty', 'w') as new_stdout, \
open('/dev/tty', 'w') as new_stderr, \
redirect_stdin(new_stdin), \
redirect_stdout(new_stdout), redirect_stderr(new_stderr):
__import__('pdb').set_trace()
Run Code Online (Sandbox Code Playgroud)
在这种情况下还没有自动完成 readline 。向上箭头或任何其他阅读行细节都不起作用。
您可以使用其他文件描述符.使用bash,您可以创建一个新的文件描述符:
exec 3<> test.txt
Run Code Online (Sandbox Code Playgroud)
然后你的python文件有类似的东西:
#!/usr/bin/python
# Use fd 3 as another stdin file.
import os
stdin=os.fdopen(3)
while True:
s=stdin.readline()
import pdb; pdb.set_trace()
print len(s)
Run Code Online (Sandbox Code Playgroud)
只运行您的脚本将使用该test.txt作为输入,您可以在stdin上使用stdin.如果需要,它也可以用于管道.
小智 2
当您使用 pdb(或任何其他 python 调试器)时,它会获取stdin调试命令,这就是为什么您会得到 NameError: name 'test' is not defined.
例如,此命令将在运行时退出调试器,并且一次运行不会出现此错误(也不会出现交互式调试):
(回声继续;回声“测试”)| python -m pdb mytool.py