Pourquoi le message d'erreur pour deux colons comme commande (: :) dans bash a-t-il trois virgules, mais un seul deux-points ne donne aucune sortie?

27

Si je tape

::

dans un shell bash, je reçois:

-bash: ::: command not found

Seulement un% : ne donne aucune sortie. Pourquoi est-ce que c'est?

    
posée NerdOfLinux 15.12.2017 - 02:18
la source

6 réponses

40

Intégré au shell : vs inexistant ::

La commande intégrée du shell " : " existe (notez le différence entre les commandes externes et les commandes intégrées ) qui ne fait rien; il renvoie simplement le succès, tout comme la commande true . La fonctionnalité intégrée : est standard et définie par la norme POSIX , où elle est également connue. comme "utilitaire nul". Il est fréquemment utilisé pour tester ou pour exécuter des boucles infinies comme dans while : ; do ...;done

bash-4.3$ type :
: is a shell builtin

Cependant, :: - deux caractères de deux points ensemble - sont interprétés comme un "mot" pour le shell, et suppose que l’utilisateur a saisi une commande. Le shell passe par le processus de vérification des composants intégrés, puis de tout répertoire dans la variable PATH pour l’existence de cette commande. Mais il n'y a ni :: ni commande externe :: . Par conséquent, cela produit une erreur.

Eh bien, quel est un format typique pour une erreur?

<shell>: <command user typed>: error message

Ainsi, ce que vous voyez n’est pas 3 points mais ce que vous avez tapé est collé dans le format d’erreur standard.

Notez également que : peut prendre des arguments en ligne de commande, c’est-à-dire qu’il est légal de le faire:

: :

Dans ce cas, le shell considérera cela comme deux "mots", l’un étant une commande et l’autre un paramètre positionnel. Cela ne produira également aucune erreur! (Voir aussi la note historique (plus loin dans cette réponse) sur l'utilisation de of : avec les paramètres de position.)

Dans les shells autres que bash

Notez que le formatage peut également varier d’un shell à l’autre. Pour bash , ksh et mksh , le comportement est cohérent. Par exemple, le shell par défaut /bin/sh d'Ubuntu (qui est en réalité /bin/dash ):

$ dash
$ ::
dash: 1: ::: not found

où 1 est le numéro de commande (équivalent au numéro de ligne dans un script).

csh en revanche ne produit aucun message d'erreur:

$ csh
% ::
%

En fait, si vous exécutez strace -o csh.trace csh -c :: , la sortie de trace dans le fichier csh.trace révèle que csh quitte avec le statut de sortie 0 (aucune erreur). Mais tcsh génère l'erreur (sans sortir son nom, cependant):

$ tcsh
localhost:~> ::
::: Command not found.

Messages d'erreur

En général, le premier élément du message d'erreur doit être le processus ou la fonction en cours d'exécution (votre shell tente d'exécuter :: , d'où le message d'erreur provenant du shell). Par exemple, ici, le processus d'exécution est stat :

$ stat noexist
stat: cannot stat 'noexist': No such file or directory

En fait, POSIX définit la fonction perror () qui, selon la documentation, prend un argument de chaîne, puis affiche un message d'erreur après les deux points, puis à nouveau. Citation:

  

La fonction perror () doit mapper le numéro d’erreur auquel on accède par le biais du symbole errno à un message d’erreur dépendant de la langue, qui doit être écrit dans le flux d’erreur standard comme suit:

     
  • Premièrement (si s n’est pas un pointeur nul et que le caractère pointé par s n’est pas l’octet nul), la chaîne pointée par s suivi de deux points et d’un space

  •   
  • Puis une chaîne de message d'erreur suivie d'un & lt; newline & gt;.

  •   

Et l'argument de chaîne à perror() techniquement pourrait être n'importe quoi, mais bien sûr, pour plus de clarté, c'est généralement le nom de la fonction ou argv[0] .

En revanche, GNU possède son propre ensemble de fonctions et de variables pour la gestion des erreurs , qu'un programmeur peut utiliser avec fprintf() à stderr stream. Comme un des exemples sur la page liée montre, quelque chose comme ceci pourrait être fait:

  fprintf (stderr, "%s: Couldn't open file %s; %s\n",
           program_invocation_short_name, name, strerror (errno));

Note historique

Dans les anciens shell Unix et Thompson, : était utilisé avec la déclaration goto (qui, selon l'utilisateur nommé Perderabo sur ce sujet n'était pas un shell intégré. Citation du manuel:

  

Le fichier de commande complet est recherché pour une ligne commençant par a: comme premier caractère non vierge, suivi d'un ou de plusieurs espaces, puis de l'étiquette. Si une telle ligne est trouvée, goto repositionne le décalage du fichier de commande sur la ligne après l'étiquette et quitte. Cela provoque le transfert du shell sur la ligne étiquetée.

Vous pouvez donc faire quelque chose comme ça pour créer un script de boucle infini:

: repeat
echo "Hello World"
goto repeat
    
réponse donnée Sergiy Kolodyazhnyy 15.12.2017 - 02:33
la source
54

Le dernier deux-points n'est qu'une partie du message par défaut "introuvable":

$ x
x: command not found
$ ::
::: command not found

La raison pour laquelle un deux-points single ne produit rien est que : est une commande valide - bien qu'il ne fasse rien (sauf return TRUE ). De la section SHELL BUILTIN COMMANDS de man bash :

   : [arguments]
          No effect; the command does nothing beyond  expanding  arguments
          and  performing any specified redirections.  A zero exit code is
          returned.

Vous le verrez parfois dans des constructions comme

while :
do
  something
done

Voir par exemple A quoi sert le colon intégré?

    
réponse donnée steeldriver 15.12.2017 - 02:30
la source
8

Essayez une autre commande inexistante et vous verrez que : remplit sa fonction normale en anglais:

$ ---
---: command not found
    
réponse donnée Olorin 15.12.2017 - 02:29
la source
6

Les deux points ajoutés font partie du message d'erreur lui-même. Si on tape cd ow , cela se traduit par bash: cd: ow: No such file or directory , ce qui montre que l'erreur ajoute les deux points supplémentaires : No such file or directory

    
réponse donnée John Orion 15.12.2017 - 02:31
la source
5
$ ::
bash: ::: command not found
$ kkkk
bash: kkkk: command not found

le 3ème est un espaceur de mise en forme

dans bash a : est une instruction vide de ligne vide

    
réponse donnée user688056 15.12.2017 - 02:30
la source
4

vous obtenez 3 colons car le format d’erreur contient un deux-points:

bash: <command>: command not found
    
réponse donnée ravery 15.12.2017 - 02:31
la source

Lire d'autres questions sur les étiquettes