Ce que je veux faire est le suivant:
stdin
dans la variable A
A
A
sans perdre les symboles de délimitation (\n
, \r
, \t
, etc.) vers une autre commandeLe problème actuel est que je ne peux pas le lire avec la commande read
, car il arrête la lecture à la nouvelle ligne.
Je peux lire stdin avec cat
, comme ceci:
my_var=`cat /dev/stdin`
, mais je ne sais pas comment l'imprimer. Pour que la nouvelle ligne, l'onglet et les autres délimiteurs soient toujours là.
Mon exemple de script ressemble à ceci:
#!/usr/local/bin/bash
A=`cat /dev/stdin`
if [ ${#A} -eq 0 ]; then
exit 0
else
cat ${A} | /usr/local/sbin/nextcommand
fi
Cela fonctionne pour moi:
myvar=`cat`
echo "$myvar"
Les citations autour de $myvar
sont importants.
Dans Bash, il existe un autre moyen; man bash
Mentionne:
La substitution de commande
$(cat file)
peut être remplacée par l'équivalent mais plus rapide$(< file)
.
$ myVar=$(</dev/stdin)
hello
this is test
$ echo "$myVar"
hello
this is test
tee fait le travail
#!/bin/bash
myVar=$(tee)
Oui, ça marche aussi pour moi. Merci.
myvar=`cat`
est le même que
myvar=`cat /dev/stdin`
Hé bien oui. Depuis la page de manuel bash
:
L'insertion de caractères entre guillemets conserve la valeur littérale de tous les caractères entre guillemets, à l'exception de $, `,\et, lorsque l'expansion de l'historique est activée,!. Les caractères $ et `conservent leur signification particulière entre guillemets doubles.
Si vous vous souciez de conserver les sauts de ligne à la fin de la sortie, utilisez ceci:
myVar=$(cat; echo x)
myVar=${myVar%x}
printf %s "$myVar"
Cela utilise l'astuce de ici .
Cette affectation va se bloquer indéfiniment s'il n'y a rien dans le tuyau ...
var="$(< /dev/stdin)"
Nous pouvons cependant éviter cela en faisant un timeout read
pour le premier caractère. S'il expire, le code retour sera supérieur à 128 et nous saurons que le canal STDIN (a.k.a /dev/stdin
) Est vide.
Sinon, nous obtenons le reste de STDIN par ...
IFS
sur NULL uniquement pour la commande read
-r
-d ''
.Donc...
__=""
_stdin=""
read -N1 -t1 __ && {
(( $? <= 128 )) && {
IFS= read -rd '' _stdin
_stdin="$__$_stdin"
}
}
Cette technique évite d'utiliser la substitution de commandes var="$(command ...)"
qui, de par sa conception, supprimera toujours les nouvelles lignes de fin.
Si la substitution de commande est préférée, pour préserver les retours à la ligne de fin, nous pouvons ajouter un ou plusieurs caractères de délimitation à la sortie à l'intérieur de $()
, puis les supprimer à l'extérieur.
Par exemple (notez $(parens)
dans la première commande et ${braces}
Dans la seconde) ...
_stdin="$(awk '{print}; END {print "|||"}' /dev/stdin)"
_stdin="${_stdin%|||}"