En mi servidor tengo una estructura de directorio que se parece a esto:
/myproject/code
Normalmente tengo una conexión ssh con el servidor y 'soporte' en ese directorio:
root@machine:/myproject/code#
Cuando implemento una nueva versión de mi código, el directorio de códigos se elimina, por lo que me queda:
root@machine:/myproject/code# ./run
-bash: ./run: No such file or directory
Y la única solución que he encontrado es crear un CD y volver a ingresarlo:
root@machine:/myproject/code# cd ../code
root@machine:/myproject/code# ./run
Running...
¿Puedo evitar esto? Es un comportamiento algo extraño. Si tiene una buena explicación de por qué sucede esto, se lo agradecería.
shell
command-line
directory
cd-command
Markus Johansson
fuente
fuente
run
es el mismo que el directorio anterior. Solo tiene el mismo nombre y directorio principal. Compare esto con su trituración de su auto viejo y la compra de un auto nuevo del mismo color y modelo: no querría sentarse en el auto destrozado y esperar terminar en el nuevo ileso, ¿verdad?cd ../code
no es un noop...
es un acceso directo para el padre de la ruta que tiene o solía tener. Si se elimina su directorio actual, la ruta principal aún puede existir, y en este caso se puede llegar evaluando..
. En ese directorio se realiza una búsqueda de un directorio con el nombre 'código'.Respuestas:
Debido a que los archivos y directorios son fundamentalmente inodos de sistema de archivos , no nombres, este es quizás un detalle de implementación específico para el tipo de sistema de archivos, pero es cierto para todos los sistemas ext, así que me quedaré aquí.
Cuando se crea un nuevo directorio
code
, se asocia con un nuevo inodo, y ahí es donde está. No hay registros de archivos y directorios eliminados previamente, por lo que no hay ningún medio por el cual el sistema pueda verificar qué inodo solía ocupar y quizás barajar las cosas para que vuelva a ser lo mismo; dicho sistema se volvería rápidamente inviable y, en cualquier caso, probablemente no sea garantía de que volvería a estar allí de nuevo; eso sería algo indeseable, ya que significa que también podría terminar accidentalmente en otro lugar si se crea un directorio que toma su inodo (actualmente no utilizado).No estoy seguro de si existe esta última posibilidad, o si se realiza un seguimiento del inodo del directorio eliminado actualmente asignado a su directorio de trabajo actual para que no se le asigne nada durante el tiempo, etc.
fuente
Su shell no siempre hace una
cd
ruta a la que estaba durante el último comando, antes de ejecutar el siguiente comando.Eliminó el directorio actual y creó un directorio con el mismo nombre, que no es el mismo directorio, solo algo con el mismo nombre / ruta.
Los exploradores de archivos como Nautilus y Windows Explorer normalmente "suben" el árbol de directorios si un directorio se elimina en un sistema de archivos local. Sin embargo, esto no siempre es cierto para los sistemas de archivos en red, en ese caso, a veces, la eliminación no se nota y la reaparición podría hacer que termine en el nuevo directorio.
Un shell podría
cd
ingresar al directorio actual antes de ejecutar el siguiente comando, no conozco ninguno que lo haga (o que pueda configurarse para hacerlo).fuente
En la mayoría de los sistemas similares a UNIX, el "directorio actual" para un proceso se almacena en el núcleo como un descriptor de archivo que apunta a ese directorio. El núcleo en realidad no almacena la ruta del directorio actual: esa información es rastreada por su shell.
Un objeto del sistema de archivos (archivo o directorio) solo se destruye para siempre cuando todos los enlaces del sistema de archivos desaparecen, y no hay descriptores de archivos que apunten a ese objeto.
Entonces, si un directorio se elimina mientras todavía hay un proceso que lo mantiene como su directorio de trabajo actual, el proceso
cwd
evitará que el directorio se elimine realmente. Los enlaces del sistema de archivos que anclan el directorio (su entrada en el directorio principal y todos sus contenidos) desaparecerán, pero el directorio en sí mismo seguirá existiendo como una especie de "zombie". Mientras tanto, puede crear un nuevo directorio en la misma ubicación que el anterior, que es un objeto de sistema de archivos completamente diferente pero que comparte la misma ruta.Por lo tanto, cuando lo hace
cd ../code
(o, en muchos shellscd .
), en realidad está atravesando la jerarquía del sistema de archivos y yendo al nuevo directorio que reside en la dirección anterior.Por analogía, eliminar un directorio sería como mover a la fuerza una casa al basurero (romper vínculos con la dirección anterior). Si todavía hubiera alguien viviendo allí (usándolo como su
cwd
), tendrían que irse antes de que la casa pudiera ser arrasada. Mientras tanto, se podría construir una casa nueva en la dirección anterior.fuente
@Anthon aclaró las razones, por qué sucede
Como solución, puede usar un alias , como ejemplo:
los alias para bash se guardan en ~ / .bashrc
fuente
Confirmación El directorio de trabajo actual está basado en el número de inodo, no en lo que buscó para llegar allí. Como está usando bash, puede usar $ PWD de la siguiente manera para cd al nuevo directorio del mismo nombre:
cd $ PWD
Para ilustrar, hice un comando de despliegue ficticio:
Creé el primer despliegue, lo codifiqué y luego verifiqué el contenido
ls -lai
para que pueda ver los inodos:Ahora ejecuta el segundo despliegue
Y verifique el contenido del directorio ... ¡ahora no hay nada en el directorio! ni siquiera '.' y '..'! A partir de esto, puede ver que bash no está utilizando la entrada de directorio '..' cuando ejecuta
cd ..
ya que '...' ya no existe; supongo que es parte de su manejo $ PWD. Algunos otros / antiguos shell no se manejancd ..
en esta situación, primero debe cd a una ruta absoluta.Cd
$PWD
y vuelva a intentarlo:¿Observa cómo cambió el inodo para el directorio actual (.)?
Si la secuencia de comandos de despliegue se trasladó al antiguo directorio a algún otro nombre, por ejemplo,
mv code code.$$
en el, guión implementar arriba, entonces./run
funcionaría, pero hasta que utilicecd $PWD
que sería correr el viejo código, no el nuevo.La implementación con capistrano tiene el mismo problema (tienen un enlace simbólico desde el nombre actual hasta la versión actual), por lo que uso alias para cd a las áreas de producción / puesta en escena, así como establecer RAIL_ENV adecuadamente:
fuente
El camino hacia algo es cómo se llega allí, no la cosa en sí. El camino a su cama puede ser a través de su habitación, pero una vez que esté en la cama, si alguien lo levanta y lo lleva afuera, ya no estará en su habitación.
fuente
No es una respuesta independiente, pero tengo un punto adicional, que el margen de comentario era demasiado pequeño para contener.
Para tener una mejor idea de la idea de que un directorio en los sistemas de archivos relevantes es más que una ruta, intente mover el directorio de trabajo actual de otro proceso: en un shell, inicie una sesión interactiva de Python:
Luego, vaya a otro shell y mueva ese directorio:
De vuelta al original:
fuente