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
dir2y 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:
cmd2es un subproceso decmd1.- la entrada estándar de
cmd2está "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