Search code examples
pythonlinuxpython-3.4ps

`ps -ef` shows running process twice if started with `subprocess.Popen`


I use the following snippet in a larger Python program to spawn a process in background:

import subprocess

command = "/media/sf_SharedDir/FOOBAR"
subprocess.Popen(command, shell=True)

After that I wanted to check whether the process was running when my Python program returned. Output of ps -ef | grep -v grep | grep FOOBAR:

ap    3396   937  0 16:08 pts/16   00:00:00 /bin/sh -c /media/sf_SharedDir/FOOBAR
ap    3397  3396  0 16:08 pts/16   00:00:00 /bin/sh /media/sf_SharedDir/FOOBAR

I was surprised to see two lines of and they have differend PIDs so are those two processes running? Is there something wrong with my Popen call?

FOOBAR Script:

#!/bin/bash

while : 
do
        echo "still alive"
        sleep 1
done

EDIT: Starting the script in a terminal ps displayes only one process.

Started via ./FOOBAR

ap@VBU:/media/sf_SharedDir$ ps -ef | grep -v grep | grep FOOBAR
ap    4115  3463  0 16:34 pts/5    00:00:00 /bin/bash ./FOOBAR

EDIT: shell=True is causing this issue (if it is one). But how would I fix that if I required shell to be True to run bash commands?


Solution

  • There is nothing wrong, what you see is perfectly normal. There is no "fix".

    Each of your processes has a distinct function. The top-level process is running the python interpreter.

    The second process, /bin/sh -c /media/sf_SharedDir/FOOBAR' is the shell that interprets the cmd line (because you want | or * or $HOME to be interpreted, you specified shell=True).

    The third process, /bin/sh /media/sf_SharedDir/FOOBAR is the FOOBAR cmd. The /bin/sh comes from the #! line inside your FOOBAR program. If it were a C program, you'd just see /media/sf_SharedDir/FOOBAR here. If it were a python program, you'd see /usr/bin/python/media/sf_SharedDir/FOOBAR.

    If you are really bothered by the second process, you could modify your python program like so:

    command = "exec /media/sf_SharedDir/FOOBAR"
    subprocess.Popen(command, shell=True)