web-dev-qa-db-fra.com

Est-ce que cd. avoir de l'utilisation?

L'un des didacticiels que j'ai suivis a brièvement indiqué que cd . n'a aucune utilité. En essayant de répliquer le problème montré par OP dans récursivité du lien symbolique - qu'est-ce qui le rend "réinitialisé"? , j'ai aussi essayé cd ., qui a montré le même effet que celui décrit par OP (croissance $PWD variable), qui peut être contrée par cd -P.

Cela me fait me demander, existe-t-il un cas où l'on voudrait en fait utiliser cd .?

102
Sergiy Kolodyazhnyy

Je pense que cela surpasse le problème. cd . n'est peut-être pas quelque chose que l'on exécuterait manuellement dans le cours normal des choses, mais c'est certainement quelque chose qui peut apparaître dans l'exécution programmatique (pensez à n'importe quelle situation où vous pourriez cd dans le répertoire contenant un fichier , dont le chemin est fourni par l'utilisateur). Par conséquent, il n'a pas besoin d'avoir une utilisation spécifique: tant qu'il remplit la sémantique habituelle de cd <some-path>, c'est utile.

157
Olorin

Le chemin du répertoire pourrait avoir changé depuis que la dernière commande a été exécutée, et sans cd . Les shells bash et ksh93 s'appuieront sur le répertoire de travail logique décrit dans le message lié dans la question, appelant donc cd ., ce qui fait que Shell émet le syscall getcwd() s'assurera que votre chemin actuel est toujours valide.

Étapes pour reproduire en bash:

  1. Dans un problème d'onglet de terminal mkdir ./dir_no_1; cd ./dir_no_1
  2. Dans un autre problème d'onglet de terminal mv dir_no_1 dir_no_2
  3. Dans le premier onglet du terminal, émettez echo $PWD Et pwd. Notez que le répertoire a été renommé en externe; l'environnement du Shell n'a pas été mis à jour.
  4. Émettez cd .; pwd; echo $PWD. Notez que la valeur a été mise à jour.

ksh93, cependant, ne met pas à jour les informations sur l'environnement, donc cd . dans ksh93 peut en fait être inutile. Dans /bin/dash Sur Ubuntu et d'autres systèmes basés sur Debian, cd . Renvoie l'erreur dash: 3: cd: can't cd to ., Cependant cd -P . Fonctionne (contrairement à ksh93).

127
Sergiy Kolodyazhnyy

Un autre cas d'utilisation de cd . serait lorsque le répertoire dans lequel vous vous trouvez actuellement a été supprimé puis reconstitué. Pensez à essayer ce qui suit -

  1. Créez un répertoire temp
  2. cd temp puis faites un ls
  3. Ouvrez un autre terminal et supprimez puis recréez ce répertoire temp
  4. De retour du premier terminal, essayez de faire un ls. Cela entraînerait une erreur - ls: cannot open directory .: Stale file handle
  5. cd . puis faire un ls fonctionne très bien
55
Sahil Agarwal

Vous pouvez effacer $OLDPWD avec un rapide cd ., s'il doit y avoir un cas où vous ne voulez pas qu'il pointe n'importe où "intéressant". Cela affectera également cd -.

36
nperson325681

Par programmation, il est utile comme no-op. Considérez un chemin fourni par une entrée externe.

read -p "Path to file: " p
dirn=$(dirname "$p")
file=$(basename "$p")
echo "dirn=$dirn, file=$file"
cd "$dirn"
ls -ld "$file"

Avec un chemin tel que "fred.txt", le répertoire deviendra ., menant à cd .

16
roaima

Cela est courant si vous devez travailler avec un mauvais câble USB. Une fois qu'un périphérique est déconnecté et reconnecté, puis monté automatiquement dans le même répertoire, vous devez utiliser cd . pour le faire fonctionner à nouveau.

15
user23013

