executar um comando como super utilizador a partir de um script python
-
05-09-2019 - |
Pergunta
Então, eu estou tentando obter um processo a ser executado como um super usuário a partir de um script python usando subprocesso. No shell ipython algo como
proc = subprocess.Popen('sudo apach2ctl restart',
shell=True, stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
funciona bem, mas assim que eu colocá-lo em um script que eu começar a receber:. sudo: apach2ctl: command not found
Eu acho que isso é devido à forma como sudo ambientes alças de ubuntu. (Eu também tentei sudo -E apche2ctl restart
e sudo env path=$PATH apache2ctl restart
com infrutíferas)
Então, minha pergunta é, basicamente, se eu quiser executar apache2ctl restart
como super usuário que solicita ao usuário a senha do super usuário quando necessário, como eu devo ir sobre como fazer isso? Não tenho a intenção de armazenar as senhas no script.
Editar:
Eu tentei passar nos comandos tanto como uma string e indexado em uma lista. No interpretador Python, com uma corda Vou pegar a senha prompt de adequadamente (ainda não funciona em um script Python como no meu problema original), uma lista apenas dá a tela de ajuda para sudo.
Edit 2:
Assim que percebo é que, enquanto Popen irá trabalhar com alguns comandos apenas como cordas quando shell = True, é preciso
proc = subprocess.Popen(['sudo','/usr/sbin/apache2ctl','restart'])
sem 'shell = True' para obter sudo ao trabalho.
Obrigado!
Solução
Tente dar o caminho completo para apache2ctl.
Outras dicas
Tente:
subprocess.call(['sudo', 'apach2ctl', 'restart'])
necessidades do subprocesso para acessar o real stdin / out / err para que ela seja capaz de pedir-lhe, e ler em sua senha. Se você configurá-los como tubos, você precisa para alimentar a senha naquele tubo si mesmo.
Se você não defini-los, então ele pega sys.stdout, etc ...
Outra maneira é fazer com que o seu usuário uma sudo user
sem senha.
Digite o seguinte na linha de comando:
sudo visudo
Em seguida, adicione o seguinte e substituir a <username>
com sua:
<username> ALL=(ALL) NOPASSWD: ALL
Isto irá permitir que o usuário executar o comando sudo
sem ter que pedir a senha (incluindo aplicação lançada pela referida usuário. Isso pode ser um risco de segurança, embora
Você tem que usar Popen assim:
cmd = ['sudo', 'apache2ctl', 'restart']
proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Ele espera que uma lista.
Eu usei isso para Python 3.5. Eu fiz isso usando subprocess module.Using o password como este é muito insegura .
O subprocess módulo assume o comando como uma lista de strings por isso ou criar uma lista de antemão usando split () ou passar toda a lista mais tarde. Leia a documentação para obter mais informações.
O que estamos fazendo aqui é ecoando a senha e, em seguida, usando tubulação que passá-lo para o sudo através argumento -S '.
#!/usr/bin/env python
import subprocess
sudo_password = 'mysecretpass'
command = 'apach2ctl restart'
command = command.split()
cmd1 = subprocess.Popen(['echo',sudo_password], stdout=subprocess.PIPE)
cmd2 = subprocess.Popen(['sudo','-S'] + command, stdin=cmd1.stdout, stdout=subprocess.PIPE)
output = cmd2.stdout.read().decode()
Eu tentei todas as soluções, mas não funcionou. Queria correr longa executando tarefas com aipo mas para estes eu precisava para executar o comando sudo chown com subprocess.call ().
Isto é o que funcionou para mim:
Para adicionar variáveis ??ambiente seguro, na linha de comando, digite:
export MY_SUDO_PASS="user_password_here"
Para testar se está Tipo de trabalho:
echo $MY_SUDO_PASS
> user_password_here
Para executá-lo na inicialização do sistema adicioná-lo ao final deste arquivo:
nano ~/.bashrc
#.bashrc
...
existing_content:
elif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi
...
export MY_SUDO_PASS="user_password_here"
Você pode adicionar todas as suas variáveis ??de ambiente senhas, nomes de usuário, host, etc aqui mais tarde.
Se as suas variáveis ??estão prontos você pode executar:
Para atualização:
echo $MY_SUDO_PASS | sudo -S apt-get update
Ou para instalar Midnight Commander
echo $MY_SUDO_PASS | sudo -S apt-get install mc
Para começar Midnight Commander com sudo
echo $MY_SUDO_PASS | sudo -S mc
Ou de shell python (ou Django / aipo), para alterar a propriedade de diretório de forma recursiva:
python
>> import subprocess
>> subprocess.call('echo $MY_SUDO_PASS | sudo -S chown -R username_here /home/username_here/folder_to_change_ownership_recursivley', shell=True)
Hope isso ajuda.
A maneira mais segura de fazer isso é para solicitar a senha de antemão e depois canalizá-lo no comando. Solicitando a senha vai evitar que a senha salva em qualquer lugar no seu código e ele também não vai aparecer na sua história bash. Aqui está um exemplo:
from getpass import getpass
from subprocess import Popen, PIPE
password = getpass("Please enter your password: ")
# sudo requires the flag '-S' in order to take input from stdin
proc = Popen("sudo -S apach2ctl restart".split(), stdin=PIPE, stdout=PIPE, stderr=PIPE)
# Popen only accepts byte-arrays so you must encode the string
proc.communicate(password.encode())