質問

There are two different python programs running in this VM

one is a background job who monitors a folder and then 'does stuff' (with several workers)

10835 ?        Sl     0:03 python main.py
10844 ?        Sl    34:02 python main.py
10845 ?        S     33:43 python main.py

the second one is started via script

20056 pts/1    S+     0:00 /bin/bash ./exp.sh
20069 pts/1    S+     0:00 /bin/bash ./exp.sh
20087 pts/1    S+     0:10 python /home/path/second.py

i have tried numerous things to find a way to kill only the main program (i want to build a cron watchdog), but non succeded

first one i want to find only the hanging 'python main.py' process (accompanied by [defunct]), but i cant even find just this process alone.

the upper ones are from ps -ax (so they both are running currently) pgrep 'python' returns all PIDs, also from second.py which i dont want: (not usefull, so is pkill therefore)

pgrep 'python'
10835
10844
10845
20087

pgrep 'python main.py' always returns empty, so does pgrep 'main.py;

the only thing which works

ps ax | grep 'python main.py'

but this one also returns its own PID, grepping 'ps' isn't a prefered solution afair. when main.py hangs, it shows "python main.py [defunct]". a

ps ax | grep 'python main.py [defunct]'

is useless as test as it always returns true. pgrep for anything more than 'python' also returns always false. i am a bit clueless.

役に立ちましたか?

解決 2

In your daemon python script you should create PID file:

def writePidFile():
  pid = str(os.getpid())
  f = open('/tmp/my_pid', 'w')
  f.write(pid)
  f.close()

Now killing this process is simple:

kill `cat /tmp/my_pid`

Or you can just use grep and filter its own process:

ps ax | grep 'python main.py [defunct]' | grep -v grep

他のヒント

This works for me. Found it on the pgrep bro pages.

Find the pids of processes with 'test.py' as an argument, like 'python test.py'

pgrep -f test.py

And I use it to check if a python process is running:

searcher="backend/webapi.py"

if pgrep -f "$searcher" > /dev/null
then
    echo "$(date +%y-%m-%d-%H-%M-%S) $searcher is alive. Doing nothing."
else
    echo "No $searcher. Kickstarting..."
    pushd $HOME/there/;
    ./run_backend
    popd;
    echo "Pgrepping $searcher:"
    pgrep "$searcher" # out to loggers
fi

I think I've found a pretty safe way to do find the proper python process PID for a specific file only. The idea is to find all the python processes, then all "test.py" processes and intersect the results to find the correct PID.

I use the subprocess module in a python script (you can interpolate for .sh script):

import subprocess as subp
#Get a list of all processes with a certain name
def get_pid(name):
    return list(map(int,subp.check_output(["pidof", "-c", name]).split()))
#Get a list of all pids for python3 processes
python_pids = get_pid('python3')
#Get a list of all pids for processes with "main.py" argument
main_py_pids = list(map(int,subp.check_output(["pgrep", "-f", "main.py"]).split()))
python_main_py_pid = set(python_pids).intersection(main_py_pids)
print(python_pids)
print(main_py_pids)
print(python_main_py_pid)

Result with 3 running python processes (including the one from this script) and one "sudo nano main.py" process:

Python pids: [3032, 2329, 1698]
main.py pids: [1698, 3031]
Interesection: {1698}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top