2017-09-29 1 views
0

Je suis nouveau au sous-processus et j'essaie d'utiliser subprocess.call au lieu de os.system. La commande ressemblerait à ceci dans os.system:Comment formater une instruction subprocess.call()?

os.system('cluster submit {} gs://{}/{}'.format(cluster_name, bucket, file))

Comment cela se traduire par subprocess? J'ai essayé ce qui suit, mais ni travaillé:

  1. subprocess.call(["cluster", "submit", "{}", "gs://{}/{}".format(cluster_name, bucket, file)]).strip()

  2. subprocess.call(["cluster", "submit", "{}", "gs://{}/{}".format(cluster_name, bucket_name, script)], shell=True).strip()

+0

Qu'est-ce que "cluster"? S'il s'agit d'un alias, vous devrez le transformer en shell pour que BASH puisse le résoudre. Voir cette réponse: https://stackoverflow.com/questions/89228/calling-an-external-command-in-python/89243#89243 –

+1

@StuartBuckingham, les shells non-interactifs ne supportent pas les alias. Ils peuvent être activés dans bash, mais même alors, un shell non interactif n'exécute pas '.bashrc' ou' .bash_profile', donc il ne les verra pas. –

+0

@ PM2Ring, le 'sh' par défaut n'a rien à voir avec cela. Si vous n'avez pas 'shell = True', alors c'est exclusivement le shebang qui décide du shell à exécuter, et l'exécution d'un script sans shebang échouera; c'est seulement si vous avez un shell qu'il y a un comportement de repli d'un autre interpréteur shell si l'appel 'exec' du noyau échoue. –

Répondre

1
subprocess.call([ 
    "cluster", 
    "submit", 
    str(cluster_name), 
    "gs://{}/{}".format(bucket_name, script) 
]) 
1

Tout d'abord, jetez un oeil à the docs for subprocess.call:

subprocess.call(args, *, stdin=None, stdout=None, stderr=None, shell=False)

Exécutez la commande décrite par args. Attendez la fin de la commande, puis renvoyez l'attribut de code retour.

La commande renvoie le code de retour du processus, qui est un entier, de sorte que votre tentative d'appel subprocess.call(...).strip() va échouer. Si vous voulez que la sortie de la commande, vous avez besoin:

subprocess.check_output(args, *, stdin=None, stderr=None, shell=False, universal_newlines=False)

commande Exécuter avec des arguments et le retour de sa sortie comme une chaîne d'octets.

Cela vous donne:

output = subprocess.call(["cluster", "submit", "{}", 
    "gs://{}/{}".format(cluster_name, bucket, file)]).strip() 

Mais il y a des problèmes là Python de base, parce que vous avez un "{}" nu sur lequel vous êtes pas appeler .format, et vous avez a obtenu "gs://{}/{}" qui a seulement deux marqueurs de format, mais trois paramètres. Vous voulez quelque chose comme:

output = subprocess.call(["cluster", "submit", cluster_name, 
    "gs://{}/{}".format(bucket, file)]).strip() 

Lorsque vous utilisez shell=True, comme dans votre deuxième exemple, vous passer une chaîne plutôt qu'une liste. E.g:

output = subprocess.check_output("cluster submit {} gs://{}/{}".format(
    cluster_name, bucket_name, script), shell=True).strip()