Y a-t-il des problèmes avec les tirets dans les fonctions, les alias et les exécutables?

25

Dans mes tests (dans Bash et Z Shell), je n'ai vu aucun problème avec la définition de fonctions ou d'alias ou de scripts de shell exécutables qui ont des tirets dans le nom, mais je ne suis pas sûr que ce sera correct dans tous les shells et dans tous les cas d'utilisation .

La raison pour laquelle je voudrais le faire est qu'un trait d'union est plus facile à taper qu'un trait de soulignement, et donc plus rapide et plus fluide.

Une raison pour laquelle j'hésite à croire que ce n'est pas un problème est que dans certaines langues (Ruby par exemple), le trait d'union serait interprété comme un signe moins même sans espaces autour. Cela ne me surprendrait pas si quelque chose comme cela pouvait se produire dans certains shells, où le trait d'union est interprété comme signalant une option même sans espace.

Une autre raison pour laquelle je suis un peu méfiant est que mon éditeur de texte bousille la coloration syntaxique des fonctions avec des tirets. (Mais bien sûr, il est tout à fait possible que ce soit juste un bogue dans sa configuration de coloration syntaxique pour les scripts shell.)

Y a-t-il une raison d'éviter les traits d'union?

iconoclaste
la source

Réponses:

32

POSIX et traits d'union: aucune garantie

Selon la norme POSIX, un nom de fonction doit être un nom valide et un nom peut être composé de:

3.231 Nom
Dans le langage de commande shell, un mot composé uniquement de traits de soulignement, de chiffres et d'alphabet du jeu de caractères portable. Le premier caractère d'un nom n'est pas un chiffre.

De plus, un alias doit être un nom d'alias valide , qui peut comprendre:

3.10 Nom d'alias
Dans le langage de commande shell, un mot composé uniquement de traits de soulignement, de chiffres et d'alphabétiques du jeu de caractères portable et de l'un des caractères suivants: '!', '%', ',', '@'.

Les implémentations peuvent autoriser d'autres caractères dans les noms d'alias en tant qu'extension. (Je souligne.)

Un tiret n'est pas répertorié parmi les caractères qui doivent être autorisés dans les deux cas. Donc, s'ils sont utilisés, la portabilité n'est pas garantie.

Exemples de coquilles qui ne prennent pas en charge les tirets

dashest le shell par défaut ( /bin/sh) de la famille debian-ubuntu et il ne prend pas en charge les tirets dans les noms de fonction:

$ a-b() { date; }
dash: 1: Syntax error: Bad function name

Chose intéressante, il prend en charge les tirets dans les alias, bien que, comme indiqué ci-dessus, il s'agit d'une caractéristique de mise en œuvre , pas d'une exigence:

$ a_b() { printf "hello %s\n" "$1"; }
$ alias a-b='a_b'
$ a-b world
hello world

Le shell busybox (shell Almquist) ne prend pas non plus en charge les tirets dans les noms de fonction:

$ a-b() { date; }
-sh: Syntax error: Bad function name

Résumé du support Hyphen par Shell

Les shells suivants sont connus pour prendre en charge les tirets dans les noms de fonction:

  • ksh, bash, zsh

Les shells suivants ne sont pas connus pour prendre en charge les tirets dans les noms de fonction:

  • frêne (busybox), csh, tcsh, dash

Conclusions

  • Les tirets ne sont pas standard. Éloignez-vous d'eux si vous souhaitez une compatibilité cross-shell.
  • Utilisez des tirets bas plutôt que des tirets: les tirets bas sont acceptés partout.
John1024
la source
2
Les noms avec -en eux sont mauvais. Je te regarde, CSS. :)
PM 2Ring
Merci. Je l' ai testé plus tard cshet tcshils ne supporte pas les traits d' union non plus , mais shell Korn fait. C'est un peu drôle que j'ai a-b()aussi utilisé comme nom de fonction.
iconoclaste
@iconoclast J'ai ajouté les résultats de vos tests shell à la réponse. Merci.
John1024
@ PM2Ring, ils sont plus faciles à taper que les noms avec des traits de soulignement. Excluant la tradition ou les décisions de mise en œuvre de systèmes qui ne les autorisent pas, sur quel principe pouvez-vous invoquer pour soutenir l'affirmation selon laquelle ils sont mauvais?
iconoclaste le
1
@iconoclast Les noms avec des tirets sont impossibles dans de nombreuses langues, car le trait d'union est interprété comme un signe moins, donc si une telle langue doit interagir avec une langue qui prend en charge les noms avec des tirets, vous obtenez la situation désordonnée où les entités avec des noms avec un trait d'union sont obligées de avoir un nom différent dans l'autre langue.
PM 2Ring
3

Je sais que c'est vraiment tard, mais vous pouvez peut-être contourner votre problème de rendre le soulignement plus accessible.

xmodmap -e "keycode  20 =  underscore minus"

Cela changera le trait de soulignement par un trait d'union (moins).

Alors maintenant, vous maintenez shift pour tiret, mais un trait de soulignement est tapé sans shift.

Votre code de touche peut être différent, cependant, je pense que cela dépend de votre clavier; le mien se trouve être 20. Faites-moi savoir si vous avez besoin d'aide pour trouver le code de clé que vous devez utiliser.

TuxForLife
la source