Мне нравится shell=False
чтобы избежать различных проблем с shell=True
. Иногда я вижу такой код, и он возвращает True, но, похоже, ничего не печатал, и я не знаю, что произошло.
subprocess.run(['echo', 'hi'], shell=True, check=True).returncode == 0
Напротив,
subprocess.run(['echo', 'hi'], shell=False, check=True).returncode == 0
на самом деле печатает на stdout.
Что происходит, когда я передаю список в качестве аргументов и shell = True?
Из документации:
В POSIX с оболочкой = True оболочка по умолчанию имеет значение /bin/sh. Если args является строкой, строка указывает команду для выполнения через оболочку. Это означает, что строка должна быть отформатирована точно так же, как и при вводе в командной строке. Это включает в себя, например, цитирование или обратную косую черту с экранированием имен файлов с пробелами в них. Если args является последовательностью, первый элемент указывает командную строку, и любые дополнительные элементы будут рассматриваться как дополнительные аргументы самой оболочки.
Таким образом, ваша команда эквивалентна sh -c "echo" "hi"
, которая просто выполняет echo
без аргументов.
Более полезным примером является использование этого механизма для безопасного переноса произвольных данных в фрагмент оболочки:
file1='my file.txt'
file2='Author&Title - [FOO] **proper**.mp3'
subprocess.run(
['for f; do printf "Input: %s\n" "$f"; done', '_',
file1, file2],
shell=True, check=True)
Это отображает переменные из оболочки без необходимости беспокоиться об экранировании метасимволов оболочки. (дополнительный '_'
становится $0
).