2017-06-17 3 views
0

Wenn ich versuche, den folgenden Code auszuführen, ersetzt die Shell $ 4 und $ 2 mit Leerzeichen, weil sie nicht als eine Bash-Variable definiert sind. Meine Frage ist, wie halte ich Bash davon ab, die Positionsparameter für awk als seine Variablen zu bewerten? Ich habe versucht, doppelte und einfache Anführungszeichen um die Positionsparameter zu setzen, die Bash jedoch nicht davon abhalten, sie als lokale Variablen anstelle von Strings zu interpretieren.BASH Shell-Ausführung von String mit Positionsparametern

Dies ist, was wird zurückgegeben, wenn ich echo "$x$i$y"

date -r /root/capture/capture11.mp4 | awk '{print }' | awk -F":" '/1/ {print }' 

Code:

#!/bin/sh 
i=$(cat /etc/hour.conf) 
x="date -r /root/capture/capture" 
y=".mp4 | awk '{print $4}' | awk -F\":\" '/1/ {print $2}'" 
$x$i$y 

Jede Hilfe wäre sehr dankbar!

+0

Erstellen einer Befehlszeile mit einer einfachen Zeichenfolge Verkettung und Anführungszeichen wird mit Feuer gespielt. – anubhava

+0

vielleicht, aber was ist ein besserer Weg, um die Anzahl der Minuten nach einer Stunde für eine vorhandene Datei zu erhalten? – user3308131

+0

Verwenden Sie ein Shell-Array – anubhava

Antwort

0

$4 ist doppelt zitiert. Obwohl es einfache Anführungszeichen gibt, ist es in doppelte Anführungszeichen eingeschlossen. Die einfachen Anführungszeichen sind also nur ein Teil der Zeichenkette und behalten nicht die wörtliche Bedeutung $. So können Sie entkommen die $:

y=".mp4 | awk '{print \$4}' | awk -F\":\" '/1/ {print \$2}'" 

Oder verwenden Sie einfache Anführungszeichen um den gesamten Teil:

y='.mp4 | awk "{print \$4}" | awk -F':' "/1/ {print \$2}"' 
3

Variablen werden in doppelte Anführungszeichen interpoliert. Verwenden Sie einfache Anführungszeichen oder geben Sie sie wie \$2 frei.

Die Art und Weise, wie Sie den Befehl in separate Variablen aufteilen möchten, funktioniert jedoch nicht. Stattdessen sollten Sie eine Funktion verwenden. Dann müssen Sie sich nicht mit Zitaten beschäftigen und überhaupt nicht entkommen. Zum Beispiel:

do_thing() { 
    date -r "/root/capture/capture$1.mp4" | awk '{print $4}' | awk -F':' '/1/ {print $2}' 
} 

do_thing "$(cat /etc/hour.conf)" 
+0

Danke für Ihr Beispiel. Ich bin ein Neuling (als ob du es nicht sagen könntest), Shell Scripting zu bash. Wie werden die Ergebnisse in Ihrem Beispiel zurückgegeben? Mit einer Aufgabe anrufen? time = do_thing "$ (cat /etc/hour.conf)" – user3308131

+0

Funktionen funktionieren wie normale Befehle. 'do_thing" $ (cat /etc/hour.conf) "' wird seine Ausgabe auf stdout ausgeben. Wenn Sie die Ausgabe erfassen möchten, führen Sie 'time = $ (do_thing $) (cat/etc/hour.conf) ")'. Wenn Sie es zu einem anderen Befehl pipen möchten, tun Sie "do_thing" $ (cat /etc/hour.conf) "| awk | sed | grep'. –

+0

Danke! Ich schätze die Hilfe! – user3308131

0

Variablen wie das Verketten eine Befehlszeile Art Werke zu bauen, aber zitiert innerhalb die Variablen nichts zitieren, werden sie nur als wörtliche Zitate genommen.

Diese Art von Arbeiten (aber ist schrecklich):

$ x=prin; y="tf %f\\n"; z=" 123456789" 
$ $x$y$z 
123456789.000000 

Dies nicht tun, was Sie wollen:

$ z='"foo bar"'; printf $y ; echo 
"foo 

Statt ein Argument foo bar, printf bekommt die beiden Argumente "foo und bar".