¿Cómo leer la entrada de mutlilina de stdin en variable y cómo imprimir una en shell(sh,bash)?
Lo que quiero hacer es lo siguiente: {[12]]}
- leer en entrada de línea múltiple desde
stdin
en variableA
- hacer varias operaciones en
A
- pipe
A
sin perder símbolos delimitadores(\n
,\r
,\t
,etc) a otro comando
El problema actual es que, no puedo leerlo con el comando read
, porque deja de leer en nueva línea.
Puedo leer stdin con cat
, así:
my_var=`cat /dev/stdin`
, pero entonces no se como para imprimirlo. Para que la nueva línea, la pestaña y otros delimitadores sigan ahí.
Mi script de ejemplo se ve así:
#!/usr/local/bin/bash
A=`cat /dev/stdin`
if [ ${#A} -eq 0 ]; then
exit 0
else
cat ${A} | /usr/local/sbin/nextcommand
fi
6 answers
Esto está funcionando para mí:
myvar=`cat`
echo "$myvar"
Las citas alrededor de $myvar
son importantes.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-01 09:15:53
En Bash, hay una forma alternativa; man bash
menciona:
El comando substitution
$(cat file)
puede ser reemplazado por el equivalente pero más rápido$(< file)
.
$ myVar=$(</dev/stdin)
hello
this is test
$ echo "$myVar"
hello
this is test
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-07 10:47:31
Tee hace el trabajo
#!/bin/bash
myVar=$(tee)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-27 09:33:47
Sí funciona para mí también. Gracias.
myvar=`cat`
Es lo mismo que
myvar=`cat /dev/stdin`
Bueno, sí. De la página de manual de bash
:
Encerrar caracteres entre comillas dobles conserva el valor literal de todos caracteres dentro de las comillas, con la excepción de$,',\, y, cuando la expansión de la historia es habilitado !. Los personajes and y ` conserve su significado especial entre comillas dobles.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-11 13:27:03
Si te importa conservar las nuevas líneas finales al final de la salida, usa esto:
myVar=$(cat; echo x)
myVar=${myVar%x}
printf %s "$myVar"
Esto usa el truco de aquí.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-09 07:01:01
[actualizado]
Esta asignación se colgará indefinidamente si no hay nada en la tubería...
var="$(< /dev/stdin)"
Podemos evitar esto haciendo un tiempo de espera read
para el primer carácter. Si se agota el tiempo, el código de retorno será mayor que 128 y sabremos que la tubería STDIN (también conocida como /dev/stdin
) está vacía.
De lo contrario, obtenemos el resto de STDIN por...
- estableciendo
IFS
a NULL solo para el comandoread
- desactivando los escapes con
-r
- eliminando el delimitador de lectura con
-d ''
. - y finalmente, añadiendo eso al carácter que obtuvimos inicialmente
Así...
__=""
_stdin=""
read -N1 -t1 __ && {
(( $? <= 128 )) && {
IFS= read -rd '' _stdin
_stdin="$__$_stdin"
}
}
Esta técnica evita usar var="$(command ...)"
Sustitución de comandos que, por diseño, siempre eliminará cualquier nueva línea final.
Si se prefiere la sustitución de comandos, para preservar las nuevas líneas finales podemos agregar uno o más caracteres delimitadores a la salida dentro del $()
y luego eliminarlos fuera.
Por ejemplo (nota $(parens)
en el primer comando y ${braces}
en el segundo )...
_stdin="$(awk '{print}; END {print "|||"}' /dev/stdin)"
_stdin="${_stdin%|||}"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-12-01 12:35:03