Wie mehrzeilige Eingabe von stdin in Variable zu lesen und wie man aus in Shell (sh, bash) drucken?

StackOverflow https://stackoverflow.com/questions/212965

  •  03-07-2019
  •  | 
  •  

Frage

Was ich tun möchte, ist die folgende:

  1. in mehrzeilige Eingabe von stdin in variable A lesen
  2. verschiedene Operationen auf A machen
  3. 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
War es hilfreich?

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 den read 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%|||}"
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top