Est-ce que cd. avoir usage?

102

L'un des tutoriels que j'ai suivis a déclaré brièvement qu'il cd .ne sert à rien. Lorsque vous essayez de reproduire le problème indiqué par OP dans la récursion de lien symbolique, qu'est-ce qui le rend «réinitialisé»? , J’ai aussi essayé cd ., qui présentait le même effet décrit par OP ( $PWDvariable de croissance ), avec laquelle on peut contrer cd -P.

Cela me fait me demander s'il existe un cas où l'on voudrait utiliser cd . .

Sergiy Kolodyazhnyy
la source
20
J'ai un fichier .zshrc personnalisé qui exécute diverses vérifications sur le répertoire lors du changement de répertoire, par exemple, l'une des vérifications consiste à activer / désactiver automatiquement un virtualenv correspondant lors du déplacement de répertoires. De temps en temps, je peux démarrer un nouveau shell ou autre, et ces vérifications ne sont pas exécutées. J'utilise généralement cd .ces déclenchements parce qu'ils sont simples et brefs. Bien que je pense que vous vouliez que la question soit pour un environnement vanille.
Lie Ryan
29
Outre l'effet (évident) sur $PWD, cd .modifie également $OLDPWDle répertoire en cours. Je n'ai (actuellement) aucune idée du pourquoi cela pourrait être utile, mais dans un souci de complétude…
Andreas Wiese
5
Je ne pense pas en avoir jamais eu besoin cd ., même si je trouvais les réponses ci-dessous, je le ferais peut- être à l'avenir, mais je l'ai parfois utilisé pushd .lorsque je voulais pouvoir popdrevenir à ce répertoire ultérieurement. par exemple, lorsque vous exécutez un script de construction configure, cd output...et make, et lorsque c'est terminé, je souhaite revenir au répertoire d'origine. Plutôt que de conserver ma propre copie du buildscript qui diffère de ce à quoi tout le monde s’attend, je le lance simplement pushd .; ./BuildScriptName.sh; popd, et cela me donne également la liberté de ne pas le faire popdparfois, et popdplus tard à la place.
3D1T0R
5
Sans parler bien sûr que '.' et '..' ne sont pas implémentés dans la commande cd elle-même, donc personne ne souhaite créer cette fonctionnalité spécifique, c'est simplement une combinaison de choses qui ne sert à rien.
David S
1
@ruakh Nope, les programmes externes ne doivent pas affecter l'environnement d'exécution du shell. C'est principalement pour la conformité POSIX qui nécessite que certains utilitaires existent en dehors du shell et pour évaluer l'état de sortie des commandes externes. Vous pouvez lire sur le but /bin/cdici unix.stackexchange.com/q/50058/85039
Sergiy Kolodyazhnyy

Réponses:

158

Je pense que c'est trop penser le problème. cd .Ce n'est peut-être pas quelque chose que l'on pourrait exécuter manuellement dans le cours normal des choses, mais c'est certainement quelque chose qui peut arriver lors d'une exécution programmatique (pensez à toute situation où vous pourriez accéder cdau répertoire contenant un fichier, dont le chemin est fourni par l'utilisateur ). Par conséquent, il n’est pas nécessaire qu’il ait une utilisation spécifique: tant qu’il remplit la sémantique habituelle de cd <some-path>, il est utile.

Olorin
la source
12
Convenu, .devrait être traité comme un chemin valide spécifié par la cdsyntaxe.
Sergiy Kolodyazhnyy
18
Vous pouvez ajouter l'exemple suivant: Loops like while IFS= read Dir; do cd "$Dir"; do_something; done < <(find . -type d). Au cours de son parcours, find produit .comme chemin, de sorte que la commande se cd "$Dir"développe en cd .. Donc, dans les scripts, c'est parfaitement utile.
rexkogitans
5
Par exemple, un script est exécuté cd ${path_to_directory}, mais à un moment donné, le répertoire est le répertoire actuel path_to_directory = .. Vous devrez cd .donc travailler au cas où.
Demis
4
En d'autres termes, son utilité réside dans le fait qu'il rend inutile tout code supplémentaire ( ifcontrôles et elseclauses, tout type de casse spéciale).
jpmc26 le
2
Donc c'est utile dans le sens où x + 0 ou x * 1 sont utiles - l'opération spécifique n'est pas utile en soi, mais cela signifie que vous pouvez gérer 0 et 1 comme n'importe quelle autre valeur, sans avoir à les traiter comme un cas particulier.
user32929
127

Le chemin du répertoire pourrait avoir changé depuis l'exécution de la dernière commande. Sans cd .les shells bash et ksh93, le répertoire de travail logique décrit dans l'article lié à la question est appelé. L'appel cd .qui getcwd()provoque le shell à appeler le syscall assurera votre Le chemin actuel est toujours valide.

