Vous confondez arguments et entrée standard. Transférer des données à un programme n'équivaut pas à lui donner des arguments de ligne de commande.
 Dans votre premier cas, vous ne transmettez aucun argument à votre script, vous ne lui fournissez que des données via son flux d'entrée standard. Donc $1 est désactivé pendant toute la durée du script. 
 La première invocation de more n'a donc pas de paramètre, et pagine l'entrée standard. Cela affiche ce que vous avez inséré (dir1 , sous forme de texte). Le echo suivant n'imprime qu'une nouvelle ligne car il n'obtient rien à imprimer, et le dernier more n'a plus rien à imprimer non plus - l'entrée standard a été "vidée" par la première.
 Dans le second cas, vous passez un argument. Alors $1 a la valeur dir2 dans le scénario. La même chose se produit, sauf que le premier more les deux :
- pages via les deux entrées standard
- tente de paginer le fichier dir2et les erreurs étant donné qu'il s'agit d'un répertoire
 L'écho fait ce qui est attendu étant donné que $1 contient dir2 , et le dernier more uniquement les erreurs sur dir2 - il n'a rien à lire à partir de l'entrée standard.
La différence est dans "Arguments " VS " Saisie standard ".
 Lorsque vous exécutez echo dir1 | bash script.sh , le $1 argumentation dans votre script.sh est toujours vide car aucun argument ne lui est donné (essayez d'ajouter un set -x au début et vous le verrez dans la sortie de débogage). Le dir1 dont l'écho provient de l'entrée standard comme le more la commande lit stdin si aucun argument n'est donné (rappelez-vous $1 est vide).
 Comment cmd1 | cmd2 fonctionne 
Lors de l'utilisation d'un tuyau :
- cmd2est un sous-processus de- cmd1.
- le stdin de cmd2est "branché" sur la sortie standard decmd1.
Comme linux stdio lib offrait un flux mis en mémoire tampon via le descripteur de fichier, le contenu stdin sera consommé (c'est-à-dire lu une seule fois) uniquement lorsque stdin sera ouvert .
 Pas à pas cmd1 | cmd2 flux de travail 
Exemple de commande :
echo dir1 | (echo "a" ; read stdinvalue; echo "$stdinvalue")
- echo dir1 |:écrire "- dir1\n" sur stdout de la première commande qui n'est pas renvoyée en écho mais mise en mémoire tampon via stdio et disponible pour sous-traiter via stdin.
- echo "a":écrire "- a\n" sur stdout ; ne lit pas stdin ! donc le "- dir1\n" la chaîne est toujours disponible
- read stdinvalue:lit stdin jusqu'à EOL (ou EOF) et stocke la chaîne dans une variable bash
- echo "$stdinvalue":écrit la valeur de la variable stdinvalue dans stdout