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?
:
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.)
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.
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));
:
é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
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é?
Essayez toute autre commande inexistante et vous verrez que le :
remplit son objectif habituel en anglais:
$ ---
---: command not found
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
$ ::
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
vous obtenez 3 points, car le format de l'erreur contient deux points:
bash: <command>: command not found