Se eu fizer: touch file; mv file /dev/null
como raiz, /dev/null
desaparece. ls -lad /dev/null
resulta em nenhum arquivo ou diretório. Isso interrompe aplicativos que dependem do /dev/null
SSH e podem ser resolvidos fazendo isso mknod /dev/null c 1 3; chmod 666 /dev/null
. Por que mover um arquivo regular para esse arquivo especial resulta no desaparecimento de /dev/null
?
Para esclarecer, isso foi feito para fins de teste e eu entendo como o mv
comando funciona. O que me interessa é o motivo pelo qual, ls -la /dev/null
antes de substituí-lo por um arquivo regular, mostra a saída esperada, mas depois mostra que /dev/null
não existe, mesmo que um arquivo tenha sido supostamente criado por meio do mv
comando original e o comando file mostre Texto ASCII. Eu acho que isso deve ser uma combinação do ls
comportamento do comando em conjunto com devfs
quando um arquivo não especial substitui um caractere / arquivo especial. Isso ocorre no Mac OS X, os comportamentos podem variar em outros sistemas operacionais.
/dev/null
.rm
comandodevfs
é engraçado com arquivos normais. Estranho, você não recebeu um erromv
. Que tal assimtouch testfile; mv testfile /dev
:?mv
só pode ser atômico no mesmo sistema de arquivos.Respostas:
Examinando o código fonte do mv, http://www.opensource.apple.com/source/file_cmds/file_cmds-220.7/mv/mv.c :
Na primeira passagem pelo loop while,
open(to, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0)
falhará com EEXIST. Então/dev/null
será desvinculado, e o loop será repetido. Mas, como você apontou no seu comentário, os arquivos regulares não podem ser criados/dev
, portanto, na próxima passagem pelo loop,open(to, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0)
ainda falhará.Eu apresentaria um relatório de bug na Apple. O
mv
código fonte é praticamente inalterado em relação à versão do FreeBSD, mas como o devfs do OSX tem esse comportamento não POSIX com arquivos regulares, a Apple deve corrigi-losmv
.fonte
Mover um arquivo para o local de um arquivo já existente substitui o arquivo existente. Nesse caso, o
/dev/null
arquivo do dispositivo é substituído, assim como qualquer arquivo normal. Para evitar isso, use a opção-i
(interativo, avisa antes de substituir) ou-n
(sem clober) paramv
./dev/null
somente executa sua função especial como um balde de bits, o dispositivo é aberto como está. Por exemplo, quando o>
operador shell é usado, o arquivo é aberto e truncado (não removido e substituído, que pode ser o que você esperava). Como mencionado por Casey, a maneira correta de remover um arquivo é comrm
ou mesmo comunlink
.fonte
Hum, porque você substituiu o arquivo especial pelo normal? O que você esperava que fosse acontecer?
dev/null
não é um diretório, é um arquivo apontando para umnull
dispositivo. Quando você fazmv
algo, exclui o original e o substitui pelo que você moveu:fonte
/dev/null
, tornou-se o arquivo que mudei.