Если вы НЕ , используя пользовательский ввод в командах, вы можете использовать это
from os import getcwd
from subprocess import check_output
from shlex import quote
def sh(command):
return check_output(quote(command), shell=True, cwd=getcwd(), universal_newlines=True).strip()
И используйте его как
branch = sh('git rev-parse --abbrev-ref HEAD')
shell=True
породит оболочку, так что вы можете использовать трубу и такие вещи оболочки sh('ps aux | grep python')
. Это очень удобно для запуска жестко запрограммированных команд и обработки их вывода. universal_lines=True
гарантирует, что выходные данные возвращаются в виде строки, а не в двоичном формате.
cwd=getcwd()
убедится, что команда запущена в том же рабочем каталоге, что и интерпретатор. Это удобно для работы команд git, как в приведенном выше примере с именем ветви git.
Некоторые рецепты
- свободной памяти в мегабайтах:
sh('free -m').split('\n')[1].split()[1]
- свободного места в / в процентах
sh('df -m /').split('\n')[1].split()[4][0:-1]
- загрузка процессора
sum(map(float, sh('ps -ef -o pcpu').split('\n')[1:])
Но это небезопасно для ввода пользователем из документов:
Вопросы безопасности¶
В отличие от некоторых других попсовых функций, эта реализация никогда не будет
неявно вызвать системную оболочку. Это означает, что все персонажи,
включая метасимволы оболочки, можно безопасно передать ребенку
процессы. Если оболочка вызывается явно, через shell = True, это
ответственность приложения за обеспечение того, чтобы все пробелы и
метасимволы указаны в кавычках, чтобы избежать внедрения в оболочку
уязвимости.
Когда используется shell = True, функцию shlex.quote () можно использовать для
правильно экранировать пробелы и метасимволы оболочки в строках, которые
будут использоваться для создания команд оболочки.
Даже при использовании shlex.quote()
полезно быть немного параноиком при использовании пользовательских вводов для команд оболочки. Одним из вариантов является использование команды с жестким кодом для получения общего вывода и фильтрации по пользовательскому вводу. В любом случае использование shell=False
обеспечит выполнение только того процесса, который вы хотите выполнить, или вы получите ошибку No such file or directory
.
Также есть некоторое влияние на производительность на shell=True
, по моим тестам оно примерно на 20% медленнее, чем shell=False
(по умолчанию).
In [50]: timeit("check_output('ls -l'.split(), universal_newlines=True)", number=1000, globals=globals())
Out[50]: 2.6801227919995654
In [51]: timeit("check_output('ls -l', universal_newlines=True, shell=True)", number=1000, globals=globals())
Out[51]: 3.243950183999914