ubuntuusers.de

Bash, mehrere Zeilen übergeben? Hilfe

Status: Ungelöst | Ubuntu-Version: Server 16.04 (Xenial Xerus)
Antworten |

Xpertus

Anmeldungsdatum:
22. Juni 2016

Beiträge: 2

Hallo,

ich würde gerne mehrere Zeilen echo an ein script übergeben. Komme aber leider nicht weiter!

Aufruf:

1
2
3
> echo "Hallo
> zweite Zeile
> dritte Zeile" | myscript.sh -p 001

Script:

1
2
3
#!/bin/bash
read text
echo "$text"

Das read erkennt nur eine Zeile. Wie bekommt man einen solchen Text komplett übergeben? zB Wie beim befehl "mail"

Bitte um Hilfe, Xpertus

misterunknown Team-Icon

Ehemalige
Avatar von misterunknown

Anmeldungsdatum:
28. Oktober 2009

Beiträge: 4403

Wohnort: Sachsen

Xpertus schrieb:

Script:

1
2
3
#!/bin/bash
read text
echo "$text"

Das read erkennt nur eine Zeile. Wie bekommt man einen solchen Text komplett übergeben? zB Wie beim befehl "mail"

Logisch. Wenn du mehrere Zeilen lesen willst, musst du auch mehrere Zeilen lesen 😉

1
while read line; do echo $line; done

D630

Avatar von D630

Anmeldungsdatum:
24. Juli 2013

Beiträge: 329

He!

Siehe

1
2
3
while IFS= read -r
do
done

Solche Konstrukte gingen auch:

1
mapfile -t stdin < /dev/stdin

:

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13174

Xpertus,herzlich willkommen hier im Forum!

D630 schrieb:

1
2
3
while IFS= read -r
do
done

Das liest nur zeilenweise:

1
2
$ seq 1 5 | { IFS= read -r a; echo "$a"; }
1

Wenn man alles in einer Variable haben will, geht es so:

1
2
3
4
5
6
$ seq 1 5 | { read -rd '' a; echo "$a"; }
1
2
3
4
5

Solche Konstrukte gingen auch:

1
mapfile -t stdin < /dev/stdin

Die Umleitung ist überflüssig, weil mapfile sowieso von Stdin liest. Das ist einfacher zu machen mit

1
mapfile -t stdin

Wobei stdin der Name der Variablen ist, die das Ergebnis aufsammelt. Die Variable wird aber immer als Array angelegt. Es klang nicht so, als ob das das ist, was Xpertus wollte.

Übrigens kann man solche mehrzeiligen Eingaben auch wunderbar mit einem Here-Doc übergeben:

1
2
3
4
5
6
7
8
$ cat <<'INPUT'
> Hallo
> zweite Zeile
> dritte Zeile
> INPUT
Hallo
zweite Zeile
dritte Zeile

Statt cat dann das Kommando / Script.

D630

Avatar von D630

Anmeldungsdatum:
24. Juli 2013

Beiträge: 329

rklm schrieb:

D630 schrieb:

1
2
3
while IFS= read -r
do
done

Das liest nur zeilenweise:

1
2
$ seq 1 5 | { IFS= read -r a; echo "$a"; }
1

Ich verstand, dass alle Zeilen zeilenweise eingelesen werden sollen.

Wenn man alles in einer Variable haben will, geht es so:

1
2
3
4
5
6
$ seq 1 5 | { read -rd '' a; echo "$a"; }
1
2
3
4
5

Ich glaub, alles in einer Variable ist nicht erwünscht. Warum denn seq? Es ist doch Bash angegeben; du benutzt ja auch -d.

Ich mag read -rd ''. Bei vielen Zeilen ist schneller:

1
printf '%s\n' {1..100} | { a=$(</dev/stdin); echo "$a"; }

Solche Konstrukte gingen auch:

1
mapfile -t stdin < /dev/stdin

Die Umleitung ist überflüssig, weil mapfile sowieso von Stdin liest. Das ist einfacher zu machen mit

1
mapfile -t stdin

Geschenkt

Wobei stdin der Name der Variablen ist, die das Ergebnis aufsammelt. Die Variable wird aber immer als Array angelegt. Es klang nicht so, als ob das das ist, was Xpertus wollte.

Bin ein Fan von Bandbreite aufzeigen.

Xpertus

(Themenstarter)

Anmeldungsdatum:
22. Juni 2016

Beiträge: 2

Hallo, und danke für die schnellen Antworten...

ich habe es jetzt so gelöst:

1
2
while IFS= read -r line; do text=$(echo "$text
$line"); done

So habe ich die Möglichkeit den kompletten Text weiterzuverarbeiten.

Ich danke vielmals...

Gruß, Xpertus

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13174

D630 schrieb:

rklm schrieb:

D630 schrieb:

1
2
3
while IFS= read -r
do
done

Das liest nur zeilenweise:

1
2
$ seq 1 5 | { IFS= read -r a; echo "$a"; }
1

Ich verstand, dass alle Zeilen zeilenweise eingelesen werden sollen.

Xpertus schrieb:

Das read erkennt nur eine Zeile. Wie bekommt man einen solchen Text komplett übergeben? zB Wie beim befehl "mail"

Ich hatte das so aufgefasst, dass alles am Stück bleiben soll, weil mail ja auch den Body einer Email am Stück weiter leitet.

Ich glaub, alles in einer Variable ist nicht erwünscht. Warum denn seq? Es ist doch Bash angegeben; du benutzt ja auch -d.

seq ist nur eine Quelle von mehreren Zeilen Text für das Beispiel.

Ich mag read -rd ''. Bei vielen Zeilen ist schneller:

1
printf '%s\n' {1..100} | { a=$(</dev/stdin); echo "$a"; }

Gemessen schneller? Oh ja!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$ seq 1 100000 | { time IFS= read -rd '' a; echo "$a" | wc -c; }

real    0m0.720s
user    0m0.093s
sys     0m0.624s
588896
$ seq 1 100000 | { time a="$(</dev/stdin)"; echo "$a" | wc -c; }

real    0m0.050s
user    0m0.015s
sys     0m0.046s
588895

Guter Hinweis! 👍

D630

Avatar von D630

Anmeldungsdatum:
24. Juli 2013

Beiträge: 329

rklm schrieb:

Gemessen schneller? Oh ja!

Mit ksh/mksh/zsh ist es nochmals wesentlich schneller

Antworten |