2011-04-22 20 views
8

Editar:¿El lado izquierdo de la tubería es la subescola?

Mi comentario más abajo con respecto sed '[email protected]^@ @' <(f1) es incorrecta Mientras $BASH_SUBSHELL indica que estamos en el mismo nivel que la puesta en marcha, las variables se pierden en el script principal. según la respuesta de Gordons Probé f1 > >(sed '[email protected]^@ @') y parece que funciona correctamente. Aún así, ¿BASH_SUBSHELL no debería ser 1 y no 0 para la primera forma?


considerar esta pequeña prueba

#!/bin/bash 
declare -i i=0 
function f1() 
{ 
    let i++ 
    echo "In f1, SUBSHELL: $BASH_SUBSHELL, i=$i" >&2 
} 

f1 
f1 | sed '[email protected]^@  @' 

echo "at end, i=$i" 

con el siguiente resultado:

In f1, SUBSHELL: 0, i=1 
In f1, SUBSHELL: 1, i=2 
at end, i=1 

(el propósito de la sed es sólo para tener una tubería a algo, no lo espera hacer cualquier cosa porque las salidas f1 a stderr)

La función f1 registra el BASH_SUBSH actual ELL y el valor actual de i

sé por qué al final de la secuencia de comandos que obtenemos i=1, es porque la segunda invocación estaba en un subnivel, y se perdió el valor de i en el subnivel 1.

Lo que no sé es por qué el lado izquierdo de la tubería no se ejecuta en el shell actual

Aunque me di cuenta de que podía evitar esto con sed '[email protected]^@ @' <(f1) me gustaría saber por qué el lado izquierdo es no en el mismo nivel que el script principal

+0

Creo que se permite que el caparazón tenga ambos extremos del tubo en la subcamada – sehe

+0

Un Google rápido encontró esto: http://www.linuxprogrammingblog.com/pipe-in-bash-can-be-a-trap –

+0

@ Brian ese artículo no discute el lado IZQUIERDO de la tubería ...Ya sé que son malas noticias para las asignaciones variables en el lado derecho de una tubería – nhed

Respuesta

12

del bash man page: "Cada comando en una canalización se ejecuta como un proceso separado (es decir, en una subcadena)." Supongo que sería posible ejecutar un componente de una tubería en el shell actual (es decir, el primero, o el último, o tal vez uno en el medio), no reproduce favoritos como este: todos ejecutan en subcapas . Si modifica la secuencia de comandos de esta manera:

#!/bin/bash 
declare -i i=0 
function f1() 
{ 
    let i++ 
    echo "In f1, SUBSHELL: $BASH_SUBSHELL, i=$i" >&2 
} 

f1 
f1 | f1 | f1 

echo "at end, i=$i" 

imprime:

In f1, SUBSHELL: 0, i=1 
In f1, SUBSHELL: 1, i=2 
In f1, SUBSHELL: 1, i=2 
In f1, SUBSHELL: 1, i=2 
at end, i=1 

porque todos los 3 invocaciones de F1 en la tubería de ejecución en subniveles.

+0

Supongo que mi confusión proviene de pensar que la redirección de tuberías y archivos es algo similar 'f1 nhed

+0

@nhed: No pensaría en una tubería como una redirección de salida. Una tubería es una serie de comandos unidos por redirecciones de E/S, y todos se ejecutan simultáneamente; dado que el shell no hace multitareas, puede ejecutar como máximo uno de ellos en el shell principal, y como son básicamente iguales, no hay razón para elegir uno para ejecutar en el shell principal, por lo que para ser justos, todos son ejecutar en subcapas. En bash, puede usar '< <()' and '>>()' para relegar explícitamente algunos de los comandos a subcapas, permitiendo que un comando se ejecute en el shell principal. –

+3

@nhed: (continuación) por ejemplo, para forzar que el primer comando en una canalización se ejecute en el shell principal, use 'cmd1>> (cmd2 | cmd3 | ...)'. Para ejecutar cmd2 en el shell principal, use 'cmd2 < <(cmd1) >> (cmd3 | ...)', etc. –

-1

Aquí está un ejemplo muy concisa, si alguien se preocupa:

cd/&& cd /tmp/ | pwd ; pwd 
/
/

O:

cd/&& cd /tmp/ | cd /var/ ; pwd 
/

Sí esta página lo dice todo

http://linux.die.net/man/1/bash# Cada comando en una tubería se ejecuta como una proceso separado (es decir, en una subcamada).

Cuestiones relacionadas