Estás confundiendo argumentos y entrada estándar. Canalizar datos a un programa no es equivalente a darle argumentos de línea de comando.
En su primer caso, no está pasando argumentos a su secuencia de comandos, solo alimentando datos a través de su flujo de entrada estándar. Así que $1
está desarmado durante toda la duración del script.
La primera invocación de more
por lo tanto, no tiene ningún parámetro y pagina la entrada estándar. Esto muestra lo que había canalizado allí (dir1
, como texto). El subsiguiente echo
solo imprime una nueva línea ya que no obtiene nada para imprimir, y el último more
tampoco tiene nada que imprimir:la entrada estándar ha sido "drenada" por la primera.
En el segundo caso, pasas un argumento. Entonces $1
tiene el valor dir2
en el guión. Sucede lo mismo, excepto que el primer more
ambos:
- páginas a través de ambas entradas estándar
- intenta paginar el archivo
dir2
y errores ya que es un directorio
El eco hace lo esperado dado que $1
contiene dir2
, y el último more
solo errores en dir2
- no tiene nada que leer de la entrada estándar.
La diferencia está en "Argumentos " VS "Entrada estándar ".
Cuando ejecutas echo dir1 | bash script.sh
, el $1
argumento en tu script.sh
siempre está vacío ya que no se le da ningún argumento (intente agregar un set -x
al principio y lo verá en la salida de depuración). El dir1
que se repite proviene de entrada estándar como el more
comando read stdin si no se proporciona ningún argumento (recuerde $1
está vacío).
Cómo cmd1 | cmd2
funciona
Al usar tubería:
cmd2
es un subproceso decmd1
.- la entrada estándar de
cmd2
está "tapado" en la salida estándar decmd1
.
Como linux stdio lib ofreció una transmisión en búfer a través del descriptor de archivo, el contenido de stdin se consumirá (es decir, se leerá solo una vez) solo cuando se abra stdin .
Paso a paso cmd1 | cmd2
flujo de trabajo
Comando de ejemplo:
echo dir1 | (echo "a" ; read stdinvalue; echo "$stdinvalue")
echo dir1 |
:escribe "dir1\n
" en la salida estándar del primer comando que no se repite sino que se almacena en búfer a través de stdio y está disponible para subprocesar a través de stdin.echo "a"
:escribe "a\n
" en stdout; no lee stdin ! entonces el "dir1\n
" la cadena todavía está disponibleread stdinvalue
:lee stdin hasta EOL (o EOF) y almacena la cadena en una variable bashecho "$stdinvalue"
:escribe el valor de la variable stdinvalue en stdout