Pourquoi tilde (~) ne se développe pas lorsqu'il est utilisé avec un argument CLI commençant par un tiret?

9

J'ai perdu quelques heures en essayant d'exécuter le serveur VNC (x0vncserver) et le client a refusé de se connecter avec un message étrange

No password configured for VNC Auth

Le serveur affiche également cette erreur

 SVncAuth:    opening password file '~/.vnc/passwd' failed

Ok, j'ai perdu beaucoup de temps jusqu'à ce que je réalise que le tilde n'était ni développé par le shell, ni par x0vncserver. Ensuite, j'ai exécuté ces tests

$ echo --PasswordFile=~/.vnc/passwd
--PasswordFile=~/.vnc/passwd

Mais

$ echo PasswordFile=~/.vnc/passwd
PasswordFile=/home/tichomir/.vnc/passwd

Pourquoi donc? Pourquoi le shell refuse de développer le tilde si l'argument commence par un tiret? Je pensais que le tilde se développerait toujours tant qu'il ne serait pas cité, mais apparemment il y a une autre règle qui entre en jeu?

Tihomir Mitkov
la source
Connexes: Expansion de tilde à zsh
Stéphane Chazelas
Voir aussi: Est
Stéphane Chazelas

Réponses:

13

C'est une particularité de la bashcoque décrite dans son manuel:

Bash effectue également l'expansion du tilde sur les mots satisfaisant aux conditions d'affectation des variables (comme décrit ci-dessus sous PARAMÈTRES) lorsqu'ils apparaissent comme arguments de commandes simples. Bash ne fait pas cela, sauf pour les commandes de déclaration listées ci-dessus, en mode posix.

Cela signifie que bash va développer le tilde dans votre PasswordFile=~/.vnc/passwdchaîne, car c'est un argument echoqui ressemble à une affectation de variable.

La chaîne --PasswordFile=~/.vnc/passwdne ressemble pas à une affectation de variable car la chaîne --PasswordFilen'est pas un nom de variable valide.

Notez que bashcela ne fait pas cela lors de l'exécution en mode POSIX, et que d'autres shells, comme zsh, kshou yashne le font pas par défaut ( zsha une magicequalsubstoption pour que l'expansion de tilde soit effectuée après des signes égaux ( =)).

Si vous voulez vous assurer que le chemin du répertoire personnel de l'utilisateur actuel est correctement développé dans le cadre d'un argument d'une commande, utilisez la $HOMEvaleur au lieu du tilde:

echo --PasswordFile="$HOME/.vnc/passwd"

Les « commandes de déclaration énumérées ci - dessus » mentionnées dans le manuel sont les commandes intégrées alias, declare, typeset, export, readonlyet local.

Kusalananda
la source
1
+1 | Je n'y penserais pas.
LinuxSecurityFreak
Remarque: bash --posix -c '"export" a=~; printf "%s\n" "$a"'sorties ~.
Stéphane Chazelas
2
Notez que le ~développement en alias a=~serait un bogue de conformité POSIX (et n'est pas utile). Mais c'est ainsi que ksh88 l'a fait (qui a changé dans ksh93) et c'est probablement pourquoi bash, zsh et pdksh le font aussi. Pourquoi yashce qui a été écrit contre la spécification POSIX ne le fait pas.
Stéphane Chazelas
C'est la bonne réponse, mais la bonne approche aurait été de simplement fournir l'argument option en tant qu'argument distinct, plutôt que de fusionner avec l'option using =en un seul argument. Ensuite, l'expansion tilde est au début d'un mot et la question est théorique.
JdeBP
1
@JdeBP, en l'occurrence, dans le cas de x0vncserver, x0vncserver --PasswordFile filene fonctionne pas, vous en avez besoin --PasswordFile=file.
Stéphane Chazelas