Warum gibt es keinen Shell-Befehl zum Erstellen von Dateien?

27

Aufmerksamkeit bitte:

Ich frage nicht , wie man eine Datei von der Kommandozeile aus erstellt!


Ich benutze es seit Jahren, touchum Dateien zu erstellen, ohne darauf zu achten, dass sein Hauptzweck etwas anderes ist. Wenn man eine Datei von der Kommandozeile aus erstellen möchte, gibt es so viele Möglichkeiten:

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

Und ich bin mir sicher, dass es noch mehr gibt.

Tatsache ist jedoch, dass keiner der oben genannten Befehle für die Erstellung von Dateien vorgesehen ist. Beispiel: man touchDieser Befehl dient zum Ändern von Dateizeitstempeln. Warum verfügt ein Betriebssystem, das so vollständig ist wie Unix (oder Linux), nicht über einen Befehl, der ausschließlich zum Erstellen von Dateien vorgesehen ist?

Pouya
quelle
35
Warum sollten Sie das System überladen, um einen Befehl hinzuzufügen, der auf ein Dutzend Arten mit bereits vorhandenen Tools ausgeführt werden kann?
Michael Kohne
4
Warum gibt es keinen Befehl zum Lesen von Dateien von / nach streams / stdin / out? Jeder benutzt den Befehl, der für die catKonfi- guration bestimmt ist!
SF.
2
@MichaelKohne, ich verstehe deinen Standpunkt, bei allem Respekt habe ich ein Problem damit. Bei diesem Ansatz gibt es viele Befehle, die das System nur überladen. Warum verwenden, morewenn lessmehr geht als was more? Oder dirund ls. Allerdings sind mir Kompatibilitätsprobleme bekannt.
Pouya
9
morevor der Schaffung von less. lesswurde speziell entwickelt, um die Mängel von more. moreist aus Gründen der Abwärtskompatibilität noch vorhanden. dirund lssind in den meisten Fällen dieselbe ausführbare Datei - sie unterscheiden sich nur in wenigen Bytes. Ein neues Werkzeug für die speziellen Dateien für die Erstellung tun würde weniger als die bestehenden Werkzeuge, und als solche , es wäre eine Regression, keine Verbesserung wie im Fall sein lessvs more.
Lanzz
1
Außerdem müssen wir uns das Erbe ansehen, Unix wurde erstellt, als jedes Byte gezählt wurde. Warum ein Dienstprogramm für eine Aufgabe erstellen, die Sie mit einem bereits vorhandenen Dienstprogramm ausführen können?
Thomas

Antworten:

38

Ich würde sagen, weil es selten notwendig ist, eine leere Datei zu erstellen, die Sie nicht sofort in der Befehlszeile oder in Shell-Skripten mit Inhalten füllen.

Es ist absolut nicht vorteilhaft, zuerst eine Datei zu erstellen und dann die E / A-Umleitung zu verwenden, um in die Datei zu schreiben, wenn Sie dies in einem Schritt tun können.

In den Fällen, in denen Sie wirklich eine leere Datei erstellen und sie > "${file}"belassen möchten, würde ich argumentieren, dass dies nicht kürzer und eleganter sein könnte.

TL; DR : Es ist nicht vorhanden, da das Erstellen leerer Dateien häufig keine Verwendung hat und in Fällen, in denen dies der Fall ist, bereits unzählige Optionen zur Verfügung stehen, um dieses Ziel zu erreichen.

Nebenbei bemerkt touchfunktioniert using nur, wenn die Datei nicht vorhanden ist, wohingegen Optionen, die die Umleitung verwenden, die Datei immer abschneiden, selbst wenn sie vorhanden ist (technisch gesehen sind diese Lösungen also nicht identisch). > fooist die bevorzugte Methode, da sie a speichert forkund echo -ngenerell vermieden werden sollte, da sie sehr unportabel ist.

