Auch wenn @cyrus richtig ist - es beantwortet nicht die ganze Frage und es gibt keine Erklärung dafür, was passiert.
Lass uns also durchgehen.
Zeilenumbrüche in Zeichenfolge
Bestimmen Sie zunächst die zu erwartende Bytereihenfolge:
$ { echo a; echo b; } | xxd
0000000: 610a 620a a.b.
Verwenden Sie jetzt Command Substitution (Abschnitt 3.5.4), um zu versuchen, diese Byte-Sequenz zu erfassen:
$ x=$( echo a; echo b; )
Führen Sie dann ein einfaches Echo durch, um die Bytesequenz zu überprüfen:
$ echo $x | xxd
0000000: 6120 620a a b.
Es scheint also, dass die erste Zeile durch ein Leerzeichen ersetzt wurde und die zweite Zeile intakt blieb. Aber wieso ?
Schauen wir uns an, was hier tatsächlich passiert:
Zunächst führt bash die Shell-Parametererweiterung aus (Abschnitt 3.5.3).
Das Zeichen '$' führt eine Parametererweiterung, eine Befehlssubstitution oder eine arithmetische Erweiterung ein. Der zu erweiternde Parametername oder das zu erweiternde Symbol kann in geschweiften Klammern angegeben werden, die optional sind, aber dazu dienen, die zu erweiternde Variable vor Zeichen zu schützen, die unmittelbar darauf folgen und als Teil des Namens interpretiert werden könnten.
Dann führt bash die Wortteilung durch (Abschnitt 3.5.7)
Die Shell überprüft die Ergebnisse der Parametererweiterung, der Befehlssubstitution und der arithmetischen Erweiterung, die bei der Wortteilung nicht in doppelten Anführungszeichen stehen.
Die Shell behandelt jedes Zeichen von $ IFS als Trennzeichen und teilt die Ergebnisse der anderen Erweiterungen in Wörter für diese Zeichen auf. Wenn IFS nicht gesetzt ist oder sein Wert genau ist, ...
Als nächstes behandelt bash es als einfachen Befehl (Abschnitt 3.2.1)
Ein einfacher Befehl ist die Art von Befehl, die am häufigsten vorkommt. Es ist nur eine Folge von Wörtern, die durch Leerzeichen getrennt sind und durch einen der Steueroperatoren der Shell abgeschlossen werden (siehe Definitionen). Das erste Wort gibt im Allgemeinen einen auszuführenden Befehl an, wobei die restlichen Wörter die Argumente dieses Befehls sind.
Die Definition von Leerzeichen (Abschnitt 2 - Definitionen)
leer Ein Leerzeichen oder ein Tabulatorzeichen.
Schließlich ruft bash den internen Befehl echo (Abschnitt 4.2 - Bash Builtin Commands) auf
... Geben Sie die durch Leerzeichen getrennten Argumente aus, die mit einem Zeilenumbruch abgeschlossen werden. ...
Zusammenfassend werden die Zeilenumbrüche durch Word Splitting entfernt, und das Echo erhält zwei Argumente, "a" und "b", und gibt sie dann getrennt durch Leerzeichen aus und endet mit einem Zeilenumbruch.
Wenn Sie das tun, was @cyrus vorgeschlagen hat (und die Newline von Echo mit -n unterdrücken), ist das Ergebnis besser:
$ echo -n "$x" | xxd
0000000: 610a 62 a.b
Zeilenumbrüche am Ende der Zeichenfolge
Es ist immer noch nicht perfekt, die nachgestellte Newline ist weg. Kommandosubstitution näher betrachten (Abschnitt 3.5.4) :
Bash führt die Erweiterung durch, indem der Befehl ausgeführt und die Befehlsersetzung durch die Standardausgabe des Befehls ersetzt wird, wobei alle nachfolgenden Zeilenumbrüche gelöscht werden.
Nun, da klar ist, warum der Zeilenumbruch wegfällt, kann man sich täuschen, ihn zu behalten. Fügen Sie dazu am Ende eine zusätzliche Zeichenfolge hinzu und entfernen Sie diese, wenn Sie die Variable verwenden:
$ x=$( echo a; echo b; echo -n extra )
$ echo -n "${x%extra}" | xxd
0000000: 610a 620a a.b.
TL; DR
Fügen Sie einen zusätzlichen Teil am Ende der Ausgabe hinzu und zitieren Sie Variablen:
$ cat /no/file/here 2>&1 | xxd
0000000: 6361 743a 202f 6e6f 2f66 696c 652f 6865 cat: /no/file/he
0000010: 7265 3a20 4e6f 2073 7563 6820 6669 6c65 re: No such file
0000020: 206f 7220 6469 7265 6374 6f72 790a or directory.
$ cat /no/file/here 2>&1 | cksum
3561909523 46
$
$ var=$( cat /no/file/here 2>&1; rc=${?}; echo extra; exit ${rc})
$ echo $?
1
$
$ echo -n "${var%extra}" | xxd
0000000: 6361 743a 202f 6e6f 2f66 696c 652f 6865 cat: /no/file/he
0000010: 7265 3a20 4e6f 2073 7563 6820 6669 6c65 re: No such file
0000020: 206f 7220 6469 7265 6374 6f72 790a or directory.
$ echo -n "${var%extra}" | cksum
3561909523 46