2016-05-03 15 views
0

Ich bin sicher, das ist einfach, aber ich bin neu zu bash Skripte und der syntaktische Prozess hier ist jenseits meiner. Ich kann nicht die richtigen Suchbegriffe finden, um zu finden, was ich brauche. Dieses Skript ist wirklich nur ein Sprungbrett zu meiner endgültigen Version.Bash - verschachtelte Variable Erweiterung innerhalb Befehlszuweisung

Invocation: ./myscript.sh testfile

Script:

#!/bin/bash 

file=$1 
awk='{print $9}' # do not expand $9 
awk="'/$file/$awk'" # DO expand file argument 
echo "$awk" # prints '/graphic/{print $9}' (as expected) 
echo "ls -l | awk $awk" # prints ls -l | awk '/graphic/{print $9}' (as expected) 
test="$(ls -l | awk $awk)" # error 
echo "$test" 

Ausgang:

'/testFile/{print $9}' 
ls -l | awk '/testFile/{print $9}' 
awk: syntax error at source line 1 
context is 
    >>> ' <<< 
    missing } 
awk: bailing out at source line 1 

Auch wenn ich die zweite echo'd Linie kopieren und ausführen kann und es funktioniert erfolgreich, das Versagen des Befehls führt mich zu der Annahme, dass dies nicht einfach String Concat ist, sondern etwas verrückter Voodoo.

Ich habe auch eine andere Version ausprobiert wie eine Variable, die den ganzen Befehl enthält, aber dann bekomme ich noch weniger erwartete Ausgabe.

Wenn ich Test = "$ ($ awk)" do ich

'/testFile/{print $9}' 
ls -l | awk '/testFile/{print $9}' 
ls: $9}': No such file or directory 
ls: '/testFile/{print: No such file or directory 
ls: awk: No such file or directory 
ls: |: No such file or directory 

Wenn ich Test tun = $ (awk) I

'/testFile/{print $9}' 
ls -l | awk '/testFile/{print $9}' 
usage: awk [-F fs] [-v var=value] [-f progfile | 'prog'] [file ...] 

Da mein Google erhalten Abfragen enthalten im Grunde nur die Wörter "bash command variable assignment", ich kann nichts mit der verschachtelten Variablenerweiterung in Verbindung bringen, die ich hier habe. Ich verstehe, was es tut, basierend auf dem Fehler, aber ich konnte nicht sagen warum oder wie es zu beheben ist.

Wenn jemand eine Reparatur zur Verfügung stellen könnte, sowie erklären oder zeigen Sie mir eine Ressource erklären, was hier vor sich geht, würde es sehr geschätzt werden. Oder vielleicht gibt es noch einen anderen Ansatz, der die Logik vereinfachen würde.

Danke!

+0

'set -x' und http://www.shellcheck.net sind deine Freunde. – Biffen

+0

Cool, set -x scheint zu enthüllen, dass flüchtige einfache Anführungszeichen hinzugefügt werden ... Frage ist, wie man es repariert ... – Liandri

+0

Ok Ich habe etwas, das funktioniert (test = "$ (ls -l | awk" $ awk ")) "), aber es wird noch mehr lernen, wie man diesen Fehler vermeidet. Es scheint, dass String-Variablen nicht nur durch Anführungszeichen definiert sind, sondern auch in Anführungszeichen eingeschlossen sind, wenn Sie sie später verwenden. Ich habe also nicht direkt Kontrolle darüber, wie meine Befehle zitiert werden. – Liandri

Antwort

1

Wechseln zu:

test="$(ls -l | awk "$awk")" # error 

awk erfordert das Skript ein einziges Argument zu sein. Aber wenn Sie eine Variable außerhalb doppelte Anführungszeichen erweitern, führt die Shell-Wort Spaltung, so wird $awk in zwei Argumente erweitert:

  1. '{print
  2. $9}'

Die Zitate der Expansion als ein einziges Argument halten .

Auch nehmen die einfachen Anführungszeichen aus

awk="'/$file/$awk'" 

Einfache Anführungszeichen eine Variable nach Erweiterung nicht verarbeitet werden, so werden sie buchstäblich zu awk weitergegeben werden. Durch Angeben von Anführungszeichen um $awk wird das Ergebnis erzielt, das Sie mit diesen Zitaten erzielen wollten.