I want to log the parent command which ultimately executed my Python script. I want to captured it within the Python subprocess so I may include it in existing logs.
I have a shell script run.sh
containing:
#!/bin/bash
python runme.py "$@"
And runme.py
contains:
import sys
import subprocess
print("Doing stuff...")
# What command called me?
psoutput = subprocess.check_output(['ps', '--no-headers','-o','cmd'], text=True)
cmds = psoutput.strip().split('\n')
print(cmds[0])
I execute this from my company's shell (on RHEL) like this, and it outputs...
$ ./run.sh arg1 arg2 arg3
Doing stuff...
run.sh arg1 arg2 arg3
Looks good! But if another process is running first, it shows up first in ps
and this doesn't work:
$ sleep 10s &
$ ./run.sh arg1 arg2 arg3
Doing stuff...
sleep 10s
I'm really trying to select my parent process from ps
. This solution uses -C <process-name>
but I don't know what my process name is. Following this solution I've tried this with several similar ideas for process name:
subprocess.check_output(['ps', '-o', 'ppid=', '-C', 'python runme.py'], text=True)
But that outputs a lot of numbers that look like PID's, but none seem related to my bash call.
How can I reliably get my parent process from within Python?
CodePudding user response:
One (okay) solution I realized while writing my question:
run.sh
contains
command_run=$(echo "$BASH_SOURCE $@")
runme.py --command-run "$command_run" "$@"
runme.py
contains
import argparse
parser = argparse.ArgumentParser()
parser.add_argument(
'-c', '--command-run', required=False,
default=None, dest='command_run',
help='Command text passed from bash'
)
args = parser.parse_args()
print("Doing stuff...")
print(args.command_run)
Additional arguments can be passed after adding more parsing. As above, the following works now:
$ sleep 5s &
$ ./run.sh
Doing stuff...
run.sh
I'll mark this answer as correct unless someone has a nicer solution than passing $BASH_SOURCE this way.
CodePudding user response:
Pure python solution. It works under any shell. The parent cmd line result is a list with the command and the arguments.
import psutil
import os
ppid = psutil.Process(os.getppid())
print(ppid.cmdline())