GNU/Linux >> Tutoriels Linux >  >> Linux

Clarification concernant le comportement du script shell avec le tube

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 dir2 et 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 :

  1. cmd2 est un sous-processus de cmd1 .
  2. le stdin de cmd2 est "branché" sur la sortie standard de cmd1 .

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")

  1. 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.
  2. echo "a" :écrire "a\n " sur stdout ; ne lit pas stdin ! donc le "dir1\n " la chaîne est toujours disponible
  3. read stdinvalue :lit stdin jusqu'à EOL (ou EOF) et stocke la chaîne dans une variable bash
  4. echo "$stdinvalue" :écrit la valeur de la variable stdinvalue dans stdout

Linux
  1. Passer un nom de fichier avec des espaces à un script shell ?

  2. Le script se termine brusquement avec un message terminé ?

  3. Comportement inattendu d'un script shell ?

  4. Script Shell avec fonction et paramètre comme variables ?

  5. Automatisez mysql_secure_installation avec la commande echo via un script shell

Le script shell se bloque sur la commande de messagerie ?

Lire des valeurs dans une variable shell à partir d'un tube

Envoi de courrier HTML à l'aide d'un script shell

Changer le répertoire de travail dans le shell avec un script python

Vérifier la connectivité de la base de données à l'aide du script Shell

Bibliothèque de sortie de script shell coloré