Respostas:
A resposta de @ milne funciona, mas subprocess.call()
fornece pouco feedback.
Eu prefiro usar subprocess.check_output()
para que você possa analisar o que foi impresso no stdout:
import subprocess
res = subprocess.check_output(["sudo", "apt", "update"])
for line in res.splitlines():
# process the output line by line
check_output
gera um erro na saída zero do comando chamado
Observe que isso não invoca bash
ou outro shell, se você não especificar o shell
argumento da palavra - chave para a função (o mesmo vale para subprocess.call()
, e você não deve, se não for necessário, pois impõe um risco à segurança), invoca diretamente o comando.
Se você se deparar com muitas invocações de comando (diferentes) do Python, talvez queira ver plumbum . Com isso você pode fazer o (IMO) mais legível:
from plumbum.cmd import sudo, apt, echo, cut
res = sudo[apt["update"]]()
chain = echo["hello"] | cut["-c", "2-"]
chain()
os.popen
ou os.system
), ex res = os.popen('sudo apt update').read()
:? @Anthon
subprocess
embora os.system
e os.popen
já existisse. Tais PEPs não são triviais para serem aceitos. Várias pessoas pensaram muito mais nisso do que você ou eu. E subprocess
melhorou desde 2003, os outros ainda estão lá para compatibilidade com versões anteriores. Você reded a os.system
página do manual: O módulo de subprocesso fornece instalações mais poderosas para gerar novos processos e recuperar seus resultados; usar esse módulo é preferível a usar esta função.
sudo
só vai tornar isso mais grave. Talvez o uso de python-apt seja uma solução melhor (eu mesmo não examinei isso).
O módulo do subprocesso foi projetado para fazer isso:
import subprocess
subprocess.call(["sudo", "apt", "update"])
Se você deseja que o script seja encerrado se o comando falhar, considere usar em check_call()
vez de analisar o código de retorno:
subprocess.check_call(["sudo", "apt", "update"])
Traceback (most recent call last): File "/home/Dremor/test.py", line 3, in <module> subprocess.call('sudo', 'yum', 'update') File "/usr/lib64/python3.4/subprocess.py", line 537, in call with Popen(*popenargs, **kwargs) as p: File "/usr/lib64/python3.4/subprocess.py", line 767, in __init__ raise TypeError("bufsize must be an integer") TypeError: bufsize must be an integer
(estou usando o yum como estou usando o Fedora como sistema operacional principal) #
subprocess.call()
está bloqueando enquanto subprocess.Popen()
é sem bloqueio ..
Também você pode usar 'os.popen'.
Exemplo:
import os
command = os.popen('ls -al')
print(command.read())
print(command.close())
Resultado:
total 16
drwxr-xr-x 2 root root 4096 ago 13 21:53 .
drwxr-xr-x 4 root root 4096 ago 13 01:50 ..
-rw-r--r-- 1 root root 1278 ago 13 21:12 bot.py
-rw-r--r-- 1 root root 77 ago 13 21:53 test.py
None
usar módulo de subprocesso
import subprocess
command = 'sudo apt update'
subprocess.check_call(command.split())