que signifient les tirets `-` avant les commandes` bash` on 'commande introuvable'?

28

Lorsque vous entrez une commande non valide à une invite bash, vous obtenez le message

-bash: {command}: command not found

Que signifie -au tout début?

Evan Purkhiser
la source
Comment exécutez-vous exactement la commande? J'ai essayé de reproduire, mais je n'obtiens pas les mêmes résultats - par exemple> jhgjbjbkjln: command not found- non -bash: là-dedans. Utilisez-vous bashsous Unix, Linux, OSX, ...? Je demande parce que c'est peut-être quelque chose qu'une implémentation spécifique met avant le message d'erreur par défaut, et cela ne veut rien dire ... peut-être.
jimm-cl
@jim Try ssh computernameet votre commande not count à répliquer.
Bernhard

Réponses:

27

Cela signifie qu'il s'agit d'un shell de connexion.

De man bash:

Un shell de connexion est un shell dont le premier caractère de l'argument zéro est un -, ou un commençant par l'option --login.

(En bashterminologie, l'argument "zeroth" est le nom de la commande qui, dans votre cas, était bash.) L' bashutilise comme signal pour effectuer des activités de connexion telles que l'exécution .bash_profile, etc.

Une façon d'ajouter le tiret automatiquement est si le shell est démarré avec exec. Du manuel Bash :

exec [-cl] [-a name] [command [arguments]]

[...] Si l' -loption est fournie, le shell place un tiret au début de l'argument zéro passé à la commande .

Exemple

Comparez ces deux tentatives pour exécuter la commande nonexistent. D'abord sans -l:

$ exec bash
$ nonexistent
bash: nonexistent: command not found

Et, deuxièmement, avec:

$ exec -l bash
$ nonexistent
-bash: nonexistent: command not found
John1024
la source
3
Je pense que la partie de la documentation que vous citez ne correspond pas à votre explication. Le fait d' exec -lajouter un tiret au début est un moyen possible qui peut entraîner l'exécution de bash -bash, mais cela ne signifie pas en soi qu'il s'agit d'un shell de connexion, et il y a de très bonnes chances que l'OP ne l'ait pas utilisé exec -ldu tout. . La partie de la documentation qui en -bashfait un shell de connexion est "INVOCATION Un shell de connexion est celui dont le premier caractère de l'argument zéro est un -, ou un a commencé avec l'option --login."
hvd
@hvd, d'accord. Bien que correcte, cette réponse manque le point.
Stéphane Chazelas
1
"L'argument zéro" n'est pas une bashterminologie, mais une convention Unix + une indexation C: chaque programme reçoit une liste de paramètres, dont l'entrée initiale est le nom du programme, suivi des arguments. Comme les tableaux C sont indexés en commençant par zéro, l'argument zéro (c'est-à-dire l'argument zéro) est le nom du programme et les arguments réels commencent par l'index 1.
celtschk
15

L'autre réponse est correcte dans la mesure où elle va, mais il convient de mentionner que la fonctionnalité est plus générale que bash.

Depuis les temps anciens, le loginprogramme a ajouté un tiret au argv[0]moment où il exécute le shell de l'utilisateur, et le shell a reconnu cela comme un signe qu'il devrait se comporter comme un "shell de connexion". Il est documenté dans les pages de manuel V7 ici: login (1) , sh (1) .

Tous les programmes qui fournissent un service de type connexion (authentifier un utilisateur et exécuter un shell) doivent suivre la règle du «tiret avant» Par exemple, sshd fait ce que vous pouvez voir dans ssh / session.c sous ce commentaire:

/*
 * If we have no command, execute the shell.  In this case, the shell
 * name to be passed in argv[0] is preceded by '-' to indicate that
 * this is a login shell.
 */

Tous les obus reconnaissent le tiret de tête. L' -loption équivalente n'existe pas dans le shell Bourne classique ou csh d'origine, mais la plupart des shells plus récents (bash, dash, ksh, yash, tcsh, zsh, rc, es, fish et toute version semi-récente de csh) l'ont.

Stéphane Chazelas
la source
2
Même si la plupart des obus ont maintenant l' -loption, loginne l'utilise toujours pas. Tous les shells devraient reconnaître le préfixe argv[0]comme mécanisme "officiel".
Barmar