¿Por qué no hay ningún comando de shell para crear archivos?

27

Atención por favor:

Estoy no preguntando cómo hacer un archivo desde la línea de comandos!


Lo he estado utilizando touchpara hacer archivos durante años sin prestar atención a que su propósito principal es otra cosa. Si uno quiere crear un archivo desde la línea de comando, hay muchas posibilidades:

touch foo.bar
> foo.bar
cat > foo.bar
echo -n > foo.bar
printf '' > foo.bar

Y estoy seguro de que hay más.

Pero el hecho es que ninguno de los comandos anteriores está diseñado para crear archivos. Por ejemplo, man touchsugiere que este comando es para cambiar las marcas de tiempo del archivo. ¿Por qué un sistema operativo tan completo como Unix (o Linux) no tiene un comando diseñado exclusivamente para crear archivos?

Pouya
fuente
35
¿Por qué desordenaría el sistema para agregar un comando para hacer algo que se puede hacer de una docena de maneras con herramientas que ya existen?
Michael Kohne
44
¿Por qué no hay un comando para leer archivos de / a streams / stdin / out? ¡Todos usan el comando destinado a la catconización!
SF.
2
@MichaelKohne, veo su punto, con el debido respeto, tengo un problema con eso. Con este enfoque, hay muchos comandos que solo saturan el sistema. ¿Por qué usar morecuándo lesshace más que qué morehacer? O dire ls. Aunque estoy al tanto de los problemas de compatibilidad.
Pouya
99
moreanterior a la creación de less. lessha sido creado específicamente para abordar las deficiencias de more. moretodavía existe por razones de compatibilidad con versiones anteriores. diry lsson, para la mayoría de las intenciones y propósitos, el mismo ejecutable; difieren solo en un puñado de bytes. Una nueva herramienta diseñada específicamente para la creación de archivos haría menos que las herramientas existentes, y como tal sería una regresión, no como una mejora en el caso de lessvs more.
lanzz
1
Además, tenemos que mirar el legado, Unix se creó cuando se contaba cada byte. ¿Por qué crear una utilidad para una tarea que puede hacer con una utilidad ya existente?
Thomas

Respuestas:

38

Diría que casi nunca es necesario crear un archivo vacío que no se llene con contenido inmediatamente en la línea de comandos o en el script de shell.

No hay absolutamente ningún beneficio en crear un archivo primero y luego usar la redirección de E / S para escribir en el archivo si puede hacerlo en un solo paso.

En aquellos casos en los que realmente desea crear un archivo vacío y dejarlo, diría que > "${file}"no podría ser más breve y elegante.

TL; DR : No existe porque la creación de archivos vacíos a menudo no tiene uso, y en los casos que tiene ya hay una miríada de opciones disponibles para lograr este objetivo.

En una nota al margen, el uso touchsolo funciona si el archivo no existe, mientras que las opciones que usan la redirección siempre truncarán el archivo, incluso si existe (por lo que técnicamente, esas soluciones no son idénticas). > fooes el método preferido ya que ahorra una forky echo -ndebe evitarse, en general, ya que es altamente no portables.

Adrian Frühwirth
fuente
1
Encontré su punto sobre crear el archivo y luego usar herramientas de E / S, muy sólido. Gracias.
Pouya
1
@FaheemMitha Sí ( >>). Me refería a los ejemplos dados por OP usando >. Anexar sería bastante inútil si lo que busca es crear archivos (o NOOP si existen).
Adrian Frühwirth
1
No olvide que noclobberno tiene que configurarse para >sobrescribir un archivo existente.
Ouki
1
@Ouki AFAIK, una configuración que no es un comportamiento predeterminado y uno podría olvidar que está configurado en un sistema y no en otro, lo que puede generar problemas de la misma manera que crear una en alias rm='rm -i'lugar de alias rmi='rm -i'una mala idea.
Agi Hammerthief
1
@mikeserv, solo > .fileen una línea de comando, lo hará perfectamente bien sin el :.
Charles Duffy
16

La respuesta de Adrian Frühwirth es correcta. Sólo quería añadir que en realidad hay una orden escrita específicamente para crear archivos: mktemp.

NAME
       mktemp - create a temporary file or directory

