Первый аргумент subprocess.Popen()
сообщает системе, что запускать.
Когда это список, вам нужно , чтобы использовать shell=False
. По совпадению, это работает так, как вы надеетесь в Windows; но на Unix -подобных платформах вы просто передаете ряд аргументов, которые обычно игнорируются. Фактически,
/bin/sh -c 'echo' '$HOME'
, который просто приводит к тому, что второй аргумент не используется ни для чего (где я использую одинарные кавычки, чтобы подчеркнуть, что это просто строки c).
В моем скромное мнение, Python должно выдать ошибку в этом случае. На Windows тоже. Это ошибка, которая должна быть перехвачена и сообщена.
(В противном случае, если указано shell=False
, но переданная вами строка не является именем допустимой команды, вы в конечном итоге получите ошибку в любом случае, и это имеет смысл, если у вас есть даже смутное представление о том, что происходит.)
Если вы действительно знаете, что делаете, вы можете заставить первый аргумент получить доступ к последующим аргументам; например,
/bin/sh -c 'printf "%s\n" "$@"' 'ick' 'foo' 'bar' 'baz'
напечатает foo
, bar
и baz
в отдельных строках. (Аргумент "ноль" - здесь, 'ick'
- используется для заполнения $0
.) Но это всего лишь неясное следствие; не пытайтесь использовать это ни для чего.
Кроме того, вам не следует использовать subprocess.Popen()
, если вы просто хотите, чтобы команда выполнялась. Документация subprocess.run()
говорит вам об этом более подробно. С text=True
вы получаете строку вместо байтов.
result = subprocess.run('echo "$HOME"', shell=True,
text=True, capture_output=True, check=True)
print(result.stdout, result.stderr)
И, конечно, os.environ['HOME']
позволяет вам получить доступ к значению $HOME
из Python. Это также позволяет вам избегать shell=True
, что вы обычно должны, если можете.