Wenn ich möchte, dass der Inhalt von file2
mit dem Inhalt von übereinstimmt file1
, könnte ich natürlich einfach laufen cp file1 file2
.
Wenn ich jedoch beibehalten möchten alles über file2
außer dem Inhalt-Besitzer, Berechtigungen, erweiterte Attribute, ACLs, Hard - Links, etc., etc., dann würde ich nicht ausgeführt werden soll cp
. * In diesem Fall möchte ich nur die plop Inhalt von file1
in file2
.
Es sieht so aus, als würde das folgendermaßen aussehen:
< file1 > file2
Aber es geht nicht. file2
wird auf nichts abgeschnitten und nicht geschrieben. Jedoch,
cat < file1 > file2
funktioniert .
Es hat mich überrascht, dass die erste Version nicht funktioniert.
Ist die zweite Version ein UUOC? Gibt es eine Möglichkeit, dies zu tun, ohne einen Befehl aufzurufen, indem lediglich Umleitungen verwendet werden?
Anmerkung: Mir ist bewusst, dass UUOC eher ein pedantischer Punkt als ein echtes Anti-Pattern ist.
* Wie tniles09 entdeckt , cp
Wille tatsächlich Arbeit in diesem Fall.
quelle
< file1 > file2
tun, was Sie wollen, hängt von der Shell ab.<
...file1
es keine gibt oder nicht lesbar ist, und öffnen Sie es mit,<
bevor die>
Ausgabe geöffnet wird. Überlegen Sie dann, was passiert, wenn Siecat
versuchen, sie zu öffnen.cat
(standardmäßig) ein leerer Befehl mit Umleitungen aufgerufen , der im Wesentlichen den zweiten Befehl ausführt . Siehe Stéphane Chazelas' Antwort unten für mehr dazu als fits in einem Kommentar.Antworten:
cat < file1 > file2
ist kein UUOC. Klassisch<
und>
Umleitungen, die Duplikaten von Dateideskriptoren auf Systemebene entsprechen. Duplikationen von Dateideskriptoren alleine machen nichts (>
Umleitungen öffnen sich mitO_TRUNC
, um genau zu sein, schneiden Umleitungen die Ausgabedatei ab). Lassen Sie sich nicht von den<
>
Symbolen verwirren. Umleitungen verschieben keine Daten - sie weisen Dateideskriptoren anderen Dateideskriptoren zu.In diesem Fall öffnen Sie
file1
die Datei Descriptor Dateideskriptor und zuweisen0
(<file1
==0<file1
) undfile2
und weisen diesen Dateideskriptor Dateideskriptor1
(>file2
==1>file2
).Nachdem Sie nun zwei Dateideskriptoren haben, müssen Sie einen Prozess zum Verschieben von Daten zwischen den beiden ausführen - und das ist der Grund
cat
dafür.quelle
Dies ist nicht der Fall, da das betreffende Verhalten, wie andere bereits ausgeführt haben, von der Shell abhängt. Wie Sie (die OP) betont haben, ist dies ein wenig umständlich , vielleicht sogar humorvoll? Art von Thema.
Doch auf GNU - Systemen Ihre erste Prämisse hat eine andere Lösung zur Verfügung:
cp --no-preserve=all file1 file2
. Probieren Sie dies aus, ich denke, es wird Ihrer beschriebenen Situation gerecht (z. B. Ändern von Inhalten,file2
ohne die Attribute zu ändern).Beispiel :
UPDATE Eigentlich bemerkte ich nur , dass mein System ist
cp
selbst scheint Attribute zu erhalten , es sei denn-a
oder-p
festgelegt sind. Ich benutze Bash Shell und GNU Coreutils. Ich denke, Sie lernen jeden Tag etwas Neues ...Testergebnisse (per Wildcard) inklusive Hardlink und unterschiedlichen Berechtigungen:
quelle
In
zsh
der Shell, in< file1 > file2
der gearbeitet wird, wird die Shell aufgerufencat
.Für eine Befehlszeile , die nur von Umleitungen und keinen Befehl noch Zuordnungen besteht
zsh
Invokes$NULLCMD
(cat
Standardeinstellung) , es sei denn die einzige Umleitung ist ein<
, in dem Fall$READNULLCMD
(pager
voreingestellt) wird stattdessen aufgerufen. (Es sei denn, eszsh
ist insh
odercsh
Emulation. In diesem Fall verhält es sich wie die Shells, die es emuliert.)So:
ist eigentlich das gleiche wie
und
ist das gleiche wie
quelle
funktioniert nicht, weil dort kein Befehl vorhanden ist; kein prozess. Die Shell öffnet / erstellt die Dateien und ordnet die Umleitungen an (dh die Dateideskriptoren, die auf diese Dateien verweisen, werden als 0 und 1 gepflanzt: Standardeingabe und Standardausgabe). Es ist jedoch nichts zu tun, um eine Schleife zum Lesen von der Standardeingabe und zum Schreiben in die Standardausgabe auszuführen.
zsh
Dies funktioniert, indem ein vom Benutzer konfigurierbarer Befehl in diesem "Null-Befehl" -Fall ersetzt wird. Der Befehl ist in der Befehlszeile nicht sichtbar, aber immer noch vorhanden. Hierfür wird ein Prozess erstellt, der auf die gleiche Weise funktioniert.NULLCMD
istcat
voreingestellt, bedeutet also< from > to
tatsächlich in , es sei denn, es ist auf etwas anderes gesetzt; Es ist ein "implizites Katzenkommando".cat < from > to
zsh
NULLCMD
Eine "nutzlose Verwendung von cat" tritt auf, wenn
cat
sie als Vermittler verwendet wird, um aus einer Datei zu lesen und die Daten einem anderen Prozess zuzuführen, dessen Dateideskriptor einfach mit der Originaldatei verbunden werden könnte.Wenn
cat
es aus der Situation entfernbar ist, so dass die verbleibenden Befehle immer noch dieselbe Aufgabe ausführen können, ist es nutzlos. Wenn es nicht entfernbar ist, ist es nicht nutzlos.A ,
cat
das ist ersetzbar ist nicht das Gleiche. Zum Beispielcat > file
können wir stattdessen verwendenvi file
, um die Datei zu erstellen. Dies gilt nicht als Entfernung voncat
, während alles, was noch übrig ist, verwendet wird, um dieselbe Aufgabe zu erfüllen.Wenn dies
cat
der einzige Befehl in der Pipeline ist, kann er natürlich nicht entfernt werden. Keine Umlagerung dessen, was noch übrig ist, wird die entsprechende Arbeit leisten.Einige Shell-Skripter verwenden
cat
diese Option, weil sie der Ansicht sind, dass sie den Eingabeoperanden näher an die linke Seite der Befehlszeile verschieben können. Umleitungen können sich jedoch an einer beliebigen Stelle in der Befehlszeile befinden:quelle
f -
für Teer verwenden.tar xf -
ist einfachtar x
.cat
an der Dateierstellung beteiligt ist? Die Antwort sagt eindeutig, dass die Shell dies tut. Auf welches Problem> file
beziehen Sie sich? Ich verwende es oft alleine, um eine vorhandene Datei auf Null zu kürzen oder sicherzustellen, dass eine solche vorhanden ist. Bei dieser Frage geht es darum, warum< from > to
nicht funktioniertcat < from > to
und UUoC, nicht "Bitte geben Sie mir Gründe, warumcat
kein guter Ersatz fürcp
".tar
ist der Bandarchivierer . Vieletar
Implementierungen funktionieren standardmäßig immer noch mit dem ersten Bandgerät.< file1 > file2
Scheint shellabhängig zu sein, auf zsh funktioniert es, auf bash nicht.edit: falsche aussage gelöscht
quelle
cp -a
Erhält die Attribute von Datei1 und überschreibt die Attribute von Datei2. Gegenteil von gewünschtem Verhalten. Plus Ich kann nicht einmal sagen , durch den Mann an Seite schauen , was mit harten Links passieren wird, aber ich denke , es ist sicher zu sagen , dass file2 ist schwer Links werden nicht erhalten bleiben.Zusätzlich zu all den guten Antworten können Sie eine UUOC von vermeiden Simulation ein
cat
:Diese Befehle kopieren die Metadaten der Datei nicht wie üblich
cp
.quelle
cat
. Hier benötigen Sie einen Befehl, um Daten zwischen den beiden Dateideskriptoren zu verschieben. Diescat
ist einer der besten. Sehen Sie auch,pv
welche untersplice()
Linux für Fifos verwendet werden können (obwohl es nichtfadvise(POSIX_FADV_SEQUENTIAL)
wie GNUcat
funktioniert).dd
Befehl für Binärdateien scheint gut zu sein ... oder würdecat
er für Binärdateien genauso gut funktionieren?cat
funktioniert auch für Binärdateien (Unix unterscheidet im Allgemeinen nicht; einige Tools arbeiten jedoch zeilenweise, wie awk, grep, wc, ... POSIX definiert theoretisch auch eine minimale größte Zeilenlänge Ein zeilenorientiertes Tool kann sich weigern, übermäßig große Zeilen zu verarbeiten.)sed '' < file1 > file2
;-)Wenn es funktioniert, beheben Sie es nicht.
ich würde ... benutzen
und nicht den PC von der Semantik schwitzen.
quelle