Respuestas:
cat /dev/null > file.txt
Es un uso inútil del gato .
Básicamente, cat /dev/null
simplemente no genera cat
nada. Sí, funciona, pero muchos lo desaprueban porque provoca la invocación de un proceso externo que no es necesario.
Es una de esas cosas que es común simplemente porque es común.
Usar solo > file.txt
funcionará en la mayoría de los proyectiles, pero no es completamente portátil. Si quiere ser completamente portátil, las siguientes son buenas alternativas:
true > file.txt
: > file.txt
Tanto :
y true
de salida sin datos, y son órdenes internas de concha (mientras que cat
es una utilidad externa), por lo que son más ligeros y más 'adecuado'.
Actualizar:
Como tylerl mencionó en su comentario, también existe la >| file.txt
sintaxis.
La mayoría de los shells tienen una configuración que les impedirá truncar un archivo existente mediante >
. Debe usar >|
en su lugar. Esto es para evitar errores humanos cuando realmente pretendía agregar >>
. Puede activar el comportamiento con set -C
.
Entonces, con esto, creo que el método más simple, más apropiado y portátil para truncar un archivo sería:
:>| file.txt
:
también tiene el mandato de POSIX para ser incorporado, y de hecho es diferente de true
que se considera un "especial" incorporado .
>| file
es un truncado más explícito.
true
se requiere que no sea incorporado y tradicionalmente no lo fue. :
Está construido en todos los depósitos de la familia Bourne. :
es un archivo incorporado especial por POSIX (por lo que : > file
saldrá del shell, por ejemplo, si file
no se puede abrir para escribir en shells POSIX) y true
no lo es. POSIX incluso menciona que :
puede ser más eficiente que true
en algunos sistemas.
Bourne POSIX zsh csh/tcsh rc/es fish
> file Y Y N(1) N(1) N N
: > file N/Y(2) Y(3) Y Y(4) N(5) N(5)
true > file Y(5) Y Y Y(5) Y(5) Y(5)
cat /dev/null > file Y(5) Y Y(5) Y(5) Y(5) Y(5)
eval > file Y(3,8) Y(3) Y Y(6) Y Y
cp /dev/null file (7) Y(5) Y Y(5) Y(5) Y(5) Y(5)
printf '' > file Y(5) Y Y Y(5) Y(5) Y
Notas:
sh
o ksh
emulación, para las redirecciones sin un comando, en zsh, se asume un comando predeterminado (un buscapersonas para la redirección de stdin solamente, de lo cat
contrario), que se puede ajustar con las variables NULLCMD y READNULLCMD. Eso está inspirado en la característica similar en(t)csh
:
en UnixV7 como :
se interpretó a mitad de camino entre un líder de comentarios y un comando nulo. Más tarde fueron y, como todos los componentes integrados, si la redirección falla, sale del caparazón.:
y eval
siendo incorporados especiales, si falla la redirección, eso sale del shell ( bash
solo lo hace en modo POSIX).(t)csh
, eso es definir una etiqueta nula (para goto
), por lo que goto ''
allí se ramificaría. Si la redirección falla, eso sale del shell.$PATH
( :
por lo general no es, true
, cat
, cp
y printf
por lo general son (POSIX les obliga)).file
Sin embargo, si es un enlace simbólico a un archivo no existente, algunas cp
implementaciones como GNU se negarán a crearlo.(esta sección es altamente subjetiva)
> file
. Eso se >
parece demasiado a un aviso o un comentario. Además, la pregunta que haré al leer eso (y la mayoría de los shells se quejarán de lo mismo) es ¿qué salida está redireccionando exactamente? .: > file
. :
se conoce como el comando no-op. Eso se lee de inmediato como generar un archivo vacío. Sin embargo, aquí nuevamente, eso :
puede perderse fácilmente y / o verse como un aviso.true > file
: ¿qué tiene que ver booleano con la redirección o el contenido del archivo? ¿Qué se quiere decir aquí? es lo primero que me viene a la mente cuando leo eso.cat /dev/null > file
. Concatenar /dev/null
en file
? cat
siendo a menudo visto como el comando para volcar el contenido del archivo, que todavía puede tener sentido: volcar el contenido de la archivo vacío enfile
, un poco como una forma enrevesada de decir cp /dev/null file
pero todavía comprensible.cp /dev/null file
. Copia el contenido del archivo vacío en file
. Tiene sentido, aunque alguien que no sabe cómo cp
hacerlo de manera predeterminada podría pensar que también está tratando de hacer file
un null
dispositivo.eval > file
o eval '' > file
. No ejecuta nada y redirige su salida a a file
. Tiene sentido para mi. Es extraño que no sea un idioma común.printf '' > file
: explícitamente no imprime nada en un archivo. El que tiene más sentido para mí.La diferencia será si estamos usando un shell incorporado o no. Si no, un proceso tiene que ser bifurcado, el comando cargado y ejecutado.
eval
Está garantizado para ser construido en todos los depósitos. :
está integrado donde esté disponible (a Bourne / csh le gusta). true
está integrado solo en conchas tipo Bourne.
printf
está integrado en la mayoría de los modernos depósitos de tipo Bourne y fish
.
cp
y cat
generalmente no están integrados.
Ahora cp /dev/null file
no invoca redirecciones de shell, por lo que cosas como:
find . -exec cp /dev/null {} \;
serán más eficientes que:
find . -exec sh -c '> "$1"' sh {} \;
(aunque no necesariamente que:
find . -exec sh -c 'for f do : > "$f"; done' sh {} +
)
Personalmente, uso : > file
en conchas tipo Bourne, y no uso otra cosa que las conchas tipo Bourne en estos días.
dd of=file count=0
?
dd
(como Solaris 10 al menos), count=0
se ignora. dd if=/dev/null of=file
Sería más portátil. En cualquier caso, eso es independiente del shell.
cp /dev/null file
, ¿verdad?
cp /dev/null file
es un idioma común. Me limito a eso, el punto no es enumerar todas las formas posibles.
Es posible que desee mirar truncate
, que hace exactamente eso: truncar un archivo.
Por ejemplo:
truncate --size 0 file.txt
Esto es probablemente más lento que usarlo true > file.txt
.
Sin embargo, mi punto principal es: truncate
está destinado a truncar archivos, mientras que usar> tiene el efecto secundario de truncar un archivo.
truncate
estaría disponible, pero >
ni las unistd
bibliotecas de C estarían disponibles?
truncate
es una utilidad FreeBSD, relativamente reciente (2008) agregada a los coreutils de GNU (aunque el --size
estilo de opción larga de GNU es específico de GNU), por lo que no está disponible en sistemas que no sean GNU o FreeBSD, y no está disponible en sistemas GNU más antiguos, No diría que es portátil. cp /dev/null file
funcionaría sin una redirección de shell y sería más portátil.
¡La respuesta depende un poco de lo que file.txt
es y cómo el proceso le escribe!
Citaré un caso de uso común: tiene un archivo de registro en crecimiento llamado file.txt
y desea rotarlo.
Por lo tanto, copia, por ejemplo, file.txt
en file.txt.save
, luego trunca file.txt
.
En este escenario, SI el archivo no se abre another_process
( por ejemplo, another_process
podría ser un programa que salga a ese archivo, por ejemplo, un programa que registra algo), entonces sus 2 propuestas son equivalentes y ambas funcionan bien (pero la segunda se prefiere como primero "cat / dev / null> file.txt" es un uso inútil de Cat y también se abre y lee / dev / null).
Pero el verdadero problema sería si other_process
todavía está activo y todavía tiene un identificador abierto que va al archivo.txt.
Luego, surgen 2 casos principales, dependiendo de cómo se other process
abrió el archivo:
Si lo other_process
abre de la manera normal, el controlador seguirá apuntando a la ubicación anterior en el archivo, por ejemplo, en el desplazamiento de 1200 bytes. Por lo tanto, la siguiente escritura comenzará en el desplazamiento 1200, y por lo tanto tendrá nuevamente un archivo de 1200bytes (+ lo que sea que se haya escrito en otro proceso), ¡con 1200 caracteres nulos iniciales! No es lo que quieres , supongo.
Si se other_process
abre file.txt
en "modo anexar", cada vez que escribe, el puntero buscará activamente hasta el final del archivo. Por lo tanto, cuando lo trunca, "buscará" hasta el byte 0, ¡y no tendrá el efecto secundario negativo! Esto es lo que quieres (... ¡por lo general!)
Tenga en cuenta que esto significa que necesita, cuando trunca un archivo, asegurarse de que todos los que other_process
todavía escriben en esa ubicación lo hayan abierto en el modo "agregar". De lo contrario, deberá detenerlos other_process
e iniciarlos nuevamente, para que comiencen a apuntar al comienzo del archivo en lugar de a la ubicación anterior.
Referencias: /programming//a/16720582/1841533 para obtener una explicación más clara y un pequeño ejemplo de la diferencia entre el registro en modo normal y anexado en /programming//a/984761/1841533
cat /dev/null > file
y a > file
es a cat /dev/null
y eso no hace ninguna diferencia en el archivo.
Me gusta y lo uso a menudo porque se ve más limpio y no como si alguien pulsara la tecla de retorno por accidente:
echo -n "" > file.txt
¿Debería ser un incorporado también?
echo
implementaciones no son compatibles -n
(y se generarían -n<SPC><NL>
aquí. printf '' > file.txt
Serían más portátiles (al menos en los sistemas modernos / POSIX).