Ответ 1
Popen
неблокируется. call
и check_call
блокируются.
Вы можете сделать блок экземпляра Popen
, вызвав его метод wait
или communicate
.
Если вы посмотрите исходный код, вы увидите call
calls Popen(...).wait()
, поэтому он блокирует.
check_call
вызывает call
, поэтому он также блокирует.
Строго говоря, shell=True
ортогонален проблеме блокировки. Однако shell=True
заставляет Python запускать оболочку, а затем запускать команду в оболочке. Если вы используете блокирующий вызов, вызов вернется, когда оболочка закончит. Так как оболочка может порождать подпроцесс для запуска команды, оболочка может завершиться до порожденного подпроцесса. Например,
import subprocess
import time
proc = subprocess.Popen('ls -lRa /', shell=True)
time.sleep(3)
proc.terminate()
proc.wait()
Здесь возникают два процесса: Popen порождает один подпроцесс, запускающий оболочку. В свою очередь оболочка запускает подпроцесс, выполняющийся ls
. proc.terminate()
убивает оболочку, но работает подпроцесс ls
. (Это проявляется в обильном выходе, даже после завершения python script. Будьте готовы убить ls
с помощью pkill ls
.)