Les étapes pour reproduire en bash:

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

Cependant, ksh93 ne met pas à jour les informations sur l'environnement. Par conséquent, cd .ksh93 peut en fait être inutile. Sur /bin/dashles systèmes Ubuntu et autres systèmes basés sur Debian, cd .renvoie une dash: 3: cd: can't cd to .erreur, mais cd -P .fonctionne (contrairement à ksh93).

Sergiy Kolodyazhnyy
la source
22
Bon à savoir: j'ajouterai cela à ma liste d'informations inutiles. ^^)
Jayooin
12
@jayooin Glad je pourrais contribuer à la liste;)
Sergiy Kolodyazhnyy
8
Je pense que vous pouvez faire mv ../dir_no_1 ../dir_no_2dans le même terminal / bash.
ctrl-alt-delor le
3
@ ctrl-alt-delor Confirmé, fonctionne :)
Sergiy Kolodyazhnyy
1
@ymbirtt Dans la plupart des shells, il pwds'agit en fait d'un composant intégré, mais l'appel /bin/pwdn'a aucun effet sur l'environnement du shell - les utilitaires externes en général n'affectent pas l'environnement du shell. La raison pour laquelle /bin/cdet /bin/pwdexistent est entre autres pour la conformité à POSIX. Il y a une bonne discussion sur le cd externe dont certains s'appliquent probablement /bin/pwdaussi
Sergiy Kolodyazhnyy
55

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

  1. Créer un répertoire temp
  2. cd temp et ensuite faire un ls
  3. Ouvrir un autre terminal et supprimer puis recréer 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 l fonctionne bien
Sahil Agarwal
la source
3
Cela ne marche pas toujours. En tiret, par exemple, vous obtiendrez: cd: can't cd to .Maintenant que je regarde cela, cela est déjà mentionné dans la réponse de Sergiy (déplacer, supprimer / recréer - en gros le même: le répertoire dans lequel vous vous trouvez n’est plus ce qui était dans l’original chemin)
Olorin
12
J'utilise beaucoup de tests de déploiement à distance. Le répertoire dans lequel je me trouve sera supprimé, puis recréé par une automatisation. Je devrai le publier cd .pour pouvoir accéder au nouveau répertoire portant le même nom.
HP Williams
2
J'utilise cd .tout le temps quand j'ai un shell dont le répertoire de travail actuel a été monté avec sshfs mais que la session ssh a été fermée et rouverte.
jamesdlin
4
Dans un tel cas, je fais "cd $ PWD". D'autres variantes peuvent fonctionner, mais celle-ci exprime clairement l'intention: extrayez ce qui est supposé être mon chemin actuel (c'est-à-dire le contenu de PWDla variable d'environnement), puis déplacez la hiérarchie du système de fichiers de la racine vers un répertoire accessible par l'intermédiaire de ce chemin, que ce soit en fait le même répertoire ou non. Cela correspond exactement au cas d'utilisation de cette réponse.
Stéphane Gourichon le
3
Je suis vraiment surpris, même choqué, que cela cd .fonctionne lorsque le répertoire a été dissocié et qu'un nouveau répertoire différent est créé sur le même chemin de système de fichiers. Le répertoire de travail actuel a été dissociées et vraisemblablement dans le cadre de cela, il n'a plus une .ou l' ..entrée, et même si elle l'a fait, l' .entrée devrait continuer à pointer vers lui - même. Il semble que le shell ou le noyau exécute la commande cd en fonction du nom du chemin de répertoire plutôt que d'accéder simplement à l' .entrée. Quelqu'un peut-il confirmer ce comportement?
Adrian Pronk le
36

Vous pouvez effacer $OLDPWDen un rapide cd ., s'il devait y avoir un cas où vous ne voulez pas qu'il pointe n'importe où "intéressant". Ça va aussi affecter cd -.

unperson325680
la source
16

Par programme, c'est utile en tant que non-op. Considérons un chemin fourni à partir d'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 ., conduisant àcd .

Roaima
la source
1
Il est utile que cela ne génère pas d'erreur si vous êtes déjà dans le répertoire dans lequel vous naviguez, mais je ne dirais pas que c'est utile en tant que non-op.
Captain Man
2
@CaptainMan ne pas lancer d'erreur si vous êtes déjà dans le répertoire est (en fait) un no-op. La dirnamecommande est générée .si nécessaire pour éviter de déchiffrer le code qui devrait permettre de fractionner un chemin.
Roaima
15

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

utilisateur23013
la source
1
Cela ne dépend-il pas du type de périphérique, de la manière dont on y accède, de son système de fichiers, du système d'exploitation, etc.?
étourdissements
OS, peut-être. Il est peu probable que le système de fichiers soit pertinent, tant que le noyau peut trouver son chemin pour le démonter pendant son utilisation. Dans tous les cas, la commande peut être utilisée dans la bonne situation.
user23013
11