Adrian Frühwirth
quelle
1
Ich fand Ihren Standpunkt, die Datei zu erstellen und dann E / A-Tools zu verwenden, sehr solide. Vielen Dank.
Pouya
1
@FaheemMitha Ja ( >>). Ich bezog mich auf die Beispiele von OP mit >. Das Anhängen von Dateien wäre völlig nutzlos, wenn Sie Dateien erstellen möchten (oder NOOP heraus, falls vorhanden).
Adrian Frühwirth
1
Vergessen Sie nicht, dass noclobbernicht festgelegt werden muss, >damit eine vorhandene Datei überschrieben wird.
Ouki
1
@Ouki AFAIK, Einstellung, die kein Standardverhalten ist, und man könnte vergessen, dass sie auf einem System und nicht auf einem anderen festgelegt ist, was möglicherweise zu Problemen auf dieselbe Weise führt, wie das Erstellen einer alias rm='rm -i'anstelle von alias rmi='rm -i'eine schlechte Idee ist.
Agi Hammerthief
1
@mikeserv, > .fileallein auf einer Kommandozeile, macht das ohne das vollkommen gut :.
Charles Duffy
16

Die Antwort von Adrian Frühwirth ist richtig. Ich wollte nur hinzufügen , dass es tatsächlich ein Befehl ist speziell geschriebenen Dateien zu erstellen: 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.

Zugegeben, es mktempgeht nicht darum, eine Datei mit einem bestimmten Namen zu erstellen, sondern nur darum, eine Datei zu erstellen . Wie Sie bereits erfahren haben, gibt es so viele effizientere und elegantere Möglichkeiten, Dateien mit einem bestimmten Namen zu erstellen, dass ein entsprechender Befehl keinen Sinn macht.

Das heißt, Sie haben auch truncateund fallocatebeide, deren wesentlicher Zweck es ist, Dateien zu erstellen. Sie haben einfach einen ausgefeilteren Ansatz. Es wird niemals ein einfaches Programm geben, das das > filetut , was es tut, da es auf keinen Fall besser wäre als > file.

terdon
quelle
11

Die meisten grundlegenden Shell - Tools sind nicht ausgelegt für jeden ganz bestimmten Zweck überhaupt. Die meisten grundlegenden Shell-Tools sind nur für die Interaktion mit anderen gedacht , um Ihren Zweck zu erreichen. Oder vielleicht sollte gesagt werden, dass die meisten Tools nur eine sehr grundlegende Funktion haben, unabhängig davon, wie sie kombiniert werden, um ein Ziel zu erreichen.

: >./file

Das erstellt eine leere Datei. Oder kürzt eine vorhandene Datei wie gewünscht. Sie können:

set -o noclobber

um den letztgenannten Fall zu vermeiden, es sei denn, Sie:

: >|./file

Sie können sich ähnlich verhalten wie touchmit:

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

Mit der Ausnahme, dass :die Änderungszeit einer Datei nicht aktualisiert wird, da sie nicht geändert wird.

DEMO

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

AUSGABE

-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

NICHT BERÜHREN

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

AUSGABE

-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
quelle
Standardmäßig wird das Echo \nam Ende der Zeile hinzugefügt. Versuchen Sie echo -n >echo-n.file(Größe = 0) und echo -e >echo-e.file(Größe = 1)
Thomas
@Thomas 'Ein String, der in die Standardausgabe geschrieben werden soll. Wenn der erste Operand -n ist oder wenn einer der Operanden einen Backslash ('\') enthält, sind die Ergebnisse implementierungsdefiniert. Wenn der erste Operand auf XSI-konformen Systemen -n ist, wird er als Zeichenfolge und nicht als Option behandelt. Die folgenden Zeichenfolgen müssen auf XSI-konformen Systemen innerhalb eines der Argumente erkannt werden
mikeserv
Fair genug, danke für den Link, und mein Kommentar ist sowieso nicht der Punkt
Thomas
2
Ja, in der Tat und Entschuldigung, ich habe gemeint, dass mein Kommentar ohnehin den Punkt Ihrer Antwort verfehlt hat. Entschuldigung.
Thomas
1
Ein Beispiel für die Tendenz von Unix zur Verallgemeinerung ist die Tatsache, dass der Befehl zum Anzeigen des Inhalts einer Datei aufgerufen wird cat. Warum einen Befehl zum Anzeigen einer Datei haben, wenn Sie einen Befehl zum Verketten mehrerer Dateien zur Standardausgabe ausführen könnten?
200_success
1

Das Dienstprogramm installist eigentlich zum Erstellen von Dateien gedacht! Sie können den Inhalt der Datei übermitteln /dev/stdin(in den meisten Fällen ist dies jedoch für die meisten Linux-Versionen erforderlich /proc) oder eine andere Quelldatei bereitstellen. Sie können den Besitz und die Berechtigungen festlegen.

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

als ein dummes Beispiel.

Otheus
quelle