exécuter une commande en tant que super-utilisateur à partir d'un script python

J'essaie donc d'obtenir un processus à exécuter en tant que super-utilisateur à partir d'un script python en utilisant un sous-processus. Dans le shell ipython quelque chose comme

proc = subprocess.Popen('sudo apach2ctl restart',
                        shell=True, stdin=subprocess.PIPE,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.PIPE)

fonctionne très bien, mais dès que j'ai le coller dans un script que j'ai commencer à obtenir: sudo: apach2ctl: command not found.

je suppose que c'est dû à la façon dont sudo gère les environnements sur ubuntu. (J'ai aussi essayé sudo -E apche2ctl restart et sudo env path=$PATH apache2ctl restart avec en vain)

donc ma question est essentiellement, si je veux courir apache2ctl restart comme super-utilisateur que invite l'utilisateur pour le super mot de passe de l'utilisateur lorsque nécessaire, Comment dois-je procéder? Je n'ai pas l'intention de stocker les mots de passe dans le script.

Edit:

j'ai essayé de passer les commandes à la fois comme une chaîne et tokenized dans une liste. Dans l'interpréteur python, avec une chaîne de caractères, j'obtiendrai l'invite de mot de passe correctement (ne fonctionne toujours pas dans un script python comme dans mon problème original), une liste ne donne que l'écran d'aide pour sudo.

Modifier 2:

donc ce que j'ai compris c'est que bien que Popen fonctionne avec certaines commandes tout comme strings quand shell=True, il faut

proc = subprocess.Popen(['sudo','/usr/sbin/apache2ctl','restart'])

sans 'shell=True' pour faire fonctionner sudo.

Merci!

36
demandé sur Silfheed 2009-02-20 01:33:16

6 réponses

essayez de donner le chemin complet vers apache2ctl.

14
répondu dwc 2009-02-19 22:46:38

Essaie:

subprocess.call(['sudo', 'apach2ctl', 'restart'])

le sous-processus doit accéder au vrai stdin/out / err pour qu'il puisse vous inviter, et lire votre mot de passe. Si vous les configurez comme des pipes, vous devez entrer le mot de passe dans cette pipe vous-même.

si vous ne les définissez pas, alors il saisit sys.stdout, etc...

22
répondu Mike Boers 2009-02-19 23:11:30

une autre façon est de rendre votre utilisateur un mot de passe-moins sudo user.

tapez ce qui suit sur la ligne de commande:

sudo visudo

puis ajouter ce qui suit et remplacer le <username> avec la vôtre:

<username> ALL=(ALL) NOPASSWD: ALL

Cela permettra à l'utilisateur d'exécuter sudo commande sans avoir à demander le mot de passe (y compris l'application lancée par ledit utilisateur. Cela peut être un risque pour la sécurité si

10
répondu Michael Loo 2014-07-09 00:06:59

Vous devez utiliser Popen comme ceci:

cmd = ['sudo', 'apache2ctl', 'restart']
proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

il attend une liste.

4
répondu Harley Holcombe 2009-02-19 22:35:06

j'ai utilisé ceci pour python 3.5. Je l'ai fait à l'aide de sous-processus module.Utiliser le mot de passe comme ceci est très peu sûr.

sous-processus le module prend la commande comme une liste de chaînes de caractères, alors créez une liste à l'avance en utilisant split () ou passer l'ensemble de la liste plus tard. Lire la documentation pour plus d'informations.

ce que nous faisons ici c'est faire écho au mot de passe et ensuite utiliser pipe nous passez-le au sudo par l'argument '- 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() 
3
répondu Nandesh 2018-05-16 11:03:43

j'ai essayé toutes les solutions, mais ne fonctionne pas. Je voulais exécuter des tâches de longue durée avec Celery, mais pour celles-ci, j'avais besoin d'exécuter sudo chown command avec subprocess.appeler.)(

C'est ce qui a fonctionné pour moi:

ajouter coffre-fort variables d'environnement, dans la ligne de commande, tapez:

export MY_SUDO_PASS="user_password_here"

Pour tester si ça fonctionne type:

echo $MY_SUDO_PASS
 > user_password_here

exécuter au démarrage du système, l'ajouter à la fin de cette fichier:

nano ~/.bashrc  

#.bashrc
...
existing_content:

  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi
...

export MY_SUDO_PASS="user_password_here"

vous pouvez ajouter toutes vos variables d'environnement mots de passe, noms d'utilisateurs, hôte, ETC ici plus tard.

si vos variables sont prêtes, vous pouvez lancer:

mettre À jour:

echo $MY_SUDO_PASS | sudo -S apt-get update

Ou à l'installation de Midnight commander

echo $MY_SUDO_PASS | sudo -S apt-get install mc

Pour commencer Midnight commander avec sudo

echo $MY_SUDO_PASS | sudo -S mc

ou de Python shell (ou Django / Celery), pour changer la propriété des répertoires de manière récursive:

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)

j'Espère que ça aide.

2
répondu Jozsef Turi 2018-03-15 16:49:49