~ est $ HOME, mais parfois?

14

cd ~

fait la même chose que

cd $HOME

qui est aussi le même que

cd /home/tandu

cependant,

cd ~not-tandu

modifications apportées à /home/not-tandu

Est-ce purement un choix syntaxique? Comment est-ce géré par le noyau (ou l' cdexécutable?) Y a-t-il un cas particulier pour ~ajouter la barre oblique si tout le reste est omis? C'est-à-dire, ~/et ~changez pour le même répertoire, mais ~ac'est un répertoire en haut. La même chose ne peut pas être dite pour tout autre répertoire dans lequel vous passez.

Pilules d'explosion
la source
3
N'hésitez pas à comparer ~ not-tandu et ~ / not-tandu, l'un pointe vers le répertoire utilisateur not-tandu home et l'autre pointe vers le répertoire not-tandu dans votre homedir.
Johan
4
Ce n'est pas le noyau ou "l'exécutable cd" (car il n'y a rien de tel) - c'est un shell intégré.
Paul Tomblin
Puisque vous ne le mentionnez pas: cdsans aucun paramètre fonctionne comme cd ~. Si vous remplacez cdpar, echovous pouvez voir à quoi l'expression est développée par le shell.
jofel

Réponses:

18

~est un alias $HOMEfourni par un certain nombre de shells, mais il $HOMEest plus universel. $HOMEdemande en fait au shell d'insérer (remplacer) la variable d'environnement HOME ici. Il existe un certain nombre de variables d'environnement différentes qui peuvent être substituées, essayez de lancer envune liste. Notez que ce ~n'est pas toujours reconnu quand ce n'est pas au début d'un mot. Essayez ces deux commandes pour la comparaison:

ls /~
ls /$HOME

Le premier est passé à l'exécutable ls en tant que /~qui essaie ensuite de regarder un fichier appelé ~dans le répertoire racine, le second se développe $HOMEet devient //home/userqui est ensuite passé à l'exécutable ls en tant qu'argument de ligne de commande. Tous les systèmes POSIX (POSIX est la norme pour le fonctionnement des systèmes UNIX et Linux) permettent à plusieurs barres obliques d'être traitées de la même manière qu'une seule barre oblique, ce qui //home/userrevient à dire /home/user. ~usernameest un raccourci pour dire au shell de rechercher le nom d'utilisateur dans le fichier passwd et de retourner son répertoire personnel. Il n'y a pas de variable d'environnement équivalente. Toutes ces substitutions sont effectuées par le shell et sont prises en charge par la plupart d'entre elles, mais seules les variables d'environnement comme $HOMEsont garanties d'être prises en charge par tous les shells. Aussi,cdest en fait une commande intégrée. C'est une directive spéciale qui indique au shell lui-même de changer de répertoire. Ce n'est pas comme les autres fonctions intégrées du shell qui peuvent être implémentées en tant qu'exécutable séparé, comme echoc'est le cas parce qu'il est utilisé pour changer un attribut fondamental du processus shell. echoest simplement un shell intégré pour des raisons de performances, mais au bon vieux temps d'UNIX, il n'était disponible que comme son propre exécutable /bin/echo.

pingouin359
la source
re "qui essaie ensuite de regarder un fichier appelé ~ dans le répertoire racine"; C'est pour toutes les saveurs Unix?
Pacerier
17

~foo signifie «le répertoire personnel de l'utilisateur foo».

Ce n'est pas fait par le noyau, c'est interprété par le shell. Chaque fois que le shell voit ~foocomme un argument, il le remplace de manière transparente par le répertoire personnel de l'utilisateur fooet le transmet à sa place. Ainsi, lorsque vous exécutez cd ~tandu, le shell est en cours d'exécution cd /home/tandu.

Patrick
la source
1
Que fait précisément ce remplacement et avec quel algorithme? Est-ce que c'est cdla coquille? Et si vous n'exécutez pas de shell? Est-ce un simple "si ~ est suivi de quelque chose, étendre différemment?" ou existe-t-il une autre manipulation spéciale pour cette condition unique?
Explosion Pills
8
Voir le manuel de Bash sur Tilde Expansion . (De nombreux autres obus et programmes suivent des règles similaires.)
cjm
4
@tandu: le shell fait cd, il n'y a pas d'exécutable externe pour le faire (ce ne serait pas possible)
Mat
1
@tandu: si vous n'exécutez pas de shell (par exemple en essayant cela en utilisant exec(2)), l'expansion du shell n'a pas lieu. Sans expansion du shell, ~il n'est remplacé par rien - c'est juste un autre personnage parfaitement valide. Cela m'a mordu à mes débuts avec SunOS parce /bin/shque je n'avais pas de problème ~.
Alexios
5

~ suivi d'un nom d'utilisateur se développe dans le répertoire personnel de cet utilisateur.

Ignacio Vazquez-Abrams
la source