2017-08-17 4 views
0

Je suis actuellement à la recherche d'un outil de configuration générale pour ROS (Robot Operating System). En utilisant subprocess.POpen() et Tkinter Je crée un treeview comme ceci:Impossible de passer l'argument au sous-processus avec POpen

enter image description here

Les deux premières colonnes sont assez simples à créer en raison de la belle façon rospack list (une commande qui répertorie tous les paquets qui sont installés sur le système y compris ceux qui sont à l'intérieur l'espace de travail respectif où le développeur crée ses propres packages) fonctionne:

ros_packages_install_retrieve = subprocess.Popen(["rospack list"], shell=True, stdout=subprocess.PIPE) 
ros_packages_installed = [] 
for ros_package in ros_packages_install_retrieve.stdout.readlines(): 
    ros_package_adapted = ros_package.split(" ") 
    ros_package_adapted[1] = ros_package_adapted[1][:-1] 
    ros_packages_installed.append(ros_package_adapted) 

le colonne est requis une délicate en raison d'un problème d'esprit h appelez le rospack depends <package> (liste (le cas échéant) tous les paquets que le <package> nécessite pour être présent sur le système afin de construire et/ou de fonctionner). Pour chaque paquet qui est à l'intérieur ros_packages_installed j'appelle la fonction suivante:

def get_deps(ros_package): 
    ros_package_deps_retrieve = subprocess.Popen(["rospack", "depends", ros_package], shell=True, stdout=subprocess.PIPE) 
    ros_package_deps = [] 
    for ros_package_dep in ros_package_deps_retrieve.stdout.readlines(): 
     ros_package_dep = ros_package_dep.split("\n") 
     ros_package_dep = ros_package_dep[:-1] 
     ros_package_deps.append(ros_package_dep) 

    return ros_package_deps 

Le problème est que je reçois

[rospack] Error: no package given

et la valeur de retour est toujours une liste vide. J'ai même essayé de concaténer l'argument ros_package à la commande elle-même mais en vain.

Pendant mes tentatives futiles, j'ai trouvé quelque chose d'assez étrange. Les deux list et depends sont en fait des arguments qui sont passés à rospack. En fait, si vous appelez rospack seulement, vous obtiendrez une erreur vous disant d'appeler rospack help pour voir les arguments disponibles.

Par conséquent, j'ai essayé de scinder ces choses et j'ai passé ["rospack", "list"] et ["rospack", "depends", "ros_package"] aux deux POpen appels. Pour ma grande surprise, j'ai eu

[rospack] Error: no command given. Try 'rospack help' [rospack]

[rospack] Error: no command given. Try 'rospack help'

qui est au moins pour moi un comportement plutôt étrange.

Répondre

3

Ceci est une confusion avec la façon d'exécuter Popen. Vous devez soit passer une seule chaîne avec shell=True:

ros_package_deps_retrieve = subprocess.Popen("rospack depends %s"rospack, shell=True, stdout=subprocess.PIPE) 

ou passer comme une liste complètement séparée et utilisez shell=False (la valeur par défaut, pas nécessaire de préciser):

ros_package_deps_retrieve = subprocess.Popen(["rospack", "depends", rospack], stdout=subprocess.PIPE) 

Voir la documentation ici : https://docs.python.org/2/library/subprocess.html#popen-constructor

pièces importantes (ci-dessous sont des citations pertinentes docs):

If shell is True, it is recommended to pass args as a string rather than as a sequence. ...

If args is a sequence, the first item specifies the command string, and any additional items will be treated as additional arguments to the shell itself.

Alors, quand vous passez shell=True et passez comme ['rospack', 'list'], rospack finit par être la commande et list devient un argument à la coquille , pas ce que vous vouliez.

Quand shell=False et vous passez comme ['rospack depends', rosmodule], qui fait la chaîne 'rospack depends' la commande à exécuter, qui n'existe pas et ne permet donc pas.