0

I am trying to create a bash script that runs a python3 script with pdb trace set. As such, in my bash script I have the following lines:

python3 path/to/my_script.py
n

What I want to happen is for bash to run the python script, which will then open the python debugger. Then, the bash script will send the key 'n' to the pdb shell so that pdb executes the first line in the python script.

The script does not work as expected and bash waits until the python script has completed (or exited) to execute 'n' in the command line which just opens node.

I thought this might be a problem unique to pdb shells so I tried executing the following in bash:

python3
print("Hello")

However, again, we observe that the script creates a python3 shell and then waits for the shell to exit before executing print("Hello") in the terminal. I understand that I could use python3 -c for this case, but that does not address the case of passing commands to the pdb shell in the context of the running script.

Is there any way to send the 'n' command to the pdb shell that the python script generates?

Ryan
  • 1

2 Answers2

0

Your code will try to run two commands. First, it will run your python script, then it will try to run a command called n. Assuming your script needs you read from stdin you can do one of the following:

Use a herestring:

python3 path/to/my_script.py <<< "n"

Use a pipeline:

One example echo "n" | python3 path/to/my_script.py Echo is not the only command you can use. You can also use printf or even yes for this use case.

  • Thank you! As a follow up, is there any way to send multiple herestrings at later times. Imagine that I wanted to dynamically interact with the python debugger such that I read the output from an input (e.g. "n") and then depending on what the stdout looks like (say I write stdout to another file), I can send another herestring to the same pdb shell? – Ryan Jan 10 '23 at 02:45
  • Unfortunately, this does not work. This results in: File "/Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions/3.8/lib/python3.8/bdb.py", line 113, in dispatch_line if self.quitting: raise BdbQuit bdb.BdbQuit – Ryan Jan 10 '23 at 02:54
  • Looks like it's just closing the pipe on you. The actual implementation of your python program will affect this, there's an example on how to fix that issue here https://stackoverflow.com/questions/9178751/use-pdb-set-trace-in-a-script-that-reads-stdin-via-a-pipe. – James Schultz Jan 10 '23 at 03:49
  • 1
    ".. such that I read the output from an input and then depending on what the stdout looks like .." -- sounds like you can use [tag:pexpect]. – sexpect - Expect for Shells Jan 10 '23 at 09:33
0

You can use a coprocess to send and receive from pdb.

#! /bin/bash

send() {
    echo "$1" >&${PDB[1]}
}

recv() {
    IFS= read -r -u ${PDB[0]} line
    echo $line
}

coproc PDB { /path/to/my_script.py; }
send 'n'
recv
#...
send 'n'
recv
Diego Torres Milano
  • 65,697
  • 9
  • 111
  • 134