cp sobrescribir vs rm luego cp

18

Cuando trato de sobrescribir un archivo binario que se inicia actualmente, cpno se puede sobrescribir, pero es posible que rmlo haga cp. Por ejemplo:

user@poste:~$ cp binaryFile /tmp
user@poste:~$ sudo cp /tmp/binaryFile binaryFile 
[sudo] password for user:
cp: cannot create regular file `binaryFile`: Text file busy
user@poste:~$ sudo rm binaryFile 
user@poste:~$ sudo cp /tmp/binaryFile  binaryFile 
user@poste:~$ file binaryFile 
binaryFile : ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0x7ce005d9eb50e2574246b6a881e625802f7e49f2, not stripped

¿Alguna idea de por qué?

M4rty
fuente
2
Pequeño hilo interesante, pero debería estar en Unix / Linux.SE IMO.
underscore_d

Respuestas:

41

En el primer caso, está intentando sobrescribir el contenido de un archivo que se está ejecutando actualmente como un programa. Linux no lo permite: si lo hiciera, sobrescribiría el código justo cuando el sistema operativo lo estaba ejecutando; La primera diferencia podría bloquear el programa o hacer que funcione mal.

Pero en el segundo caso, en realidad no está cambiando el contenido del archivo antiguo: está creando un nuevo archivo en su lugar, mientras que el anterior simplemente pierde el nombre del archivo pero mantiene su contenido intacto.

(Recuerde que rmno técnicamente borrar archivos, que sólo elimina los enlaces de directorio - similar a cómo lnañade más enlaces a un mismo archivo Sólo cuando un archivo no tiene enlaces. Y no hay referencias de archivos abiertos, automáticamente se elimina.)

El sistema hace referencia a los archivos en uso por su inodo, por lo que no importa que tengan el mismo nombre de archivo; sigue siendo el archivo antiguo que permanece abierto por el sistema, y ​​aunque ya no tiene enlaces, solo se eliminará una vez que todos los programas lo cierran.

usuario1686
fuente
77
Otro truco que a menudo se usa con la misma lógica: abra un archivo (temporal) en su software y elimínelo inmediatamente, sin cerrar primero el archivo. Su programa aún puede usarlo de la forma que desee y cuando su programa lo cierre (controlado) u olvide cerrarlo (por ejemplo, su programa se bloqueó sin limpieza), el SO lo eliminará automáticamente. (Fin del programa, no importa cómo sucedió eso, libera todas las referencias que el programa tenía al archivo).
Tonny
2
Es por eso que cuando elimina algún archivo de registro de un proceso en ejecución, el comando df no devuelve el tamaño corregido hasta que detiene el proceso
M4rty
¿Hay alguna manera para que un programa externo (con puentes civiles) encuentre y cree un nuevo identificador para este inodo colgante? Me imagino que hay programas que usan esto como una "característica de seguridad", por lo que es interesante entender la historia completa.
BenPen
3
@BenPen: en Linux, sí, use /proc/*/fdpara acceder a él y opcionalmente linkat () para agregar un nuevo enlace al sistema de archivos.
user1686
3
@BenPen y grawity: en realidad, no puede vincular un inodo a la estructura del directorio si tiene cero enlaces, incluso con linkat(), por razones de seguridad . (Excepción a esta regla: a menos que se haya creado con open(O_TMPFILE)él, así que comenzó con cero enlaces). Si lo intenta, linkat()devuelve ENOENT, incluso como root. Vea mi respuesta a esa pregunta para que se ejecute un script perl linkaty demuestre que no funciona, incluso como root: /
Peter Cordes