La tubería asigna variable


19

Para simplificar, me gustaría hacer:

echo cart | assign spo;
echo $spo  

Salida: carro

¿Existe tal assignaplicación?

Soy consciente de todas las formas de hacer esto usando la sustitución.


¿Por qué quieres hacer esto sin sustitución?
— Thanatos

Me gusta el flujo de notación polaca inversa cuando escribo solo con pipas. Estoy codificando mucho más rápido y la calidad / velocidad de los códigos no es tan importante. También yo no Cuando se encadenan es hella más fácil para comentar partes de la cadena y el eco de la salida de corriente en lugar de borrar las garrapatas, etc
— MageProspero

Si le preocupa la facilidad de depuración, considere colocar el comando backticks en una serie de líneas separadas. A=$( some | command | here )con cada uno de some |, command |y hereen su propia línea.
— roaima

Respuestas:


11
echo cart | { IFS= read -r spo; printf '%s\n' "$spo"; }

Funcionaría (almacenar la salida de echosin el carácter de nueva línea final en la spovariable) siempre que echosolo salga una línea.

Siempre puedes hacer:

assign() {
  eval "$1=\$(cat; echo .); $1=\${$1%.}"
}
assign spo < <(echo cart)

Las siguientes soluciones funcionarían en bashscripts, pero no en el bashindicador:

shopt -s lastpipe
echo cat | assign spo

O:

shopt -s lastpipe
whatever | IFS= read -rd '' spo

Para almacenar la salida de whateverhasta los primeros caracteres NUL (las bashvariables no pueden almacenar caracteres NUL de todos modos) en $spo.

O:

shopt -s lastpipe
whatever | readarray -t spo

para almacenar la salida de whateveren la $spo matriz (una línea por elemento de matriz).


1
¿No debería haber un espacio entre IFS=y read?
— caesarsol

Todos granizan la última pipa. También se necesita un conjunto de notas al margen + m (ermmm o -m) desde una línea de comando, ya que la última tubería no funciona con el control de trabajo activo.
— MageProspero

17

Podría hacer algo como esto, si usa bash:

echo cart | while read spo; do echo $spo; done

Desafortunadamente, la variable "spo" no existirá fuera del ciclo while-do-done. Si puede hacer lo que quiere dentro del ciclo while, eso funcionará.

En realidad, puede hacer casi exactamente lo que escribió anteriormente en ATT ksh (no en pdksh o mksh) o en el fabuloso zsh:

% echo cart | read spo
% echo $spo
cart

Entonces, otra solución sería usar ksh o zsh.


1
Puede usar coprocesos en Korn Shell (por ejemplo mksh): echo cart |& while read -p spo; do echo $spo; done( while IFS= read -p -r spo; do…aunque en realidad es mejor usarlo )
— mirabilos

2

Si entiendo el problema correctamente, desea canalizar stdout a una variable. Al menos eso era lo que estaba buscando y terminé aquí. Entonces, para aquellos que comparten mi destino:

spa=$(echo cart)

Asigna carta la variable $spa.


2
Eso es lo que llaman sustitución, que el OP quería evitar.
— Dmitry Grigoryev

Esto fue útil para mí, solo necesitaba asignarlo a una variable, ¡no me importaba cómo llegó allí!
— Chris Marisic

1

Si solo desea generar el flujo de tubería actual, use cat.

echo cart | cat 

Si desea continuar su cadena de comandos, intente usar el teecomando para hacer eco de la salida.

echo cart | tee /dev/tty | xargs ls

Puede usar un alias para acortar el comando.

alias tout='tee /dev/tty'
echo cart | tout | xargs ls

¿Por qué querrías canalizar la salida a un plano cat?
— roaima

1
@roaima Algunos comandos reconocen que se están ejecutando en un terminal y se comportan de manera diferente que si se están enviando a una tubería. En particular, pueden truncar líneas al ancho de pantalla actual. Para la mayoría de los comandos, el comando cat es redundante.
— BillThor

Ah ok, ahora veo lo que intentabas ilustrar. La echo | catconstrucción me arrojó.
— roaima

1

Aquí está mi solución al problema.

# assign will take last line of stdout and create an environment variable from it
# notes: a.) we avoid functions so that we can write to the current environment
#        b.) aliases don't take arguments, but we write this so that the "argument" appears
#            behind the alias, making it appear as though it is taking one, which in turn
#            becomes an actual argument into the temporary script T2.
# example: echo hello world | assign x && echo %x outputs "hello world"
alias assign="tail -1|tee _T1>/dev/null&&printf \"export \\\$1=\$(cat _T1)\nrm _T*\">_T2&&. _T2"
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.