2011-12-15 11 views
14

Estoy tratando de vaciar un archivo en linux mientras está en uso, es un archivo de registro por lo que se escribe continuamente. Ahora he utilizado:Vaciar un archivo mientras está en uso en Linux

echo -n > filename 

o

cat /dev/null > filename 

pero todo esto producir un archivo vacío con un carácter de nueva línea (o extraño personaje que puedo ver como^@^@^@^@^@^@^@^@^@^@^@^.. en vi) y tengo que eliminar manualmente con vi y dd la primera línea y luego guardar.

Si no utilizo vi y dd no puedo manipular el archivo con grep pero necesito un procedimiento automático que pueda escribir en un script de shell.

Ideas?

+0

echo ""> nombre de archivo? –

+0

¿Por qué escribe '@@@@' cuando realmente ve '^ @^@^@^@'? – glglgl

+0

@gigigi post corregido –

Respuesta

4

¿Por qué no solo :>filename?

(: es una fiesta de orden interna que tiene el mismo efecto que /bin/true, y ambos comandos no echo nada)

prueba de que funciona:

[email protected] ~ $ du t.txt 
4  t.txt 
[email protected] ~ $ :>t.txt 
[email protected] ~ $ du t.txt 
0  t.txt 
+1

':' no es un alias para '/ bin/true'. En bash al menos, es un comando nulo, no hace nada. Sin embargo, siempre vuelve verdadero. También es realmente innecesario aquí. Puedes hacer '> file'. – pgl

+0

@pgl sí, en bash es un builtin, realmente quise decir que podría ser un reemplazo para '/ bin/true'. Reformulando ... – fge

+1

mismo comportamiento. La primera vez que el proceso escribe en un archivo, escribe @@@@@@@ char –

0

no tengo ni un shell de Linux para Pruébalo, pero ¿has intentado esto?

echo "" > file 
+0

sí, el mismo comportamiento que echo -n> filename pero con una nueva línea. De todos modos, el mismo carácter extraño al comienzo de un archivo –

21

Esto debería ser suficiente para vaciar un archivo:

> file 

Sin embargo, los otros métodos que dijo que ha intentado también debería funcionar. Si está viendo caracteres extraños, se están escribiendo en el archivo por otra cosa, muy probablemente sea cual sea el proceso que esté iniciando sesión allí.

+0

no funciona, solo llena el archivo con^@^@^@ – default

+0

También en http://superuser.com/q/90008/1771 –

3

Si se trata de un archivo de registro, la forma correcta de hacerlo es utilizar logrotate. Como mencionaste al hacerlo manualmente, no funciona.

6

Otra forma es la siguiente:

cp /dev/null the_file 

La ventaja de esta técnica es que se trata de un solo comando, por lo que en caso de que necesite acceso sudo sólo se requiere una llamada sudo.

12

Lo que está sucediendo es bastante simple: es vaciar el archivo.

¿Por qué está lleno de ^@ s, entonces, usted pregunta? Bueno, en un sentido muy real, no lo es. No contiene esos personajes extraños. Tiene un "agujero".

El programa que está escribiendo en el archivo está escribiendo un archivo que se abrió con O_WRONLY (o tal vez O_RDWR), pero no O_APPEND. Este programa ha escrito, digamos, 65536 bytes en el archivo en el momento en que vacía el archivo con cp /dev/null filename o : > filename o algún comando similar.

Ahora el programa va a write otro trozo de datos (digamos, 4096 u 8192 bytes). ¿Dónde se escribirán esos datos? La respuesta es: "en el desplazamiento de búsqueda actual en el descriptor de archivo subyacente". Si el programa usara O_APPEND, el write estaría, de hecho, precedido por una llamada lseek que hizo una "búsqueda hasta el final actual del archivo, es decir, la longitud actual del archivo". Cuando trunca el archivo, "el final actual del archivo" se volvería cero (el archivo se volvería vacío) de modo que la búsqueda movería el desplazamiento write a la posición 0 y la escritura iría allí. Pero el programa no usó O_APPEND, por lo que no hay una operación de "reposición" previa a write, y los bytes de datos se escriben en el desplazamiento actual (que, nuevamente, hemos afirmado que es 65536 anterior).

Ahora tiene un archivo que no tiene datos en desplazamientos de bytes 0 a 65535 inclusive, seguido de algunos datos en desplazamientos de bytes 65536 a través 73727 (suponiendo que el write escribe 8192 bytes). Esa información "faltante" es el "agujero" en el archivo. Cuando algún otro programa va a leer el archivo, el sistema operativo pretende que es datos allí: datos de cero bytes.

Si el programa que realiza las operaciones write no las hace en los límites de los bloques, el sistema operativo de hecho asignará algunos datos adicionales (para ajustar la escritura en bloques enteros) y lo pondrá a cero. Esos bytes cero no son parte del "agujero" (son cero bytes reales en el archivo), sino a los programas comunes que no se asoman detrás de la cortina en el Wizard of Oz, los "cero" bytes y el "no" "cero bytes" son indistinguibles.

Lo que necesita hacer es modificar el programa para usar O_APPEND, o usar rutinas de biblioteca como syslog que saben cómo cooperar con operaciones de rotación de registros, o tal vez ambas.

[Editar para agregar: no está seguro de por qué esto repente apareció en la primera página y me respondió una pregunta de 2,011 ...]

+0

Esto debe aceptarse como la respuesta , ¡ya que es el más completo y correcto aquí! – pgl

Cuestiones relacionadas