Does pdb have a "comm" command like gdb? - python

In GDB, users can define some actions that run automatically when a breakpoint is hit. For example,
b foo.cpp:100
comm 1
p x
end
Does pdb have the similar function?

Yes. In https://docs.python.org/2/library/pdb.html, you can find:
commands [bpnumber]
Specify a list of commands for breakpoint number bpnumber. The commands themselves appear on the following lines. Type a line containing just ‘end’ to terminate the commands

Related

Can python run a "persistent shell"

I'm trying to run a sequence of shell commands in the same environment:
same exported variables, persistent history, etc.
And I want to work with each commands output before running the next command.
After looking over python subprocess.run and Pexpect.spawn neither seem to provide both features.
subprocess.run allows me to run one command and then examine the output, but not to keep the environment open for another command.
Pexpect.spawn("bash") allows me to run multiple commands in the same environment, but i can't get the output until EOF; when bash itself exits.
Ideally i would like an interface that can do both:
shell = bash.new()
shell.run("export VAR=2")
shell.run("whoami")
print(shell.exit_code, shell.stdout())
# 0, User
shell.run("echo $VAR")
print(shell.stdout())
# 2
shell.run("!!")
print(shell.stdout())
# 2
shell.run("cat file -")
shell.stdin("Foo Bar")
print(shell.stdout())
# Foo Bar
print(shell.stderr())
# cat: file: No such file or directory
shell.close()
Sounds like a case for Popen. You can specify bufsize to disable buffering, if it gets in the way.
Example from the linked page:
with Popen(["ifconfig"], stdout=PIPE) as proc:
log.write(proc.stdout.read())
There's also proc.stdin for sending more commands, and proc.stderr.

Using python to interact with a command line program

(new to python so bear with me...)
I have a simple java jar file that when executed, it asks the user for some basic data in a command prompt and then executes an operation based on this data.
I want to write a simple python script that will automate the execution of this jar file without the need for the user to supply the data, meaning writing the data inside the script and basically interact with the java application when asked by the command prompt.
Think of a java file that is executed by running Java -jar someJavaApp.jar
Then a command prompt is asking for you name. you enter it and press enter, then it asks for your last name, you enter it and press enter and then the java app executes an arbitrary operation based on the input.
I want to have a python script that I can execute the java app several times, each time with different inputs taken from a file or something similar.
Any help will be appreciated.
Thanks.
You can use Popen from the subprocess module.
Here's a simple example, first script to prompt for input and return some output, test_input.py:
first = input("Enter your first name: ")
second = input("Enter your second name: ")
print(first+second)
Then the script to call the first script:
import subprocess
values = (("A", "B"), ("C", "D"), ("E", "F"))
command = "python test_input.py"
for first, second in values:
# lazy use of universal_newlines to prevent the need for encoding/decoding
p = subprocess.Popen(command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True, universal_newlines=True)
output, err = p.communicate(input="{}\n{}\n".format(first, second))
# stderr is not connected to a pipe, so err is None
print(first, second, "->", end="")
# we just want the result of the command
print(output[output.rfind(" "):-1]) # -1 to strip the final newline
This will print:
A B -> AB
C D -> CD
E F -> EF
If you have problems getting it working with your java program, a quick solution may be to specify shell=True in the Popen function call. But you'll want to be aware of the security considerations.

How to use the 'debug' command inside pdb (python)

I would like to know how to use the debug command in pdb?
(Pdb) help
Documented commands (type help <topic>):
========================================
EOF c d h list q rv undisplay
a cl debug help ll quit s unt
alias clear disable ignore longlist r source until
args commands display interact n restart step up
b condition down j next return tbreak w
break cont enable jump p retval u whatis
bt continue exit l pp run unalias where
Miscellaneous help topics:
==========================
pdb exec
(Pdb) help debug
debug code
Enter a recursive debugger that steps through the code
argument (which is an arbitrary expression or statement to be
executed in the current environment).
(Pdb) debug print('hello')
ENTERING RECURSIVE DEBUGGER
> <string>(1)<module>()->None
((Pdb)) n
hello
--Return--
> <string>(1)<module>()->None
((Pdb)) n
LEAVING RECURSIVE DEBUGGER
(Pdb)
The question confused me years. I always forgot to search the final answer. But today I get it, and share what I find here.
How can I debug manually typed expression and statements in pdb?
When you are in the recursive debug mode first time, type s , you will kwon what to do the next.
Let, you have a bunch of code. You put pdb, say line 3.
In this case, when you run the program, line 1 and line 2 is executed automatically and you can see the result by putting the variable name and from line 4 is not executed.
If you wanna see after line 3 result you have to write code which results you want to see or you can go next line using n, and c for continuing that means exit from debugging mode.