Notez que "." c'est la bonne façon de spécifier le nom du fichier ouvert comme répertoire de travail courant de tout processus (y compris un processus Shell bien sûr), et "." est toujours un nom valide d'un fichier dans tous les répertoires, y compris le répertoire de travail actuel. Le nom . Peut ne pas être un nom valide pour un fichier pour une instance donnée d'un processus si, par exemple, le répertoire de travail actuel sous-jacent a été supprimé (ou est devenu "mauvais", par exemple un descripteur NFS périmé), mais c'est un nom valide d'un fichier qui est garanti d'exister dans chaque répertoire valide.

Donc . doit être un argument valide pour toute commande qui accepte le nom d'un répertoire, et donc dans le shell standard cd . Doit être une commande valide.

L'utilité de cd . Dépend de l'implémentation de Shell. Comme mentionné, il peut être utile si le shell réinitialise son idée interne du nom de chemin complet du répertoire de travail actuel après avoir appelé l'appel système chdir sous-jacent, par exemple si le répertoire sous-jacent (ou un parent de celui-ci) a été renommé.

Au moins certains shells que je connais (/bin/sh Sur FreeBSD et NetBSD) convertiront cd "" En cd ., Ce qui peut sans doute être décrit comme une fonctionnalité pour prendre en charge l'utilisation programmatique dans un script Shell où une variable peut être utilisée comme paramètre (c'est-à-dire convertir une substitution de variable vide en un résultat "ne rien faire"), bien que l'historique de validation de FreeBSD indique que le changement était directement dû à l'ajout de la prise en charge POSIX pour éviter un échec de chdir(""), que les mandats POSIX doivent échouer.

Certains autres shells remplaceront le . Par tout ce qu'ils ont stocké en tant que chemin d'accès complet dans leur répertoire de travail actuel, et donc pour eux, cela peut permettre le comportement mentionné dans Réponse de Sahil Agarwal .

11
Greg A. Woods

J'ai utilisé cette commande juste aujourd'hui lorsque j'ai rebasé la branche sur laquelle je travaillais dans Git, à partir d'un répertoire qui avait d'abord été créé sur cette même branche. Le rebase s'est bien passé mais après, git status a généré une erreur. Après cd . tout était normal.

(Je travaillais d'ailleurs dans MobaXterm sur Windows. Au cas où vous essayez de reproduire cela. Cela peut ne pas se produire sur d'autres systèmes.)


J'ai également utilisé cette commande dans des répertoires qui sont actualisés par un processus automatisé qui écarte l'ancien répertoire et le remplace par un nouveau (il est donc aussi proche de l'atomique que possible). Pas une situation courante mais cd . est exactement ce dont on a besoin.


Après avoir lu cette excellente réponse de Stéphane Chazelas:

Je comprends maintenant que mes cas d'utilisation ci-dessus ne fonctionnent que parce que j'utilise bash, dans lequel cd . est équivalent à cd "$PWD". Je recommande fortement de lire la réponse liée.

4
Wildcard

J'utilise cd . pour relancer le truc que j'ai surchargé cd avec via une fonction bash.

De mon ~/.bashrc:

# from the "xttitle(1)" man page - put info in window title
update_title()
{
    [[ $TERM = xterm ]] || [[ $TERM = xterm-color ]]  && xttitle "[$$] ${USER}@${HOSTNAME}:$PWD"
}

cd()
{
    [[ -z "$*" ]] && builtin cd $HOME
    [[ -n "$*" ]] && builtin cd "$*"
    update_title
}
1
waltinator

EDIT: Cela a déjà été suggéré par Sahil précédemment.

Ceci est utile si vous vous trouvez dans un dossier qui a été supprimé et recréé par un autre processus. Par exemple, en supposant que les deux sessions terminales $1 et $2:

$1 mkdir d
$1 cd d
$1 touch f

$2 rm -rf /path/to/d # delete the folder where $1 is in ...
$2 mkdir /path/to/d # ... and recreate it

$1 touch g # cannot create file g because current dir doesn't exist anymore
touch: cannot touch ‘g’: Stale file handle
$1 cd . # go to the newly created dir (same path)
$1 touch g # works fine now

Je ne sais pas exactement où (OS, Shell, ...?) La cause première de ce comportement est.

0
Rolf