Passer des Variables de sous-processus.Popen
J'ai un script qui appelle un autre script python en sous-processus.Popen module. Mais depuis que j'ai des arguments stockés dans la variable(s)
servers[server]['address']
servers[server]['port']
servers[server]['pass']
Je ne suis pas en mesure d'exécuter la commande
p = subprocess.Popen(["python mytool.py -a ", servers[server]['address'], "-x", servers[server]['port'], "-p", servers[server]['pass'], "some additional command"], shell=True, stdout=subprocess.PIPE)
Utiliser les variables pour construire une chaîne de caractères qui est de la commande, ou de les transmettre à une liste d'arguments.
Les réponses ne doivent pas être modifiés en questions. Ceci permet d'éviter le point de l'ensemble de la commande basée sur la communauté de vote pondéré, ce qui est particulièrement dangereux parce que la solution que vous utilisez a de graves failles de sécurité (si un nom de serveur contient
Voir aussi Est-il OK pour l'utilisateur de modifier la accepté de répondre à la question? sur Meta Stack Overflow.
Les réponses ne doivent pas être modifiés en questions. Ceci permet d'éviter le point de l'ensemble de la commande basée sur la communauté de vote pondéré, ce qui est particulièrement dangereux parce que la solution que vous utilisez a de graves failles de sécurité (si un nom de serveur contient
$(rm -rf ~)
, devinez ce qui arrive?).Voir aussi Est-il OK pour l'utilisateur de modifier la accepté de répondre à la question? sur Meta Stack Overflow.
OriginalL'auteur GaNi | 2013-11-22
Vous devez vous connecter pour publier un commentaire.
Baisse
shell=True
. Les arguments pourPopen()
sont traités différemment sur Unix sishell=True
:Remarque que le passage
shell=True
pour les commandes avec entrée extérieure est un risque de sécurité, tel que décrit par un avertissement dans les docs.OriginalL'auteur jfs
Lorsque vous appelez
subprocess.Popen
vous pouvez passer une chaîne ou une liste pour la commande à exécuter. Si vous passez une liste, les éléments doivent être répartis d'une manière particulière.Dans votre cas, vous avez besoin de partager quelque chose comme ceci:
C'est parce que si vous passez dans une liste,
Popen
suppose que vous avez déjà fendu de la ligne de commande en mots (les valeurs desys.argv
), de sorte qu'il n'a pas besoin d'.La façon dont vous êtes l'appeler, il va essayer d'exécuter un binaire appelée "python mytool.py -un", ce qui n'est pas ce que vous voulez dire.
L'autre moyen pour résoudre ce problème est de rejoindre tous les mots dans une chaîne de caractères (qui
Popen
sera alors divisé - voirsous-processus.list2cmdline
). Mais il est préférable d'utiliser la version de liste, si possible, - il donne plus simple de contrôler la gestion de la ligne de commande est divisé (si les arguments sont séparés par des espaces ou des citations, par exemple) sans avoir à déranger les citations citation caractères.Je pense que tu veux dire que quand vous lisez à partir de p.stdout, il n'y a pas de sortie? C'est parce que la commande n'est pas en cours d'exécution.
En fait, le shell=True est probablement troubler l'eau ici - sauf si vous utilisez d'expansion (pour afficher une liste de fichiers, par exemple), il est préférable de l'éteindre.
sans shell=true, le script refuse de signer, il montre "sh: mytool.sh command not found"
Mettre dans le chemin d'accès complet mytool.sh - quoi "qui mytool.sh" donne lorsque vous tapez sur la ligne de commande.
OriginalL'auteur babbageclunk
Votre problème dans le type
str
pour la premièrePopen
argument. Remplacer àlist
. Ci-dessous le code:Si
command
arguments obtenir à partir d'une source fiable, vous pouvez construire descommand
et l'utiliser avecshell=True
d'une telle manière:Note 1: construit
command
avecshell=True
est potentiellement dangereux. Utilisationpipes.quote()
pour réduire l'injection de possibilité.Note 2:
pipes.quote()
obsolète depuispython2
; pourpython3
utilisationshlex
module.Si vous passez une liste avec
shell=True
, le premier argument est traité comme un script shell, et les arguments suivants en tant que paramètres pour le script (son$0
,$1
, etc). Les résultats de cetteshlex.split()
opération de liste n'est pas destinée à être analysés de cette façon; dans la pratique, il sera exécutépython
sans arguments.merci pour les bon commentaire. Fixe.
Beaucoup améliorée au premier semestre. Re: la seconde moitié, mieux à démontrer l'utilisation de
pipes.quote()
(ou en Python 3shlex.quote()
) pour la création de contenu être remplacé par une commande shell en toute sécurité, plutôt que de juste les mettre dans le code unsafe avec un tas de mises en garde.Me semble bon.
OriginalL'auteur Michael Kazarian
Vous devriez concaténer la commande pour un ensemble de la chaîne:
Ajouter "stderr=sous-processus.PIPE aussi
Si quelqu'un flux vous une liste d'adresses qui contient
$(rm -rf ~)
, vous feriez mieux espère que personne n'est à l'aide de cette concaténation. C'est massivement insécurité; même si vous souhaitez utilisershell=True
, le (seul) moyen sûr de le faire est de passer des variables hors-bande à partir d'un script de code:p = subprocess.Popen(['python mytool.py -a "$1" -x "$2" -p "$3" some additional command', '_', str(servers[server]['address']), str(servers[server]['port']), str(servers[server]['pass'])], shell=True, stdout=subprocess.PIPE)
OriginalL'auteur ciphor