Sur mon serveur, j'ai une structure de répertoires ressemblant à ceci:
/myproject/code
J'ai normalement une connexion ssh au serveur et 'stand' dans ce répertoire:
root@machine:/myproject/code#
Lorsque je déploie une nouvelle version de mon code, le répertoire de code est supprimé, il me reste donc:
root@machine:/myproject/code# ./run
-bash: ./run: No such file or directory
Et la seule solution que j'ai trouvée est de sortir et de rentrer en cd:
root@machine:/myproject/code# cd ../code
root@machine:/myproject/code# ./run
Running...
Puis-je éviter cela? C'est un comportement quelque peu étrange. Si vous avez une belle explication pourquoi cela se produit, je l'apprécierais.
shell
command-line
directory
cd-command
Markus Johansson
la source
la source
run
est le même que l'ancien répertoire. Il n'a que le même nom et le même répertoire parent. Comparez cela à la destruction de votre ancienne voiture et à l'achat d'une nouvelle voiture de la même couleur et du même modèle: vous ne voudriez pas vous asseoir dans la voiture déchiquetée et espérer que vous vous retrouviez indemne avec la nouvelle, n'est-ce pas?cd ../code
n'est pas un noop...
est un raccourci pour le parent du chemin que vous avez ou avez utilisé. Si votre répertoire actuel est supprimé, le chemin parent peut toujours exister et, dans ce cas, être accessible en évaluant..
. Dans ce répertoire, une recherche est effectuée pour un répertoire avec le nom «code».Réponses:
Parce que les fichiers et les répertoires sont fondamentalement des inodes de système de fichiers , pas des noms - c'est peut-être un détail d'implémentation spécifique au type de système de fichiers, mais c'est vrai pour tous les systèmes ext, donc je m'en tiendrai ici.
Lorsqu'un nouveau répertoire
code
est créé, il est associé à un nouvel inode, et c'est là qu'il se trouve. Il n'y a aucun enregistrement des fichiers et répertoires précédemment supprimés, il n'y a donc aucun moyen par lequel le système pourrait vérifier quel inode il occupait et peut-être mélanger les choses pour qu'il en soit de même; un tel système deviendrait rapidement irréalisable, et en tout cas, il n'y a probablement aucune garantie que vous y retourniez - ce serait en quelque sorte indésirable, car cela signifie que vous pourriez également accidentellement vous retrouver ailleurs si un répertoire est créé qui prend votre inode (actuellement inutilisé).Je ne sais pas si cette dernière possibilité existe, ou si l'inode du répertoire supprimé actuellement affecté à votre répertoire de travail actuel est suivi afin que rien ne lui soit affecté pendant la durée, etc.
la source
Votre shell ne fait pas à chaque fois un
cd
chemin vers le chemin où il se trouvait lors de la dernière commande, avant d'exécuter la commande suivante.Vous avez supprimé le répertoire actuel et créé un répertoire avec le même nom, qui n'est pas le même répertoire, juste quelque chose avec le même nom / chemin.
Les navigateurs de fichiers comme Nautilus et l'Explorateur Windows "remontent" normalement l'arborescence des répertoires si un répertoire est supprimé sur un système de fichiers local. Cependant, ce n'est pas toujours le cas pour les systèmes de fichiers en réseau, dans ce cas, parfois, la suppression n'est pas remarquée et la réapparition pourrait vous faire vous retrouver dans le nouveau répertoire.
Un shell pourrait
cd
pénétrer dans le répertoire courant avant d'exécuter la commande suivante, je n'en connais aucun qui le fasse (ou peut être configuré pour le faire).la source
Sur la plupart des systèmes de type UNIX, le "répertoire courant" d'un processus est stocké dans le noyau en tant que descripteur de fichier pointant vers ce répertoire. Le noyau ne stocke pas réellement le chemin du répertoire courant: ces informations sont suivies par votre shell.
Un objet de système de fichiers (fichier ou répertoire) n'est détruit pour de bon que lorsque tous les liens du système de fichiers vers celui-ci ont disparu et qu'aucun descripteur de fichier ne pointe vers cet objet.
Donc, si un répertoire est supprimé alors qu'il y a encore un processus le tenant comme son répertoire de travail actuel, le processus
cwd
empêchera le répertoire d'être vraiment supprimé. Les liens du système de fichiers qui ancrent le répertoire (son entrée dans le répertoire parent et tout son contenu) auront disparu, mais le répertoire lui-même continuera d'exister comme une sorte de "zombie". Pendant ce temps, vous pouvez créer un tout nouveau répertoire au même emplacement que l'ancien, qui est un objet de système de fichiers complètement différent mais qui partage le même chemin.Ainsi, lorsque vous le faites
cd ../code
(ou, sur de nombreux shells,cd .
), vous parcourez en fait la hiérarchie du système de fichiers et accédez au nouveau répertoire qui réside à l'ancienne adresse.Par analogie, la suppression d'un répertoire reviendrait à déplacer de force une maison vers le dépotoir (rompre les liens avec l'adresse précédente). S'il y avait toujours quelqu'un là-bas (l'utilisant comme leur
cwd
), ils devraient partir avant que la maison ne soit rasée. En attendant, une maison neuve pourrait être construite à l'ancienne adresse.la source
@Anthon a expliqué les raisons pour lesquelles cela se produit.
Comme solution, vous pouvez utiliser un alias , par exemple:
les alias pour bash sont conservés dans ~ / .bashrc
la source
Confirmation Le répertoire de travail actuel EST basé sur le numéro d'inode, pas sur ce que vous avez recherché pour y arriver. Puisque vous utilisez bash, vous pouvez utiliser $ PWD comme suit pour accéder au nouveau répertoire du même nom:
cd $ PWD
Pour illustrer, j'ai fait une commande de déploiement factice:
Créé le premier déploiement, cd'd pour coder puis vérifié le contenu avec
ls -lai
afin que vous puissiez voir les inodes:Exécutez maintenant le 2e déploiement
Et vérifiez le contenu du répertoire ... maintenant il n'y a rien dans le répertoire! pas même '.' et '..'! De cela, vous pouvez voir que bash n'utilise pas l'entrée de répertoire «..» lorsque vous exécutez
cd ..
depuis que «..» n'existe plus - je suppose que sa partie de sa gestion de $ PWD. Certains autres / anciens shell ne gèrent pascd ..
dans cette situation, vous devez d'abord accéder à un chemin absolu.Cd
$PWD
et réessayez:Notez comment l'inode du répertoire actuel (.) A changé?
Si votre script de déploiement a déplacé l'ancien répertoire vers un autre nom, par exemple
mv code code.$$
dans le script de déploiement ci-dessus,./run
cela fonctionnerait, mais jusqu'à ce que vous l'utilisiez,cd $PWD
vous exécutez l' ancien code, pas le nouveau.Le déploiement à l'aide de capistrano a le même problème (ils ont un lien symbolique du nom actuel vers la version actuelle), donc j'utilise des alias pour cd vers les zones de production / mise en scène ainsi que pour définir RAIL_ENV de manière appropriée:
la source
Le chemin vers quelque chose est la façon dont vous y arrivez, pas la chose elle-même. Le chemin menant à votre lit peut être à travers votre chambre, mais une fois que vous êtes au lit, si quelqu'un le ramasse et le porte à l'extérieur, vous n'êtes plus dans votre chambre.
la source
Pas une réponse autonome, mais j'ai un point supplémentaire, que la marge de commentaires était trop petite pour contenir.
Pour avoir une meilleure idée de l'idée qu'un répertoire dans les systèmes de fichiers appropriés est plus qu'un simple chemin, essayez de déplacer le répertoire de travail actuel d'un autre processus: dans un shell, démarrez une session Python interactive:
Ensuite, allez dans un autre shell et déplacez ce répertoire:
Retour à l'original:
la source