Pourquoi n'y a-t-il pas de commande shell pour créer des fichiers?

27

Attention, s'il vous plaît:

Je ne demande pas comment créer un fichier à partir de la ligne de commande!


J'utilise touchpour faire des fichiers depuis des années sans faire attention à ce que son objectif principal soit autre chose. Si l'on veut créer un fichier à partir de la ligne de commande, il y a tellement de possibilités:

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

Et je suis sûr qu'il y en a plus.

Mais le fait est qu'aucune des commandes ci-dessus n'est réellement conçue pour créer des fichiers. Par exemple, man touchsuggère que cette commande sert à modifier les horodatages des fichiers. Pourquoi un système d'exploitation aussi complet qu'Unix (ou Linux) n'a-t-il pas une commande uniquement conçue pour créer des fichiers?

Pouya
la source
35
Pourquoi voudriez-vous encombrer le système pour ajouter une commande pour faire quelque chose qui peut être fait d'une douzaine de façons avec des outils qui existent déjà?
Michael Kohne
4
Pourquoi n'y a-t-il pas de commande pour lire les fichiers de / vers les flux / stdin / out? Tout le monde utilise la commande destinée à la con catenation!
SF.
2
@MichaelKohne, je vois votre point, avec tout le respect que je vous dois, j'ai un problème avec cela. Avec cette approche, il existe de nombreuses commandes qui ne font qu'encombrer le système. Pourquoi utiliser morequand lessfait plus que quoi more!? Ou diret ls. Mais je suis conscient des problèmes de compatibilité.
Pouya
9
moreest antérieure à la création de less. lessa été créé spécifiquement pour combler les lacunes de more. moreexiste toujours pour des raisons de compatibilité descendante. diret lssont, pour la plupart des intentions et des fins, le même exécutable - ils ne diffèrent que par une poignée d'octets. Un nouvel outil destiné spécifiquement pour la création de fichiers ferait moins que les outils existants, et en tant que tel , il serait une régression, et non une amélioration comme dans le cas de lessvs more.
lanzz
1
De plus, nous devons regarder l'héritage, Unix a été créé lorsque chaque octet a été compté. Pourquoi créer un utilitaire pour une tâche que vous pouvez faire avec un utilitaire déjà existant?
Thomas

Réponses:

38

Je dirais parce qu'il n'est presque jamais nécessaire de créer un fichier vide que vous ne remplirez pas de contenu immédiatement sur la ligne de commande ou dans un script shell.

Il n'y a absolument aucun avantage à créer un fichier d'abord, puis à utiliser la redirection d'E / S pour écrire dans le fichier si vous pouvez le faire en une seule étape.

Dans les cas où vous voulez vraiment créer un fichier vide et le laisser, je dirais que > "${file}"cela ne pourrait pas être plus bref et plus élégant.

TL; DR : Cela n'existe pas car la création de fichiers vides n'a le plus souvent aucune utilité, et dans les cas où il y en a déjà une myriade d'options disponibles pour atteindre cet objectif.

Sur une note latérale, l'utilisation touchne fonctionne que si le fichier n'existe pas alors que les options utilisant la redirection tronqueront toujours le fichier, même s'il existe (donc techniquement, ces solutions ne sont pas identiques). > fooest la méthode préférée car elle enregistre un forket echo -ndevrait être évitée en général car elle est très peu transférable.

Adrian Frühwirth
la source
1
J'ai trouvé votre point sur la création du fichier puis sur l'utilisation des outils d'E / S, très solide. Merci.
Pouya
1
@FaheemMitha Oui ( >>). Je faisais référence aux exemples donnés par OP en utilisant >. L'ajout serait tout à fait inutile si ce que vous recherchez est la création de fichiers (ou NOOP out s'ils existent).
Adrian Frühwirth
1
N'oubliez pas que cela noclobberne doit pas être défini afin d' >écraser un fichier existant.
Ouki
1
@Ouki AFAIK, paramètre qui n'est pas un comportement par défaut et on pourrait oublier qu'il est défini sur un système et non sur un autre, ce qui peut entraîner des problèmes de la même manière que la création d'un alias rm='rm -i'au lieu de alias rmi='rm -i'est une mauvaise idée.
Agi Hammerthief
1
@mikeserv, > .filesur une seule ligne de commande, le fera parfaitement bien sans le :.
Charles Duffy
16

La réponse d'Adrian Frühwirth est juste. Je voulais juste ajouter qu'il ya effectivement une commande spécifiquement écrite pour créer des fichiers: 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.

Certes, mktemple travail de n'est pas de créer un fichier avec un nom spécifique, c'est simplement de créer un fichier . Cependant, comme on vous l'a déjà dit, il existe de nombreuses façons plus efficaces et élégantes de créer des fichiers avec un nom donné que fournir une commande pour cela serait inutile.

Cela dit, vous avez également truncateet fallocatetous deux l'objectif essentiel est de créer des fichiers. Ils ont simplement une approche plus sophistiquée. Il n'y aura jamais un programme simple qui fait ce qu'il > filefait, car il n'y a aucun moyen que ce soit mieux que > file.

terdon
la source
11

La plupart des outils shell de base ne sont pas conçus du tout pour un objectif très spécifique. La plupart des outils shell de base sont conçus uniquement pour interagir avec d'autres pour atteindre votre objectif. Ou peut-être faut-il dire que la plupart des outils ne font qu'une chose très fondamentale, quelle que soit la façon dont ils peuvent être combinés pour atteindre un objectif.

: >./file

Cela crée un fichier vide. Ou tronque un fichier existant comme vous le souhaitez. Vous pouvez:

set -o noclobber

pour éviter toute possibilité de ce dernier cas, sauf si vous:

: >|./file

Vous pouvez obtenir un comportement similaire à celui touchde:

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

Sauf que :cela ne mettra pas à jour le modtime d'un fichier car il n'est pas modifié.

DEMO

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

SORTIE

-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

NE TOUCHEZ PAS

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

SORTIE

-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
la source
Par défaut, l'écho ajoute \nà la fin de la ligne. Essayez echo -n >echo-n.file(taille = 0) et echo -e >echo-e.file(taille = 1)
Thomas
@Thomas 'Une chaîne à écrire sur la sortie standard. Si le premier opérande est -n, ou si l'un des opérandes contient une barre oblique inverse ('\'), les résultats sont définis par l'implémentation. Sur les systèmes conformes à XSI, si le premier opérande est -n, il doit être traité comme une chaîne et non comme une option. Les séquences de caractères suivantes doivent être reconnues sur les systèmes conformes à XSI dans l'un des arguments ... ' pubs.opengroup.org/onlinepubs/009604599/utilities/echo.html
mikeserv
Très bien, merci pour le lien, et mon commentaire n'est pas le point de toute façon
Thomas
2
Oui en effet et désolé, je voulais dire que mon commentaire manquait de toute façon le point de votre réponse, désolé.
Thomas
1
Une illustration de la tendance d'Unix à généraliser est le fait que la commande pour afficher le contenu d'un fichier est appelée cat. Pourquoi avoir une commande pour afficher un fichier, alors que vous pouvez faire une commande pour concaténer plusieurs fichiers en sortie standard?
200_success
1

L'utilitaire installest en fait conçu pour créer des fichiers! Vous pouvez passer le contenu du fichier via /dev/stdin(dans la plupart des cas, cependant, sur la plupart des versions de Linux, cela nécessite qu'il /procsoit monté) ou fournir un autre fichier source. Vous pouvez définir la propriété et les autorisations.

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

comme un exemple stupide.

Otheus
la source