Respuestas:
cat /dev/null > file.txtEs un uso inútil del gato .
Básicamente, cat /dev/nullsimplemente no genera catnada. 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.txtfuncionará 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 truede salida sin datos, y son órdenes internas de concha (mientras que cates 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.txtsintaxis.
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 trueque se considera un "especial" incorporado .
>| filees un truncado más explícito.
truese 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 : > filesaldrá del shell, por ejemplo, si fileno se puede abrir para escribir en shells POSIX) y trueno lo es. POSIX incluso menciona que :puede ser más eficiente que trueen 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:
sho kshemulació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 catcontrario), 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 evalsiendo incorporados especiales, si falla la redirección, eso sale del shell ( bashsolo 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, cpy printfpor lo general son (POSIX les obliga)).fileSin embargo, si es un enlace simbólico a un archivo no existente, algunas cpimplementaciones 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/nullen file? catsiendo 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 filepero 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 cphacerlo de manera predeterminada podría pensar que también está tratando de hacer fileun nulldispositivo.eval > fileo 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.
evalEstá garantizado para ser construido en todos los depósitos. :está integrado donde esté disponible (a Bourne / csh le gusta). trueestá integrado solo en conchas tipo Bourne.
printfestá integrado en la mayoría de los modernos depósitos de tipo Bourne y fish.
cpy catgeneralmente no están integrados.
Ahora cp /dev/null fileno 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 : > fileen 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=0se ignora. dd if=/dev/null of=fileSería más portátil. En cualquier caso, eso es independiente del shell.
cp /dev/null file, ¿verdad?
cp /dev/null filees 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: truncateestá destinado a truncar archivos, mientras que usar> tiene el efecto secundario de truncar un archivo.
truncateestaría disponible, pero >ni las unistdbibliotecas de C estarían disponibles?
truncatees una utilidad FreeBSD, relativamente reciente (2008) agregada a los coreutils de GNU (aunque el --sizeestilo 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 filefuncionaría sin una redirección de shell y sería más portátil.
¡La respuesta depende un poco de lo que file.txtes y cómo el proceso le escribe!
Citaré un caso de uso común: tiene un archivo de registro en crecimiento llamado file.txty desea rotarlo.
Por lo tanto, copia, por ejemplo, file.txten file.txt.save, luego trunca file.txt.
En este escenario, SI el archivo no se abre another_process( por ejemplo, another_processpodrí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_processtodaví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 processabrió el archivo:
Si lo other_processabre 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_processabre file.txten "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_processtodavía escriben en esa ubicación lo hayan abierto en el modo "agregar". De lo contrario, deberá detenerlos other_processe 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 > filey a > filees a cat /dev/nully 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?
echoimplementaciones no son compatibles -n(y se generarían -n<SPC><NL>aquí. printf '' > file.txtSerían más portátiles (al menos en los sistemas modernos / POSIX).