2017-10-24 10 views
0

Ich muss den gleichen Befehl auf einem lokalen und Remote-Server ausführen. Also verwende ich subprocess.Popen, um auszuführen, und der lokale Befehl funktioniert wie erwartet, aber wenn ich auf der Fernbedienung ausführe, gibt es mir einen Fehler wie Befehl nicht gefunden. Ich schätze Ihre Unterstützung, da ich neu bin.Wie führe ich python subprocess.Popen mit vielen Argumenten aus?

Lokale Ausführungsfunktion

def topic_Offset_lz(self): 
     CMD = "/dsapps/admin/edp/scripts/edp-admin.sh kafka-topic offset %s -e %s | grep -v Getting |grep -v Verifying | egrep -v '^[[:space:]]*$|^#' | awk -F\: '{print $3}'|sed '%sq;d'" % (self.topic,self.envr,self.partition) 
     t_out_lz, t_error_lz = subprocess.Popen(CMD, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate() 
     return t_out_lz 

Remote-Server Ausführung

def topic_offset_sl(self): 
     CMD = "/dsapps/admin/edp/scripts/edp-admin.sh kafka-topic offset %s -e %s | grep -v Getting |grep -v Verifying | egrep -v '^[[:space:]]*$|^#' | awk -F\: '{print $3}'|sed '%sq;d'" % (self.topic, self.envr, self.partition) 
     t_out_sl, t_error_sl = subprocess.Popen(["ssh", "-q", CMD], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate() 
     return t_error_sl 

Fehler Ich

für die Remote-Ausführung bekommen

Landing Zone Offset: 0

SoftLayer Zone Offset: /bin/sh: ^# |sed 1: command not found /bin/sh: d: command not found

+0

'CMD = "ssh -q" + CMD' und dann:' subprocess.Popen (CMD.split(), stdout = ... ' – alfasin

+0

Jetzt ist es mir SSH Nutzung Menü angezeigt wird, scheint, wie es nicht pars die Variable, wie ich wollte, einen Fehler – Biginor

Antwort

0

Der ssh Befehl übergibt ihr Argument Vektor als eine einzige Befehlszeilen-String, kein Array. Um dies zu tun, verkettet sie einfach die Argumente, ohne Schale quotiert:

$ ssh target "python -c 'import sys;print(sys.argv)'" 1 2 3 
['-c', '1', '2', '3'] 
$ ssh target "python -c 'import sys;print(sys.argv)'" "1 2 3" 
['-c', '1', '2', '3'] 

Wenn es die richtige Schale zitiert, die Unterscheidung zwischen 1 2 3 und "1 2 3" wäre erhalten geblieben sind, und das erste Argument nicht brauchen doppelt zitieren .

Wie auch immer, in Ihrem Fall könnten folgende Arbeiten:

def topic_offset_sl(self): 
    CMD = "ssh -q " + pipes.quote("/dsapps/admin/edp/scripts/edp-admin.sh" 
      + " kafka-topic offset %s -e %s" % (self.topic, self.envr)) \ 
     + "grep -v Getting |grep -v Verifying | egrep -v '^[[:space:]]*$|^#'" 
     + " | awk -F\: '{print $3}'|sed '%sq;d'" % self.partition 
    t_out_sl, t_error_sl = subprocess.Popen(CMD], stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate() 
    return t_error_sl 

Dies setzt voraus, Sie wollen nur das /dsapps/admin/edp/scripts/edp-admin.sh Skript remote und nicht den Rest laufen.

Beachten Sie, dass bei der Verwendung von String-Spleißen zum Erstellen von Befehlszeilen wahrscheinlich Shell-Befehlsinjektionsschwachstellen (sowohl lokal als auch auf dem Remote-Server) auftreten.

+0

Erste, File "./test.py", Linie 107, in sl_offset_1 = c.topic_offset_sl() File "./test.py", line 70 in topic_offset_sl + "| grep -v Getting | grep -v Überprüfung | egrep -v '^ [[: space:]] * $ |^#'" + "| awk -F \: '{print $ 3}' | sed '% sq; d' "% self.partition AttributError: 'modul' Objekt hat kein Attribut 'quote' – Biginor

+0

Es ist' pipes.quote' o n Python 2. –

0

Ich kam mit der untenstehenden Lösung, vielleicht gibt es einen einfachen Weg, anstatt dies.

def topic_offset_sl(self): 
     CMD_SL1 = "ssh -q %s '/dsapps/admin/edp/scripts/edp-admin.sh kafka-topic offset %s -e %s'" % (KEY_SERVER,self.topic, self.envr) 
     CMD_SL2 = "| grep -v Getting |grep -v Verifying | egrep -v '^[[:space:]]*$|^#' | awk -F\: '{print $3}'|sed '%sq;d'" % (self.partition) 
     t_out_sl, t_error_sl = subprocess.Popen(CMD_SL1 + CMD_SL2 , stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True).communicate() 
     return t_out_sl 
Verwandte Themen