“mv: não pode mover '.' para '../general/.': Dispositivo ou recurso ocupado ”

3
$ mv . ../general/
mv: cannot move '.' to '../general/.': Device or resource busy

Isso significa que o diretório atual é um dispositivo ou recurso ocupado e não pode ser removido? Por que isso acontece?

    
por Tim 05.10.2014 / 02:00

4 respostas

6

Você não pode mover o diretório em que está atual. O processo atual é aquele que o mantém ocupado.

Em vez disso, suba um nível e nomeie o diretório anterior para movê-lo para o destino.

    
por 05.10.2014 / 02:48
6

Não é possível mover um ponto . . O ponto não é o mesmo que o nome do diretório atual. Você pode pensar em . como um ponteiro para o diretório, mas não no próprio diretório, portanto,

$ 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

não funciona, mas

cd tmp1
mv ../tmp1 ../tmp2

funciona bem, então na verdade você pode mover o diretório atual, embora alguns comandos possam ser confundidos após esta operação:

$ 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

História semelhante com .. , ou seja, diretório pai.

Em outras palavras, cada diretório deve conter pelo menos dois elementos: . e .. . Você não pode movê-los ou excluí-los.

    
por 05.10.2014 / 03:29
4

O motivo pelo qual você está recebendo a mensagem:

mv: cannot move .' to../general/.': Device or resource busy

é devido a como . e .. trabalham além de mv . Quando você move algo no Unix, o comando mv tenta desvincular tudo o que referencia o inode do item que você está tentando mover. Neste caso, seria o inode de qualquer que seja o diretório que . esteja referenciando.

Os "símbolos / links" . e .. estão vinculados a inodes e, em certo sentido, são especiais. Você pode ler sobre a história deles aqui na seção Perguntas e respostas intitulado: Por que um novo diretório tem uma contagem de hard link de 2 antes que qualquer coisa seja adicionada a ele? . Se você já olhou para um diretório recém-criado, notará que ele sempre começa com uma contagem vinculada de 2. O motivo é devido à existência de . e .. .

$ 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 ..

OBSERVAÇÃO: A referência para a saída de ls , se você não tiver certeza, está aqui neste anúncio de perguntas e respostas intitulado: O que significam os campos ls -al output? .

Portanto, eles não são nomes de diretórios reais, mas são "símbolos / links" que estão vinculados a eles. Portanto, eles devem ser desvinculados antes de serem capazes de mv .

Bem, desde que seu comando está usando o . , ele não pode ser desvinculado pelo comando mv , daí o msg: "Dispositivo ou recurso ocupado".

Referências

por 05.10.2014 / 13:49
2

O Linux proíbe a renomeação de qualquer caminho que termine no componente . ou .. , retornando o erro EBUSY; o seguinte também falhará:

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

O código para isso está em namei.c::renameat . O último componente do nome do caminho quando passado para várias funções precisa ser do tipo LAST_NORM , não LAST_DOT ou LAST_DOTDOT .

O FreeBSD retorna o erro EINVAL em cada um desses casos.

Só podemos adivinhar por que existe essa restrição.

The rename() function shall fail if:
...
[EBUSY] The directory named by old or new is currently in use by the system or another process, and the implementation considers this an error.

Pode-se considerar que . esteja atualmente em uso pelo processo. Mas observe que o Linux permite o seguinte, portanto, um diretório que está meramente sendo usado por algum processo não é suficiente para que rename falhe:

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

O motivo para proibir a renomeação de . e .. é provavelmente "leva a menos confusão do usuário".

  • . é tipicamente um link rígido para a entrada do diretório em seu pai, e é um tanto especial, pois um processo sempre pode abrir . para acessar seu diretório de trabalho atual. Ser capaz de mudar o nome seria contraproducente.
  • .. é tipicamente um link rígido para o pai do diretório, e é um tanto especial em que um processo que abre .. obterá o diretório pai (ou o próprio diretório, se for um ponto de montagem). Ser capaz de mudar o nome seria contraproducente.

O Linux também proíbe rmdir de um caminho cujo último componente é .. (ENOTEMPTY) ou . (EINVAL). O FreeBSD retorna o erro EINVAL para cada um deles. O padrão POSIX para rmdir tem isto:

The rmdir() function shall fail if:
...
[EINVAL] The path argument contains a last component that is dot.

    
por 05.10.2014 / 18:29

Tags