web-dev-qa-db-fra.com

Pourquoi le message d'erreur de deux points-virgule sous forme de commande (: :) in bash comporte-t-il trois points, mais un seul deux-points ne donne aucun résultat?

Si je tape

::

dans un shell bash, je reçois:

-bash: ::: command not found

Cependant, un seul : ne génère aucun résultat. Pourquoi est-ce?

27
NerdOfLinux

: Shell intégré vs non existant ::

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

bash-4.3$ type :
: is a Shell builtin

Cependant, :: - deux points ensemble - est interprété comme un "mot" pour le shell, et il s’agit d’une commande entrée par l’utilisateur. Le shell passera par le processus de vérification des éléments intégrés, puis par n'importe quel répertoire de la variable PATH pour vérifier l'existence de cette commande. Mais il n'y a ni :: intégré ni commande externe ::. Par conséquent, cela produit une erreur.

Eh bien, quel est le format typique d'une erreur?

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

Ainsi, ce que vous voyez n'est pas 3 points mais ce que vous avez tapé 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 de position. Cela ne produira également aucune erreur! (Voir aussi la note historique (plus loin dans cette réponse) sur l'utilisation du of : avec des paramètres de position.)


Dans des coquillages 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 /bin/sh par défaut d'Ubuntu (qui est en fait /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 se ferme avec le statut de sortie 0 (aucune erreur). Mais tcsh génère l'erreur (sans toutefois indiquer son nom):

$ 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 ::; le message d'erreur provient donc 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 génère un message d'erreur après les deux points, puis une nouvelle ligne. Citation:

La fonction perror () mappera le numéro d'erreur auquel on accède par le symbole errno avec un message d'erreur dépendant de la langue, qui sera écrit dans le flux d'erreur standard comme suit:

  • D'abord (si s n'est pas un pointeur nul et que le caractère pointé par s n'est pas un octet nul), la chaîne pointée par s est suivie de deux points et d'un <espace>.

  • Ensuite, une chaîne de message d'erreur suivie d'une <nouvelle ligne>.

Et l'argument de chaîne pour perror() pourrait techniquement être n'importe quoi, mais pour des raisons de clarté, il s'agit généralement du nom de la fonction ou de argv[0].

En revanche, GNU a son propre ensemble de fonctions et de variables pour la gestion des erreurs , qu’un programmeur peut utiliser avec le flux fprintf() to stderr. Comme l’a montré l’un des exemples de la page liée, on pourrait faire quelque chose comme ceci:

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

Note historique

: était utilisé avec instruction goto (qui selon l'utilisateur nommé Perderabo sur ce fil n'était pas un shell intégré). Citation du manuel:

Le fichier de commande complet est recherché pour une ligne commençant par: en tant que premier caractère non vide, suivi par un ou plusieurs espaces, puis par le libellé. Si une telle ligne est trouvée, goto repositionne le décalage du fichier de commandes sur la ligne après le libellé et se termine. Cela provoque le transfert du shell sur la ligne étiquetée.

Vous pouvez donc faire quelque chose comme ceci pour créer un script à boucle infinie:

: repeat
echo "Hello World"
goto repeat
40
Sergiy Kolodyazhnyy

Les deux derniers points font partie du message par défaut "introuvable":

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

La raison pour laquelle ( un seul point ne produit rien est que : est une commande valide - bien que cela ne fasse rien (sauf return TRUE). Dans 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é?

54
steeldriver

Essayez toute autre commande inexistante et vous verrez que le : remplit son objectif habituel en anglais:

$ ---
---: command not found
8
Olorin

Les deux points ajoutés font partie du message d'erreur même. Si l’on tape cd ow, il en résulte bash: cd: ow: No such file or directory, ce qui montre que l’erreur est en train de mettre des deux points supplémentaires : No such file or directory

6
John Orion
$ ::
bash: ::: command not found
$ kkkk
bash: kkkk: command not found

le 3ème est un spacer de formatage

in bash un : est une instruction vide de ligne vide

5
user688056

vous obtenez 3 points, car le format de l'erreur contient deux points:

bash: <command>: command not found
4
ravery