busybox ash via paramiko not emitting prompt on stdout

I created Python GUI that takes a list of commands as input and executes the list through a Telnet or SSH session. While opening a SSH session (using Paramiko in Python) I run commands on various devices using this code in a for loop:
stdin.write(command+"\n")
then = time.time()
timeout=10.0
while not stdout.channel.exit_status_ready():
if timeout is not None:
timeTest =time.time() - then
if timeout <= timeTest:
break
# Only print data if there is data to read in the channel
if stdout.channel.recv_ready():
# Write data from stdout
temp=str(stdout.channel.recv(1024))
print temp
if (temp.endswith(delim)) or (temp.endswith("# ")) :
print "successful exit"
break
The code is designed to be used on modems that have BusyBox installed. Thus it's common for a user to enter a command to open busybox and run a sequence of commands in the BusyBox shell. As you can see in this line of code "if (temp.endswith(delim)) or (temp.endswith("# "))" the while loop is suppose to break when the command prompt of busybox is detected which is a "# " (this means the command has finished outputting).
The problem I'm having is that BusyBox isn't printing the command prompt to stdout or in the debug line "print temp". Why is this? The command outputs (an example is ls -l) are successfully printed to stdout but not the command prompt or busybox intro message: when a user enters busybox on these modems a introduction message is printed "BusyBox v1.17.2 (2014-10-02 10:50:35 PDT) built-in shell (ash)
Enter 'help' for a list of built-in commands." which is also not printed to STDOUT. This is forcing the code to utilize the timeout for each command executed in busybox which is undesirable, i.e. it's slow and there could be command outputs that take longer than the desired timeout so it's best to look for the command prompt.
Is this issue due to the implementation of ash in BusyBox? Is there a way to receive the command prompt text?
First: If you're trying to recognize shell prompts when invoking a shell programmatically, you're Doing It Wrong.
If you use exec_command() on a new channel (over the same transport) for each command you want to run, you'll get a separate stdout, stderr, etc. for each command; have the exit status for that command individually reported, and never need to guess whether a piece of output is from the command or from the outer shell.
Second: If you really want to do it that way (and, again, you shouldn't!), you should be using invoke_shell() after a get_pty() call, not exec_command('sh').
See the entry on PS1 (the variable specifying the prompt to emit) in IEEE standard 1003.1 (emphasis added):
PS1
Each time an interactive shell is ready to read a command, the value of this variable shall be subjected to parameter expansion and written to standard error. The default value shall be "$ ". For users who have specific additional implementation-defined privileges, the default may be another, implementation-defined value. The shell shall replace each instance of the character '!' in PS1 with the history file number of the next command to be typed. Escaping the '!' with another '!' (that is, "!!" ) shall place the literal character '!' in the prompt. This volume of POSIX.1-2008 specifies the effects of the variable only for systems supporting the User Portability Utilities option.
Thus, any POSIX-compliant shell -- not just busybox ash, but ksh, dash, bash, and all the rest -- must write its prompt to stderr, not stdout.
Your simple fix, then, is to either read from stderr, or to use redirection to combine the streams (running exec 2>&1, for instance).

setting breakpoint in pdb python

I want to set breakpoints using pdb and then run the loop in the program until that breakpoint. and then after checking the values keep continuing (only stopping at that point) until the loop ends. how do i do it?
You can run your program into pdb from the command line by running
python -m pdb your_script.py
This will stop execution at line 1, now set breakpoint with b linenumber e.g. b 25. Now type run it will run the program until that break point.
If you can modify the code, one way is to add this line where you want to break:
import pdb; pdb.set_trace()

Categories

Resources