web-dev-qa-db-fra.com

Différence entre "cd -" et "cd ~ -"

La commande Bash

cd - 

imprime le répertoire utilisé précédemment et le modifie.

Par contre, la commande Bash

cd ~-

passe directement au répertoire précédemment utilisé, sans faire écho à quoi que ce soit.

Est-ce la seule différence? Quel est le cas d'utilisation de chacune des commandes?

62
dr_

Il y a deux choses en jeu ici. Premièrement les - seul est développé dans votre répertoire précédent. Ceci est expliqué dans la section cd de man bash (c'est moi qui souligne):

Un argument de - est converti en $ OLDPWD avant que la modification du répertoire ne soit tentée. Si un nom de répertoire non vide de CDPATH est utilisé, ou si - est le premier argument, et le changement de répertoire est réussi, le chemin absolu du nouveau répertoire de travail est écrit dans la sortie standard. La valeur de retour est vraie si le répertoire a été changé avec succès; faux sinon.

Donc, un simple cd - vous ramènera à votre répertoire précédent et imprimera le nom du répertoire. L'autre commande est documentée dans la section "Tilde Expansion":

Si le préfixe tilde est un ~+, la valeur de la variable Shell PWD remplace le préfixe tilde. Si le préfixe tilde est un ~-, la valeur de la variable Shell OLDPWD, si elle est définie, est substituée. Si les caractères qui suivent le tilde dans le préfixe tilde sont constitués d'un nombre N, éventuellement préfixé par un + ou un -, le préfixe tilde est remplacé par l'élément correspondant de la pile de répertoires, car il serait affiché par le répertoire dirs appelé avec le préfixe tilde comme argument. Si les caractères qui suivent le tilde dans le préfixe tilde sont constitués d'un nombre sans _ + ou -, + est assumé.

Cela pourrait être plus facile à comprendre avec un exemple:

$ pwd
/home/terdon
$ cd ~/foo
$ pwd
/home/terdon/foo
$ cd /etc
$ pwd
/etc
$ echo ~        ## prints $HOME
/home/terdon
$ echo ~+       ## prints $PWD
/etc
$ echo ~-       ## prints $OLDPWD
/home/terdon/foo

Donc, en général, le - signifie "le répertoire précédent". Voilà pourquoi cd - à lui seul vous ramènera où que vous soyez.

La principale différence est que cd - est spécifique à la fonction intégrée cd. Si vous essayez de echo - il imprimera simplement un -. Le ~- fait partie de la fonctionnalité d'extension tilde et se comporte de la même manière qu'une variable. C'est pourquoi vous pouvez echo ~- et obtenir quelque chose de significatif. Vous pouvez également l'utiliser dans cd ~- mais vous pouvez aussi bien l'utiliser dans n'importe quelle autre commande. Par exemple cp ~-/* . qui serait équivalent à cp "$OLDPWD"/* .

86
terdon

~- est sujet à l'expansion du tilde (voir man bash), donc ce que cd voit est le nom du répertoire précédent directement. - n'est pas développé par le shell, cd le voit directement et se comporte comme documenté:

Un argument de - équivaut à $ OLDPWD. Si un nom de répertoire non vide de CDPATH est utilisé, ou si - est le premier argument et que le changement de répertoire réussit, le chemin d'accès absolu du nouveau répertoire de travail est écrit sur la sortie standard.

14
choroba

TL; DR: cd - est intégré à cd, ~- est une extension ultérieure de ~[name], non spécifique à cd.

POSIX.1-2008 Shell & Utilities définit cd - comme cas spécial spécifique pour la commande cd :

Lorsqu'un - est utilisé comme opérande, cela doit être équivalent à la commande:

cd "$OLDPWD" && pwd

qui passe au répertoire de travail précédent puis écrit son nom.

Le ~- l'extension sera étendue à $OLDPWD avant l'exécution de toute commande et peut être passé comme argument pour n'importe quelle commande, pas seulement cd. Il s'agit d'une extension ultérieure dans ksh et bash .

La norme POSIX.1-2008 Shell & Utilities susmentionnée a également ne explication détaillée de l'extension Tilde . Le libellé est très spécifique pour permettre ~- comme comportement non défini dans le domaine d'application de la norme, où ~[name] fait référence à $HOME si [name] est la chaîne vide ou le répertoire personnel de l'utilisateur name si name est un nom d'utilisateur valide.

5
Henk Langeveld