Search code examples
pythonlinuxshellpython-os

Running Python interpreter inside Python interpreter: Explain behavior


While fooling around with the OS module in the python interpreter (run inside the shell on a Linux system), I noticed it is possible to do the following:

>>> os.system("python") #execute run python command in enclosing shell

Producing the following output, indicating a new python REPL session:

Python 2.7.9 (default, Apr  2 2015, 15:34:55) 
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> #*blinking cursor*

From here, its possible to once again make a system call to start a new session of Python, from which I can make the system call again, etc. These Python environments seem independent from each other in that variables aren't shared amongst sessions and that the system calls are treated equivalently.

These sessions seem to run inside each other, at least to some extent, rather than in parallel, as evidenced by the outcome of the quit() function:

>>> os.system("python")
Python 2.7.9 (default, Apr  2 2015, 15:34:55) 
[GCC 4.9.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> quit()
0
>>> quit()
0
>>> quit()
0
>>> quit()
shaked@shaked-ThinkPad-X220:~/Desktop$ python

Yet, a quick examination (>>> os.system("ps -e")) of the ongoing processes from the shell reveals a new sh for each python interpreter running:

11802 ?        00:00:00 kworker/u16:0
11803 pts/3    00:00:00 sh
11804 pts/3    00:00:00 python
11806 pts/3    00:00:00 sh
11807 pts/3    00:00:00 python
11810 pts/3    00:00:00 sh
11811 pts/3    00:00:00 python
11813 pts/3    00:00:00 sh
11814 pts/3    00:00:00 ps

Can anyone explain this (seemingly) strange behaviour in terms of underlying system processes? That is, are these sessions running in parallel or from within each other?

Apologies if this question has come up before, but I wasn't sure how others might have presented it.


Solution

  • As per the documentation of os.system():

    Execute the command (a string) in a subshell.

    os.system() forks, executes a subshell passing the argument to this subshell and waits for the subshell to exit.

    The subshell executes the command and waits for it to terminate, hence the process tree is:

    - python
    \-- sh
      \-- python
        \-- sh
          \-- python