Wie mehrzeilige Eingabe von stdin in Variable zu lesen und wie man aus in Shell (sh, bash) drucken?
Frage
Was ich tun möchte, ist die folgende:
- in mehrzeilige Eingabe von
stdin
in variableA
lesen - verschiedene Operationen auf
A
machen - Rohr
A
ohne Begrenzer Symbole zu verlieren (\n
,\r
,\t
, usw.) an einem anderen Befehl
Das aktuelle Problem ist, dass ich es nicht lesen kann mit read
Befehl in, weil es bei Newline Lesen stoppt.
Ich kann stdin mit cat
, wie diese lesen:
my_var=`cat /dev/stdin`
, aber dann weiß ich nicht, wie es zu drucken. Damit die Newline, Reiter und andere Begrenzungszeichen sind immer noch da.
Mein Beispielskript sieht wie folgt aus:
#!/usr/local/bin/bash
A=`cat /dev/stdin`
if [ ${#A} -eq 0 ]; then
exit 0
else
cat ${A} | /usr/local/sbin/nextcommand
fi
Lösung
Dies funktioniert für mich:
myvar=`cat`
echo "$myvar"
Die Anführungszeichen um $myvar
sind wichtig.
Andere Tipps
In Bash, gibt es eine Alternative Art und Weise; man bash
erwähnt:
Der Befehl Substitution
$(cat file)
kann durch die äquivalente aber schneller$(< file)
ersetzt werden.
$ myVar=$(</dev/stdin)
hello
this is test
$ echo "$myVar"
hello
this is test
T-Shirt macht den Job
#!/bin/bash
myVar=$(tee)
Ja, es funktioniert auch für mich. Danke.
myvar=`cat`
ist die gleiche wie
myvar=`cat /dev/stdin`
Nun ja. Von der bash
Manpage:
Enclosing Zeichen in doppelten Anführungszeichen bewahrt den wörtlichen Wert aller Zeichen innerhalb der Anführungszeichen, mit Ausnahme von $, `, \, und, wenn die Geschichte Expansion aktiviert, !. Die Zeichen $ und ` behalten ihre besondere Bedeutung in doppelten Anführungszeichen.
Wenn Sie interessieren sich über Hinterzeilenumbrüche am Ende der Ausgabe bewahren, verwenden Sie diese:
myVar=$(cat; echo x)
myVar=${myVar%x}
printf %s "$myVar"
Dies nutzt den Trick von hier .
[aktualisiert]
wird diese Zuordnung hängt auf unbestimmte Zeit, wenn es nichts in dem Rohr ist ...
var="$(< /dev/stdin)"
Wir können dies aber verhindern, indem ein Timeout read
für das erste Zeichen zu tun. Wenn es mal aus, wird der Return-Code größer als 128 und wir werden das STDIN Rohr wissen (a.k.a /dev/stdin
) leer ist.
Ansonsten bekommen wir den Rest von STDIN durch ...
-
IFS
auf NULL nur für denread
Befehl Einstellung - Ausschalten entkommt mit
-r
- Lesen der Begrenzer mit
-d ''
eliminiert wird. - und schließlich anhängt, dass wir auf den Charakter bekam zunächst
So ...
__=""
_stdin=""
read -N1 -t1 __ && {
(( $? <= 128 )) && {
IFS= read -rd '' _stdin
_stdin="$__$_stdin"
}
}
Diese Technik vermeidet var="$(command ...)"
Befehl Substitution verwendet, die durch Design, werden alle nachgestellten Zeilenumbrüche immer abzustreifen.
Wenn die Befehls Substitution bevorzugt wird, erhalten newlines Hinter wir ein anhängen oder mehrere Begrenzungszeichen an den Ausgang innerhalb des $()
und sie dann nach außen abzustreifen.
Zum Beispiel (Anmerkung $(parens)
in ersten Befehl und ${braces}
in Sekunden) ...
_stdin="$(awk '{print}; END {print "|||"}' /dev/stdin)"
_stdin="${_stdin%|||}"