703 Stimmen

Erfassen der Ausgabe mehrerer Zeilen in einer Bash-Variablen

Ich habe ein Skript "myscript", das Folgendes ausgibt:

abc
def
ghi

in einem anderen Skript, rufe ich auf:

declare RESULT=$(./myscript)

y $RESULT erhält den Wert

abc def ghi

Gibt es eine Möglichkeit, das Ergebnis entweder mit den Zeilenumbrüchen oder mit '' zu speichern? \n Zeichen, damit ich es mit '' ausgeben kann echo -e '?

2 Stimmen

Das überrascht mich. haben sie nicht $(cat ./myscipt) ? sonst hätte ich erwartet, dass es versucht, die Befehle abc, def und ghi auszuführen

0 Stimmen

@litb: Ja, ich denke schon; Sie können auch $(<./myscript) verwenden, was die Ausführung eines Befehls vermeidet.

3 Stimmen

(Anmerkung: Die beiden obigen Kommentare beziehen sich auf eine Überarbeitung der Frage, die mit Ich habe ein Skript "myscript", das Folgendes enthält was zu den Fragen führte. Die aktuelle Überarbeitung der Frage ( Ich habe ein Skript "myscript", das Folgendes ausgibt ) macht die Kommentare überflüssig. Die Überarbeitung stammt jedoch vom 11.11.2011, lange nachdem die beiden Kommentare abgegeben wurden.

1307voto

Jonathan Leffler Punkte 694013

Eigentlich enthält RESULT das, was Sie demonstrieren wollen:

echo "$RESULT"

Was man zeigt, ist das, was man bekommt:

echo $RESULT

Wie in den Kommentaren erwähnt, besteht der Unterschied darin, dass (1) die in Anführungszeichen gesetzte Version der Variablen ( echo "$RESULT" ) behält den internen Abstand des Wertes genau so bei, wie er in der Variablen dargestellt ist - Zeilenumbrüche, Tabulatoren, mehrere Leerzeichen und alles -, während (2) die nicht in Anführungszeichen gesetzte Version ( echo $RESULT ) ersetzt jede Folge von einem oder mehreren Leerzeichen, Tabulatoren und Zeilenumbrüchen durch ein einzelnes Leerzeichen. Somit behält (1) die Form der Eingabevariablen bei, während (2) eine potenziell sehr lange einzelne Ausgabezeile mit "Wörtern" erzeugt, die durch einzelne Leerzeichen getrennt sind (wobei ein "Wort" eine Folge von Zeichen ohne Leerzeichen ist; keines der Wörter muss alphanumerisch sein).

102voto

l0b0 Punkte 51652

Ein weiterer Fallstrick dabei ist, dass Befehlsersetzung - $() - entfernt nachstehende Zeilenumbrüche. Wahrscheinlich ist das nicht immer wichtig, aber wenn Sie wirklich die genau was ausgegeben wurde, müssen Sie eine weitere Zeile und einige Anführungszeichen verwenden:

RESULTX="$(./myscript; echo x)"
RESULT="${RESULTX%x}"

Dies ist besonders wichtig, wenn Sie Griff alle mögliche Dateinamen (um undefiniertes Verhalten zu vermeiden, wie z.B. das Arbeiten mit der falschen Datei).

32voto

user2574210 Punkte 303

Falls Sie an bestimmten Zeilen interessiert sind, verwenden Sie ein Ergebnis-Array:

declare RESULT=($(./myscript))  # (..) = array
echo "First line: ${RESULT[0]}"
echo "Second line: ${RESULT[1]}"
echo "N-th line: ${RESULT[N]}"

16voto

Lurchman Punkte 181

Zusätzlich zu der von @l0b0 gegebenen Antwort hatte ich gerade die Situation, in der ich sowohl die vom Skript ausgegebenen Zeilenumbrüche als auch die und prüfen Sie den Rückgabewert des Skripts. Und das Problem mit der Antwort von l0b0 ist, dass das 'echo x' $? wieder auf Null zurücksetzt... also habe ich mir diese sehr schlaue Lösung einfallen lassen:

RESULTX="$(./myscript; echo x$?)"
RETURNCODE=${RESULTX##*x}
RESULT="${RESULTX%x*}"

8voto

F. Hauri Punkte 57640

Parsen mehrerer Ausgaben

Einführung

Also Ihr myscript Ausgabe von 3 Zeilen, könnte wie folgt aussehen:

myscript() { echo $'abc\ndef\nghi'; }

ou

myscript() { local i; for i in abc def ghi ;do echo $i; done ;}

Ok, dies ist eine Funktion, kein Skript (kein Pfad erforderlich ./ ), aber die Ausgabe ist die gleiche

myscript
abc
def
ghi

Unter Berücksichtigung von Ergebniscode

Um den Ergebniscode zu prüfen, wird die Testfunktion:

myscript() { local i;for i in abc def ghi ;do echo $i;done;return $((RANDOM%128));}

1. Speicherung mehrerer Ausgaben in einer einzigen Variablen, mit Zeilenumbrüche

Ihre Operation ist korrekt:

RESULT=$(myscript)

Über Ergebniscode könnten Sie hinzufügen:

RCODE=$?

sogar in derselben Zeile:

RESULT=$(myscript) RCODE=$?

Dann

echo $RESULT $RCODE

abc def ghi 66

echo "$RESULT"

abc
def
ghi

echo ${RESULT@Q}

$'abc\ndef\nghi'

printf '%q\n' "$RESULT"

$'abc\ndef\nghi'

aber für die Anzeige der Variablendefinition, verwenden Sie declare -p :

declare -p RESULT RCODE

declare -- RESULT="abc
def
ghi"
declare -- RCODE="66"

2. Parsen mehrerer Ausgaben in einem Array, mit mapfile

Speichern der Antwort in myvar variabel:

mapfile -t myvar < <(myscript)
echo ${myvar[2]}

ghi

anzeigen $myvar :

declare -p myvar

declare -a myvar=([0]="abc" [1]="def" [2]="ghi")

Unter Berücksichtigung von Ergebniscode

Falls Sie nach einem Ergebniscode suchen müssen, können Sie dies tun:

RESULT=$(myscript) RCODE=$?
mapfile -t myvar <<<"$RESULT"

declare -p myvar RCODE

declare -a myvar=([0]="abc" [1]="def" [2]="ghi")
declare -- RCODE="40"

3. Parsing mehrerer Ausgaben durch aufeinanderfolgende read in der Befehlsgruppe

{ read firstline; read secondline; read thirdline;} < <(myscript)
echo $secondline
def

Anzeige der Variablen:

declare -p firstline secondline thirdline

declare -- firstline="abc"
declare -- secondline="def"
declare -- thirdline="ghi"

Ich verwende oft:

{ read foo;read foo total use free foo ;} < <(df -k /)

Dann

declare -p use free total

declare -- use="843476"
declare -- free="582128"
declare -- total="1515376"

Unter Berücksichtigung von Ergebniscode

Derselbe vorangestellte Schritt:

RESULT=$(myscript) RCODE=$?
{ read firstline; read secondline; read thirdline;} <<<"$RESULT"

declare -p firstline secondline thirdline RCODE

declare -- firstline="abc"
declare -- secondline="def"
declare -- thirdline="ghi"
declare -- RCODE="50"

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X