Notez que "." est le moyen approprié de spécifier le nom du fichier ouvert en tant que répertoire de travail actuel de tout processus (y compris un processus shell), et "." est toujours un nom valide de fichier dans tous les répertoires, y compris le répertoire de travail en cours. 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 devenu "incorrect", par exemple un descripteur NFS obsolète), mais s'il s'agit d'un nom valide. d'un fichier dont l'existence est garantie 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.

Que cela cd .soit utile ou non dépend de l'implémentation du shell. Comme indiqué, il peut être utile que le shell réinitialise sa conception interne du nom de chemin complet du répertoire de travail actuel après l'appel de l' chdirappel système sous-jacent , par exemple si le répertoire sous-jacent (ou un de ses parents) a été renommé.

Au moins quelques obus que je connais ( /bin/shsur FreeBSD et NetBSD) convertira cd ""en cd ., qui peut sans doute être décrit une fonctionnalité permettant de soutenir l' utilisation programmatique dans un script shell où une variable peut être utilisée comme paramètre (ie la conversion d' une substitution de variable vide en un " ne faites rien "en conséquence), bien que l'historique des mises à jour de FreeBSD indique que la modification est directement due à l'ajout du support POSIX pour empêcher une défaillance chdir(""), ce que les mandats POSIX doivent échouer.

Certains autres shells remplaceront .par ce qu'ils ont stocké en tant que chemin d'accès complet à leur répertoire de travail actuel. Cela peut donc permettre le comportement mentionné dans la réponse de Sahil Agarwal .

Greg A. Woods
la source
4

J'utilisais cette commande aujourd'hui même lorsque je rebasais la branche sur laquelle je travaillais dans Git, à partir d'un répertoire qui avait été créé sur cette même branche. Le rebase s'est bien passé, mais a ensuite git statuslancé une erreur. Après cd .tout était normal.

(Je travaillais d'ailleurs dans MobaXterm sous Windows. Juste au cas où vous essayez de reproduire cela. Cela ne se produira peut-être pas sur d'autres systèmes.)


J'ai également utilisé cette commande dans des répertoires actualisés par un processus automatisé qui déplace l'ancien répertoire et le remplace par un nouveau (il est donc aussi proche que possible de l'atomique). Pas une situation commune, mais cd .c'est exactement ce qui est nécessaire.


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, ce qui cd .équivaut à cd "$PWD". Je recommande fortement de lire la réponse liée.

Wildcard
la source
1

J'avais l' cd .habitude de relancer les choses que j'avais surchargées cdvia une bashfonction.

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
}
Waltinator
la source
0

EDIT: Cela a déjà été suggéré par Sahil auparavant.

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 de terminal $1et $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 suis pas sûr que la cause fondamentale de ce comportement soit où (OS, SHELL, ...?).

Rolf
la source
Cela a déjà été mentionné par d'autres réponses.
Kusalananda
-8

Non, ça n'a aucun sens. Ni dans le script, il ne fait rien.

Federico
la source
2
Selon le shell, il serait réinitialisé $PWDet il pourrait éventuellement appeler d'autres fonctions du shell si l'utilisateur avait fourni sa propre cdfonction ou son alias pour surcharger le programme intégré cd. Cela vérifierait également que le répertoire actuel est toujours valide et que l'utilisation actuelle est autorisée à s'y trouver.
Kusalananda
1) bien sûr, nous ne parlons pas d’éventuels alias personnalisés de "cd" mais de la version standard 2) comment l’utilisation actuelle peut-elle être présente si elle n’a pas la permission? Pour faire simple, je dis simplement que dans le monde réel, il n’ya aucune raison de l’utiliser à mon avis.
Federico
1
1) n'est-ce pas? 2) Le monde réel n’est pas simple et Unix est un système d’exploitation multi-utilisateurs. Un utilisateur peut modifier les autorisations sur les répertoires et si le script, ou le shell interactif d'un autre utilisateur, se trouve avoir ce répertoire (ou l'un de ses sous-répertoires) comme répertoire de travail, cd .se plaindre.
Kusalananda
4
Federico, selon les règles du site et mes propres règles personnelles, je devrais avoir votre réponse. Cependant, vous êtes nouveau. Bienvenue! Veuillez examiner certaines des autres réponses . Après cela, si vous pensez que votre réponse est fausse, supprimez-la. S'il vous plaît profiter de donner d'autres réponses à cette question et d'autres.
daveloyall
2
Surtout dans les scripts, parfois "ne fait rien" est exactement ce qu'il faut.
Matthew Najmon le