David Shaked
David Shaked

Reputation: 3381

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.

Upvotes: 1

Views: 94

Answers (3)

dhke
dhke

Reputation: 15388

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

Upvotes: 3

ForceBru
ForceBru

Reputation: 44838

Python's os.system starts a new system process. When you pass "python" to it, it starts a new Python interpreter, that is independent from the one os.system was called from.

Upvotes: 0

kojiro
kojiro

Reputation: 77089

When you use os.system, it performs the command in a subshell, something like /bin/sh -c 'yourcommand'*. Thus, it's completely sensible that you would get the behavior you describe. It's not different from running:

/bin/sh -c 'python'

in any shell.

*with mild differences on Windows, please read the documentation.

Upvotes: 4

Related Questions