Introductory NOTE about the CURRENT STATUS of this question:
In spite of given helpful answers and many helpful comments this question still needs an answer explaining the actual technical reason for the observed behavior instead of providing only high-level explanations and guesses not backed up with detailed knowledge about what is going on under the hood and which scripting language design decisions or system properties result in allowing the child process to finish its job after the script exit.
In other words a good answer should at least give some information related to following detail:
- is the observed behavior a general rule of behavior or an exception due to special properties of sudo or of Popen? Or in other words: is the reason for the observed behavior caused by the design of Python scripting language or is it caused by the design of the operating system (with no way to shut down a child process preventing it from execution and finishing of still pending tasks at the time of parent shutdown)
See also two other questions which tackle another aspects of this one to get more insight about the context of this question:
How to reliably check from Python script code if just created directory exist?
Why does a later Python code line win the race of becoming executed before similar preceding line?
The code below creates a directory in the root directory of the file system. In order to be able to do it, it needs root rights, so the appropriate code line uses sudo
and provides the root password.
Now it turns out that the execution of the line creating the directory waits until the script is finished what causes the code checking if the directory created by the previous lines of code exist report that the directory was not created.
from subprocess import Popen, PIPE
from os.path import isdir
from time import sleep
sudoShCmd = Popen(["sudo", "-S", "mkdir", "/AnewDir"], stdin=PIPE)
sudoShCmd.stdin.write(b'YOUR ROOT PASSWORD HERE')
sleep(5); print()
print(f'{isdir("/AnewDir")=}')
And because I know how I can modify the provided code to preserve the order of executing its lines I am only interested in UNDERSTANDING how it comes that in the case of the code above the last line is executed before the preceding line which seem to be executed at the very end or maybe even after the script shutdown/exit.
So my question is: Why does the Python code creating a directory get executed AFTER the code at the end of the script?
To make even more clear what my question is about here some further clarifying statements:
I am not interested in knowing how to get rid of the observed behavior. I know how to write code that does work as expected. What I am after is to UNDERSTAND what actually happens in case of the code above, so that the lines of code are executed in reversed order.
See my other question on the same subject which current outcome is to ask this one in order to avoid asking multiple question in one question: How to reliably check from Python script code if just created directory exist?.
Here also some thoughts about the explanations given in a comment:
When your script ends, Python begins its cleanup. The subprocess running sudo is still hanging out waiting for input.
Flushing the content of stdin and closing the stdin pipe does not help here. So there must be another reason why sudo does not proceed after getting its password input.
When python starts closing its objects, the stdin closes, the subprocess finally gets control and starts running in parallel. Your script didn't notice that its own subprocess was hanging around waiting for data because the script isn't waiting for the process to finish.
Also with a closed stdin the order of execution will remain switched, so a not closed stdin does not explain the observed behavior.