2016-05-30 14 views
0

Meine Frage an dieser früheren Frage zusammenhängt - Python subprocess usagePython-Skript: Ausführen eines Skripts mit mehreren Argumenten subprocess

Ich versuche, diesen Befehl auszuführen Python mit

nccopy -k 4 „http://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/ncep.reanalysis2/pressure/air.2014.nc?air[408:603][2][20:34][26:40]“ foo .nc

Wenn ich den obigen Befehl ausführen, sollte ich in der Lage sein, eine Datei namens foo.nc auf meiner Festplatte oder einen Netzwerkfehler zu sehen, der nicht auf diese URL oder Remote-URL nicht gefunden.

Zur Zeit der ESRL NOAA Server ausgefallen ist - so, wenn ich den obigen Befehl ausführen ich

Syntaxfehler, unerwarteten $ end, erwartet SCAN_ATTR oder SCAN_DATASET oder SCAN_ERROR Kontext:^ NetCDF: Zugriffsfehler Ort: Datei nccopy.c; 1348 Leitung

Ich sollte den gleichen Fehler, wenn ich das Python-Skript laufen

Dies ist der Code, den ich habe, und ich bin nicht in der Lage, genau herauszufinden, wie weiter verfahren ist -

Ich versuchte Spaltung " -k 4" in zwei Argumente und die Anführungszeichen zu entfernen und ich immer noch diesen Fehler nccopy: ungültiges Format: 4

Ergebnisse drucken (sys.argv) data.py

[ 'data.py', ' -k ',' 4 ',' http://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/ncep.reanalysis2/pressure/air.2014.nc?air[480:603][20:34][26:40] ',' foo.nc ']

import numpy as np 

import subprocess 

import sys 

url = '"http://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/ncep.reanalysis2/pressure/air.2014.nc?air[408:603][2][20:34][26:40]"' 

outputFile = 'foo.nc' 

arg1 = "-k 4" 

arg3 = url 

arg4 = outputFile 


print (input) 

subprocess.check_call(["nccopy",arg1,arg3,arg4]) 
+0

Verwenden Sie zuerst [shlex] (https://docs.python.org/3/library/shlex.html), verwenden Sie zweitens 'Popen()' anstelle von 'check_call()' wenn möglich. Ihr Problem ist auch, dass Sie '-k' und' 4' nicht trennen. Der Subprozess versucht automatisch, für jedes Parameterelement einen Platz einzufügen. Versuchen Sie dies '[" nccopy "," -k "," 4 "]' – Torxed

+0

Auch beim Aufruf von Systembefehlen gilt immer noch die traditionelle Shelllogik, was '' 'ermöglicht das Parsen von Variablen und Zeichen, wo es keine Parameter gibt Wenn Sie den Parameter nicht parsen möchten, würde ich '' 'verwenden, um die Parameter zu umbrechen. – Torxed

Antwort

2

dort ist zwei Dilemmas hier.
Ein Wesen, dass Unterprozess Ihre Argumente verarbeitet und versucht, 4 als separates Argument zu verwenden.

Der andere, dass Systemaufrufe immer noch unter normalen Shell-Regeln geht, bedeutet, dass Parameter und Befehle für metacharacters aka Sonderzeichen analysiert werden. In diesem Fall wickeln Sie [ und ] ein.

Für Sie benötigen jeweils Parameter zu trennen und es ist Wert in separate Objekte in der Parameterliste, zum Beispiel -k 4['-k', '4'] sein sollte, und Sie müssen Parameter/Werte in '...' statt "..." wickeln.

Try this, shlex.split() macht die Hauptarbeit für dich und ich tauschte die Verkapselung Zeichen rund um die URL:

import numpy as np 
import subprocess 
import sys 
import shlex 

url = "'http://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/ncep.reanalysis2/pressure/air.2014.nc?air[408:603][2][20:34][26:40]'" 

outputFile = 'foo.nc' 
command_list = shlex.split('nccopy -k 4 ' + url + ' ' + outpufFile) 

print(command_list) 

subprocess.check_call(command_list) 
+2

Wenn' outputFile' ein Leerzeichen enthält, schlägt Ihr Code-Beispiel fehl kein Grund, 'shlex.split()' hier zu verwenden (und [es kann im allgemeinen Fall getäuscht werden]) (http://stackoverflow.com/questions/14386775/subprocess-call/14386815#comment45736245_14386815)) 'shlex.split()' in einer REPL zu verwenden (um eine Seedarguments-Liste aus einem Shell-Befehl zu erstellen, die Sie später manuell anpassen können) - vermeiden Sie es im endgültigen Code – jfs

+0

@JFSebastian - können Sie ein schreiben alternative Antwort, die völlig anders ist als die anderen beiden? – gansub

2

Anstelle von arg1 = "-k 4" verwenden Sie stattdessen zwei Argumente.

import subprocess 


url = 'http://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/ncep.reanalysis2/pressure/air.2014.nc?air[408:603][2][20:34][26:40]' 

outputFile = 'foo.nc' 

arg1 = "-k" 
arg2 = "4" 
arg3 = url 
arg4 = outputFile 

subprocess.check_call(["nccopy", arg1, arg2, arg3, arg4]) 

Siehe hier auch Python subprocess arguments

+0

Ja, gut, ich bearbeite – SnoozeTime

1

Wenn Sie eine funktionierende Shell-Befehl haben, die ein einzelnes Programm mit mehreren Argumenten ausgeführt wird, und Sie wollen Um zB einen variablen Dateinamen anstelle des hardcoded Wertes zu parametrisieren, könnten Sie shlex.split() verwenden, um eine Liste von Befehlszeilenargumenten zu erstellen, die Sie an das subprocess Modul übergeben und das gewünschte Argument durch eine Variable ersetzen können:

>>> shell_command = "python -c 'import sys; print(sys.argv)' 1 't w o'" 
>>> import shlex 
>>> shlex.split(shell_command) 
['python', '-c', 'import sys; print(sys.argv)', '1', 't w o'] 

den Befehl mit dem gleichen Python-Interpreter als Mutter Skript auszuführen, sys.executable verwendet werden könnte, und wir können einen variable statt '1' passieren:

#!/usr/bin/env python 
import random 
import sys 
import subprocess 

variable = random.choice('ab') 
subprocess.check_call([sys.executable, '-c', 'import sys; print(sys.argv)', 
         variable, 't w o']) 

Hinweis:

  • ein Befehlszeilenargument pro Listenelement
  • keine shlex.split() in der Fin al-Code
  • es keine Anführungszeichen innerhalb 't w o' dh, wird 't w o' statt '"t w o"' oder "'t w o'"

subprocess Modul läuft nicht die Shell standardmäßig verwendet und daher müssen Sie keine Shell-Meta-Zeichen, wie zu entkommen als ein Leerzeichen innerhalb der Befehlszeilenargumente. Und umgekehrt, wenn Ihr Befehl irgendeine Shell-Funktionalität (z. B. Dateimuster) verwendet, dann entweder die entsprechenden Features in Python neu implementieren (z. B. glob-Modul verwenden) oder shell=True verwenden und den Befehl als String unverändert übergeben. Möglicherweise benötigen Sie pipes.quote(), um in diesem Fall variable Argumente zu umgehen. Wildcard not working in subprocess call using shlex

Verwandte Themen