Unerwartetes Ergebnis bei Verwendung eines Pipe-Operators in einer Shell-Variablen

415
hebbo

Ich habe einen Prozess, der einige gezippte Ausgaben an die Standardausgabe sendet. Was ich mit dieser Ausgabe mache, ist Pipe und sende sie durch einen SSH-Tunnel an einen anderen Computer, wo sie in eine Datei gespeichert wird.

So wie:

/usr/bin/myapp | ssh root@remotemachine "cat > /path/to/output/file.gz" 

Wenn ich sshan die Maschine gehe und diese Zeile anrufe, geht alles gut. Aber wenn ich diesen Befehl in ein Shell-Skript stecke

#!/bin/sh APP=/usr/bin/myapp OPTS=--gzip OUTPUT= "| ssh root@remotemachine \"cat > /path/to/output/file.gz\"" $APP $OPTS $OUTPUT 

Und dann rufen Sie das Skript auf, ich sehe Müll auf der Konsole, von dem ich nur annehmen kann, dass es sich um die Ausgabe handelt myapp, und dann diese

Unknown parameter '|' Unknown parameter 'ssh' Unknown parameter 'root@remotemachine' Unknown parameter '"cat' Unknown parameter '>' Unknown parameter '/path/to/output/file.gz"' 

Ich vermute, dass die Shell die $OUTPUTSektion als Argument an sie geschickt hat, myappanstatt darauf zu wirken. Diese "unbekannten Parameter" stammen also myappnicht von der Shell.

Wie kann ich das beheben?

0
Haben Sie / bin / bash anstelle von / bin / sh versucht? Sirex vor 5 Jahren 0
Nein, das System, an dem ich arbeite, hat keine Bash. Ich muss die Arbeit auf Asche beschränken hebbo vor 5 Jahren 0
Dann sollten Sie `bash 'nicht als Tag verwenden. AFH vor 5 Jahren 0
ok ... entfernte es. Aber ich habe mich gefragt, ob mein Problem nicht spezifisch für Asche ist und tatsächlich auch in Bash vorkommen kann. Also wollte ich ein breiteres Publikum erreichen. An diesem Punkt bin ich auch nicht dort, wo das Problem liegt. hebbo vor 5 Jahren 0

2 Antworten auf die Frage

0
hebbo

Ok .... ich habe gefunden, was ich brauchte. Es war der evalBefehl. Dies war in der Tat beantwortet hier .

Das Skript kann also folgendermaßen geändert werden:

#!/bin/sh APP=/usr/bin/myapp OPTS=--gzip OUTPUT= "| ssh root@remotemachine \"cat > /path/to/output/file.gz\"" eval "$APP $OPTS $OUTPUT" 
0
Kamil Maciorowski

Ihre Shell analysiert jede Befehlszeile in einer bestimmten Reihenfolge. Wenn es trifft $APP $OPTS $OUTPUT, sieht es, dass es keinen Pipe-Operator gibt; Später werden diese Variablen erweitert und |erscheinen, aber es hat keine besondere Bedeutung, da es dafür bereits zu spät ist.

Das Ergebnis kann mit neu bewertet werden eval(Ihre Antwort zeigt, dass Sie dies bereits entdeckt haben), evalkann sich jedoch als falsch geschrieben herausstellenevil .

Ihr ursprünglicher Ansatz ist fehlerhaft, da Shell-Variablen keinen Code enthalten sollen. Funktionen sind für Code. Beispiel:

app=/usr/bin/myapp opts=--gzip output() { ssh root@remotemachine "cat > /path/to/output/file.gz"; } $app $opts | output 

Beachten Sie, dass die Verwendung von Variablennamen in Kleinbuchstaben eine gute Praxis ist .

Ich bin kein Experte für Shell-Scripting. Ich werde deine Antwort ausprobieren. Es sieht besser aus als meiner. hebbo vor 5 Jahren 0