mv un archivo a / dev / null rompe dev / null


25

Si lo hago: touch file; mv file /dev/nullcomo root,/dev/null desaparece. ls -lad /dev/nullno da como resultado tal archivo o directorio. Esto interrumpe las aplicaciones que dependen de /dev/nullSSH y se pueden resolver haciendo esto mknod /dev/null c 1 3; chmod 666 /dev/null. ¿Por qué mover un archivo normal a este archivo especial resulta en la desaparición de /dev/null?

Para aclarar, esto fue con fines de prueba, y entiendo cómo funciona el mvcomando. Lo que tengo curiosidad es por qué ls -la /dev/nullantes de reemplazarlo con un archivo normal muestra el resultado esperado, pero luego muestra que /dev/nullno existe a pesar de que supuestamente se creó un archivo a través del mvcomando original y el comando de archivo muestra texto ASCII. Creo que esto debe ser una combinación del lscomportamiento del comando junto con devfscuando un archivo no especial reemplaza un archivo de caracteres / especial. Esto está en Mac OS X, los comportamientos pueden variar en otros sistemas operativos.


44
No te metas con /dev/null.
devnull

77
así lo dice @devnull
Braiam

3
La forma correcta de eliminar archivos es el rmcomando.
casey

1
Parece que esa es la raíz de su problema, OSX devfses divertido con los archivos normales. Sin embargo, es extraño que no haya recibido un error mv. ¿Qué tal esta manera touch testfile; mv testfile /dev:?
Graeme

3
@Gregg, mvsolo puede ser atómico en el mismo sistema de archivos.
Graeme

Respuestas:


16

Mirando el código fuente de mv, http://www.opensource.apple.com/source/file_cmds/file_cmds-220.7/mv/mv.c :

/*
 * If rename fails because we're trying to cross devices, and
 * it's a regular file, do the copy internally; otherwise, use
 * cp and rm.
 */
if (lstat(from, &sb)) {
    warn("%s", from);
    return (1);
}
return (S_ISREG(sb.st_mode) ?
    fastcopy(from, to, &sb) : copy(from, to));

...

int
fastcopy(char *from, char *to, struct stat *sbp)
{
...
while ((to_fd =
    open(to, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0)) < 0) {
        if (errno == EEXIST && unlink(to) == 0)
            continue;
        warn("%s", to);
        (void)close(from_fd);
        return (1);
}

En la primera pasada a través del ciclo while, open(to, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0)fallará con EEXIST. Luego /dev/nullse desvinculará y se repetirá el ciclo. Pero como señaló en su comentario, no se pueden crear archivos regulares en/dev , por lo que en el próximo paso a través del ciclo, open(to, O_CREAT | O_EXCL | O_TRUNC | O_WRONLY, 0)todavía va a fallar.

Presentaría un informe de error con Apple. El mvcódigo fuente en su mayoría no ha cambiado desde la versión de FreeBSD, pero debido a que los devfs de OSX tienen ese comportamiento que no es POSIX con los archivos normales, Apple debería corregirlos mv.


1
Estoy dando esta mejor respuesta en este momento por proporcionar el código fuente y reconocer esto como un error, que es a lo que estaba conduciendo.
Gregg Leventhal

12

Mover un archivo a la ubicación de un archivo ya existente reemplaza el archivo existente. En este caso, el /dev/nullarchivo del dispositivo se reemplaza, como lo haría cualquier archivo normal. Para evitar esto, use la opción -i(interactivo, advierte antes de sobrescribir) o -n(sin clober) para mv.

/dev/nullsolo realiza su función especial como un depósito de bits y luego el dispositivo se abre como está. Por ejemplo, cuando >se utiliza el operador de shell, el archivo se abre y luego se trunca (no se elimina y se reemplaza, lo que puede ser lo que esperaba). Como mencionó Casey, la forma correcta de eliminar un archivo es con rmo incluso con unlink.


Ver mis comentarios a terdon.
Gregg Leventhal

Entendido, el -d era innecesario, eso es solo un mal hábito, sin embargo, el archivo aún debería aparecer en la salida ls, no debería mostrarse como inexistente.
Gregg Leventhal

@Graeme - ¡Bienvenido a 3K, buen trabajo!
slm

10

Umm, ¿porque sobrescribes el archivo especial con uno normal? Qué esperabas que sucediera? dev/nullno es un directorio, es un archivo que apunta a un nulldispositivo. Cuando tiene mvalgo que hacer, elimina el original y lo reemplaza con lo que haya movido:

$ file /dev/null 
/dev/null: character special 
$ sudo mv file /dev/null 
$ file /dev/null 
/dev/null: ASCII text

2
Pero estoy diciendo que / dev / null se mostraba como perdido cuando se ejecuta un ls -lad / dev / null. Esto debe ser algo específico para los devfs, que es lo que quería saber.
Gregg Leventhal

Si mv archivo / dev / null entonces / dev / null debería contener qué archivo contenía pero aún existe. Quiero saber por qué esto causó que / dev / null no se encuentre en un ls.
Gregg Leventhal

De acuerdo, estoy haciendo esto en una Mac, por lo que podría ser un poco diferente, pero no esperaba que el archivo se mostrara como perdido, solo esperaba que se mostrara como cambiado al archivo fuente.
Gregg Leventhal

@GreggLeventhal sí, debe ser una cosa OSX o BSD (edite su Q y especifique su sistema operativo). En mi Linux todavía puedo ver /dev/null, se ha convertido en el archivo que moví.
terdon
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.