2010-03-18 17 views
5

Ich schreibe ein Skript zu ssh in eine Liste von Maschinen und vergleichen Sie eine Variable mit einem anderen Wert .. Ich habe ein Problem (Ich habe ein paar Problemumgehungen, aber an dieser Stelle bin ich frage mich nur, warum diese Methode nicht funktioniert.Messy Bash Variable

VAR=`ssh $i "awk -F: '/^bar/ {print \$2}' /local/foo.txt"` 

($ würde ich ein Hostname sein Die Gastgeber vertraut sind, ist keine Passwortabfrage gegeben.)

Beispiel foo.txt:

foo:123456:abcdef 
bar:789012:ghijkl 
baz:345678:mnopqr 

Ich nehme an, es ist ein Problem, mit Anführungszeichen oder irgendwo gebraucht. Ich habe verschiedene Methoden ausprobiert (anders ausgedrückt, mit $() anstelle von ``, usw.), aber ich finde es nicht richtig. Mein Skript funktioniert ordnungsgemäß mit den folgenden:

VAR=`ssh $i "grep bar /local/foo.txt" | awk -F: '{print \$2}'` 

Wie ich schon sagte, nur eine Neugier, jede Antwort wird geschätzt.

Forgot zu schreiben, was meine Ausgabe war: awk spuckt die gesamte übereinstimmende Zeile aus, nicht die zweite Sektion. Ich spielte mit den Anführungszeichen und es schien ein Fehler zu sein, dass "{print" Befehl nicht gefunden wurde usw., als ob dort irgendwo eine neue Zeile wäre.

+0

Sie könnten mehr Antwort auf ServerFault, bezogen auf meine Frage dort: http://serverfault.com/ques/99886/ssh-not-redirecting-stdout-zu-lokal-terminal –

+0

Was passiert, wenn Sie das Caret aus dem ersten Beispiel entfernen? Vielleicht gibt es am Anfang der Zeile ein unsichtbares Zeichen. – danben

+0

@Lance Roberts - diese Frage bezieht sich auf awk, nicht auf ssh, und ist daher für Stack-Überlauf geeignet. – danben

Antwort

5

sshd gibt Ihren Befehl zur Ausführung von bash, so dass es sowohl den Bash-Interpreter auf der entfernten Seite als auch die Seite, auf der Sie das Skript ausführen, durchläuft. Lassen Sie uns an Ihren Befehl aussehen:

VAR=`ssh $i "awk -F: '/^bar/ {print \$2}' /local/foo.txt"` 

Sie haben richtig die $2 für die lokale Maschine entkommen, so dass die Bash-Skript Sie ausführen es nicht interpretieren. Aber alle Zitate von der Zeit entfernt werden wird es awk (Ich bin nicht ganz sicher, warum die inneren Anführungszeichen erhalten entfernt) und es wird die Ausführung dieses:

awk -F: /^bar/ {print $2} /local/foo.txt 

bash auf der Remote-Seite sieht $ 2 und ersetzt sie mit einer leeren Zeichenfolge, so dass Sie:

awk -F: /^bar/ {print } /local/foo.txt 

Deshalb druckt es die gesamte Zeile. Wie reparierst du es? Sie können entkommen, was bash auf der Remote-Seite wird mit einem Schrägstrich, wie so werden Ausführung:

VAR1=`ssh $i localhost "echo awk -F: '/^bar/ {print \\\$2}' /local/foo.txt"` 

Auch können Sie Echo nur den Befehl zu sehen, welche bash wirklich ausgeführt wird für Sie weitere Probleme debuggen Sie kommen across:

VAR1=`ssh $i localhost "echo awk -F: '/^bar/ {print \$2}' /local/foo.txt"` 
echo VAR1: $VAR1 

Execute it and see this output and see right away that it has removed $2: 
VAR1: awk -F: /^bar/ {print } /local/foo.txt 
+0

Es ist nicht so, dass die Anführungszeichen willkürlich entfernt werden, sondern dass die Shell auf der entfernten Seite sie interpretiert. Schreiben Sie die Befehlszeile. Zitieren Sie es für die Remote Shell. Zitieren Sie es für die lokale Shell. –

+0

Ahhh ich war nah dran! Vielen Dank! – Kyle

+0

@Chris Johnsen: Ich hatte mich beim Experimentieren verwirrt, als ich "... \ '{print \ $ 2} \' .." '. Ich sah auf der anderen Seite, dass es richtig um den Ausdruck herum war, aber die "$ 2" fehlten immer noch. Aber nachdem du gelesen hast, was du gesagt hast, macht es Sinn, weil es das '\ '' durch '' 'ersetzt und gleichzeitig' $ 2' ersetzt. Ich wusste, dass es keine Magie war, ich konnte es einfach nicht erklären. ;) Danke fürs klarstellen. – indiv

0

versuchen, die $() Syntax so weit wie möglich zu verwenden

VAR=$(ssh $i "awk -F: '/^bar/ {print \$2}' /local/foo.txt")