SYNOPSIS
       mktemp [OPTION]... [TEMPLATE]

DESCRIPTION
       Create a temporary file or directory, safely, and print its name.  TEM
       PLATE must contain at least 3 consecutive 'X's in last  component.   If
       TEMPLATE is not specified, use tmp.XXXXXXXXXX, and --tmpdir is implied.
       Files are created u+rw, and directories  u+rwx,  minus  umask  restric
       tions.

De acuerdo, mktempel trabajo no es crear un archivo con un nombre específico, es simplemente crear un archivo . Sin embargo, como ya le han dicho, hay muchas formas más eficientes y elegantes de crear archivos con un nombre dado que proporcionar un comando para eso sería inútil.

Dicho esto, también tiene truncatey fallocatecuyo propósito esencial es crear archivos. Simplemente tienen un enfoque más sofisticado. Nunca habrá un programa simple que haga lo que > filehace, ya que no hay forma de que sea mejor que > file.

terdon
fuente
11

La mayoría de las herramientas básicas de shell no están diseñadas para ningún propósito muy específico. La mayoría de las herramientas básicas de shell están diseñadas solo para interactuar con otros para lograr su propósito. O tal vez debería decirse que la mayoría de las herramientas hacen solo una cosa muy básica, independientemente de cómo se combinen para lograr un objetivo.

: >./file

Eso crea un archivo vacío. O trunca un archivo existente como lo hará. Usted puede:

set -o noclobber

para evitar cualquier posibilidad de este último caso a menos que usted:

: >|./file

Puede obtener un comportamiento similar al touchde:

: >>./file
: >>|./file

Excepto que :no actualizará el modtime de un archivo porque no está modificado.

MANIFESTACIÓN

mkdir test ; cd $_
touch touch.file 
: >null.file
echo >echo.file
ls -l

SALIDA

-rw-r--r-- 1 mikeserv mikeserv 1 Apr 10 14:52 echo.file
-rw-r--r-- 1 mikeserv mikeserv 0 Apr 10 14:52 null.file
-rw-r--r-- 1 mikeserv mikeserv 0 Apr 10 14:52 touch.file

NO TOCAR

: >>|./echo.file
ls -l 

SALIDA

-rw-r--r-- 1 mikeserv mikeserv 1 Apr 10 14:52 echo.file
-rw-r--r-- 1 mikeserv mikeserv 0 Apr 10 14:52 null.file
-rw-r--r-- 1 mikeserv mikeserv 0 Apr 10 14:52 touch.file
mikeserv
fuente
Por defecto, echo agrega \nal final de la línea. Prueba echo -n >echo-n.file(size = 0) y echo -e >echo-e.file(size = 1)
Thomas
@Thomas 'Una cadena que se escribirá en la salida estándar. Si el primer operando es -n, o si alguno de los operandos contiene un carácter de barra diagonal inversa ('\'), los resultados están definidos por la implementación. En sistemas conformes a XSI, si el primer operando es -n, se tratará como una cadena, no como una opción. Las siguientes secuencias de caracteres se reconocerán en los sistemas compatibles con XSI dentro de cualquiera de los argumentos ... ' pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html
mikeserv
Muy bien, gracias por el enlace, y mi comentario no es el punto de todos modos
Thomas
2
Sí, de verdad y lo siento, quise decir que mi comentario estaba perdiendo el punto de su respuesta de todos modos, lo siento.
Thomas
1
Una ilustración de la tendencia de Unix a generalizar es el hecho de que se llama al comando para mostrar el contenido de un archivo cat. ¿Por qué tener un comando para mostrar un archivo, cuando podría hacer un comando para concatenar múltiples archivos a la salida estándar?
200_success
1

¡La utilidad installestá diseñada para crear archivos! Puede pasar el contenido del archivo a través de /dev/stdin(en la mayoría de los casos, sin embargo, en la mayoría de las versiones de Linux, esto requiere que /procesté montado) o proporcionar otro archivo fuente. Puede establecer la propiedad y los permisos.

echo "New file" | install -o 0644 -m 452452 -g dumbass /dev/stdin /var/www/index.html

Como un ejemplo tonto.

Oteo
fuente