Al mover el directorio actual aparece "mv: no se puede mover `.' a `../dir/.': Dispositivo o recurso ocupado"

Al mover el directorio actual aparece "mv: no se puede mover `.' a `../dir/.': Dispositivo o recurso ocupado"
$ mv . ../general/
mv: cannot move `.' to `../general/.': Device or resource busy

¿Significa que el directorio actual es un dispositivo o recurso ocupado y no se puede mover? ¿Por qué es así?

Respuesta1

No puede mover el directorio en el que se encuentra actualmente. El proceso actual es el que lo mantiene ocupado.

En su lugar, suba un nivel y nombre el directorio anteriormente actual para moverlo al destino.

Respuesta2

No es posible mover un punto .. El punto no es lo mismo que el nombre del directorio actual. Puede pensar en .un puntero al directorio, pero no en el directorio en sí, por lo tanto,

$ pwd && echo $PWD && realpath .
/home/jimmij/tmp
/home/jimmij/tmp
/home/jimmij/tmp
$ mkdir tmp1 tmp2
$ mv tmp1/. tmp2/
mv: cannot move ‘tmp1/.’ to ‘tmp2/.’: Device or resource busy

no funciona, pero

cd tmp1
mv ../tmp1 ../tmp2

funciona bien, así que en realidadpodermover el directorio actual, aunque algunos comandos pueden confundirse después de esta operación:

$ pwd && echo $PWD && realpath .
/home/jimmij/tmp/tmp1
/home/jimmij/tmp/tmp1
/home/jimmij/tmp/tmp2/tmp1
$ cd .
$ pwd && echo $PWD && realpath .
/home/jimmij/tmp/tmp2/tmp1
/home/jimmij/tmp/tmp2/tmp1
/home/jimmij/tmp/tmp2/tmp1

Historia similar con .., es decir, directorio principal.

En otras palabras, cada directorio debe contener al menos dos elementos: .y ... No puedes moverlos ni eliminarlos.

Respuesta3

La razón por la que recibes el mensaje:

mv: no se puede mover .' to../general/.': Dispositivo o recurso ocupado

se debe a cómo funcionan ., y ..además de mv. Cuando mueves algo en Unix, el mvcomando intenta desvincular todo lo que hace referencia al inodo del elemento que estás intentando mover. En este caso, ese sería el inodo de cualquier directorio al que .se haga referencia.

Los "símbolos/enlaces" .y ..están vinculados a inodos y son, en cierto sentido, especiales. Puede leer sobre su historia aquí en las preguntas y respuestas de U&L tituladas:¿Por qué un nuevo directorio tiene un número de enlaces físicos de 2 antes de que se le agregue algo?Si alguna vez ha mirado un directorio recién creado, notará que siempre comienza con un recuento de enlaces de 2. La razón se debe a la existencia de .y ...

$ mkdir adir

$ ls -l | grep adir
drwxrwxr-x. 2 saml saml 4096 Oct  5 08:02 adir

$ ls -la adir/
total 8
drwxrwxr-x. 2 saml saml 4096 Oct  5 08:02 .
drwxrwxr-x. 3 saml saml 4096 Oct  5 08:02 ..

NOTA:La referencia para lsel resultado si no está claro está aquí en estas preguntas y respuestas de U&L titulada:¿Qué significan los campos en la salida ls -al?

Por lo tanto, no son nombres de directorios reales, sino "símbolos/enlaces" que enlazan con ellos. Por lo tanto es necesario desvincularlos antes de poder hacerlo mv.

Bueno, dado que su comando utiliza ., el comando no puede desvincularlo mv, de ahí el mensaje: "Dispositivo o recurso ocupado".

Referencias

Respuesta4

Linux prohíbe cambiar el nombre de cualquier ruta que termine en el componente .o .., devolviendo el error EBUSY; lo siguiente también fallará:

$ mkdir a a/aa
$ mv a/aa/.. b
mv: cannot move ‘a/aa/..’ to ‘b/..’: Device or resource busy

El código para esto está en namei.c::renameat. El último componente de la ruta cuando se pasa a varias funciones debe ser de tipo LAST_NORM, no LAST_DOTo LAST_DOTDOT.

FreeBSD devuelve el error EINVAL en cada uno de estos casos.


Sólo podemos adivinar por qué existe esta restricción.

La función rename() fallará si:
...
[EBUSY] El directorio nombrado por antiguo o nuevo está actualmente en uso por el sistema u otro proceso, y la implementación lo considera un error.

Se podría considerar .que actualmente está en uso por el proceso. Pero tenga en cuenta que Linux permite lo siguiente, por lo que un directorio que simplemente esté siendo utilizado por algún proceso no es suficiente para renameque falle:

$ mkdir /tmp/t
$ cd /tmp/t
$ mv /tmp/t /tmp/t1
$ /bin/pwd
/tmp/t1

La razón para prohibir el cambio de nombre de .y ..es probablemente "conduce a una menor confusión del usuario".

  • .Generalmente es un enlace físico a la entrada del directorio en su padre, y es algo especial porque un proceso siempre puede abrirse .para acceder a su directorio de trabajo actual. Poder cambiarle el nombre sería contraproducente.
  • ..Normalmente es un enlace físico al directorio principal y es algo especial porque al abrir un proceso ..se obtendrá el directorio principal (o el directorio mismo, si es un punto de montaje). Poder cambiarle el nombre sería contraproducente.

Linux también prohíbe rmdiruna ruta cuyo último componente sea ..(ENOTEMPTY) o .(EINVAL). FreeBSD devuelve el error EINVAL para cada uno de estos. ElEstándar POSIX para rmdirtiene esto:

La función rmdir() fallará si:
...
[EINVAL] El argumento de la ruta contiene un último componente que es un punto.

información relacionada