Ich beginne in einem leeren Verzeichnis.
$ touch aFile
$ ls
aFile
Dann habe ich ls
zwei Argumente, von denen sich eines nicht in diesem Verzeichnis befindet. Ich leite beide Ausgabestreams in eine Datei namens um output
. Ich benutze >>
, um nicht gleichzeitig zu schreiben.
$ ls aFile not_exist >>output 2>>output
$ cat output
ls: cannot access 'not_exist': No such file or directory
aFile
Welches scheint zu funktionieren. Gibt es Gefahren für diesen Ansatz?
io-redirection
stdout
stderr
exit_status
quelle
quelle
ls aFile not_exist &>>output
hier nicht den Standard ? (Beachten Sie, ich&>>
ist NICHT Standard. Es ist eine DEPRECATED, mehrdeutige Syntax, die in verschiedenen Shells unterschiedlich funktioniert. Ich frage mich, woher ihr eure Sachen bekommt.ls &>>foo ...
als zwei Comands analysiert werden sollls &
und>>foo ...
, und dies ist die Art und Weise andere Shells wie der/bin/sh
von Ubuntu es parsen. Wenn es veraltet ist, können Sie hier nachsehen - obwohl ich nicht vorgebe, dass das irgendeine Art von Autorität ist. Sie können diebash
Betreuer jedoch fragen , ob sie dies für eine gute Idee halten.Antworten:
Nein, es ist nicht nur so sicher wie der Standard
>>bar 2>&1
.Wenn du schreibst
Sie öffnen die
bar
Datei zweimal mitO_APPEND
und erstellen zwei völlig unabhängige Dateiobjekte [1] mit jeweils eigenem Status (Zeiger, Öffnungsmodus usw.).Dies ist sehr viel anders , als wenn
2>&1
nur derdup(2)
Systemaufruf aufgerufen wird, und macht die Aliase stderr und stdout für dasselbe Dateiobjekt austauschbar.Nun gibt es ein Problem damit:
Sie können in der Regel auf der Wahrscheinlichkeit der Datei zählen wie
bar
infoo >>bar 2>&1
bis aus zwei getrennten Orten zur gleichen Zeit geschrieben wird ziemlich niedrig zu sein. Aber>>bar 2>>bar
Sie haben es ohne Grund nur um ein Dutzend Größenordnungen erhöht.[1] "Dateibeschreibungen öffnen" in POSIX-Jargon.
quelle
O_APPEND
ist sowieso eine Art Pfusch - ziemlich mühsam, um es richtig zu implementieren.O_APPEND
, ruft der Client zuerst die "echte" Größe der Datei vom Server ab ("validieren" Sie den Inode) und führen dann die Aktualisierung von Suche + Schreiben + zwischengespeichertem Inode durch, und nur der letzte Teil ist Dies bedeutet, dass der erste Teil immer noch eine veraltete Größe vom Server abrufen und die richtige Größe vom lokalen / zwischengespeicherten Inode überschreiben kann. Gleiches Problem mitlseek(SEEK_END)
.Was passiert, wenn du es tust?
Das
file
wird zum zweimaligen Anhängen geöffnet. Dies ist auf einem POSIX-Dateisystem sicher möglich. Alle Schreibvorgänge, die beim Öffnen der Datei zum Anhängen auftreten, werden am Ende der Datei ausgeführt, unabhängig davon, ob die Daten über den Standardausgabestream oder den Standardfehlerstream übertragen werden.Dies setzt die Unterstützung von atomaren Schreiboperationen für Anhänge im zugrunde liegenden Dateisystem voraus. Einige Dateisysteme wie NFS unterstützen kein atomares Anhängen. Siehe z. B. die Frage "Ist der Dateianhang unter UNIX atomar?" Auf StackOverflow.
Verwenden
würde aber auch auf NFS funktionieren.
Verwenden Sie jedoch
ist nicht sicher, da die Shell die Ausgabedatei (zweimal) abschneidet und alle Schreibvorgänge auf einem der Streams die Daten überschreiben, die bereits vom anderen Stream geschrieben wurden.
Beispiel:
Die
hello
Zeichenfolge wird zuerst geschrieben (mit einem abschließenden Zeilenumbruch), und dann wird die Zeichenfolge,abc
auf die ein Zeilenumbruch folgt, aus einem Standardfehler geschrieben, wobei der Wert überschrieben wirdhell
. Das Ergebnis ist der Stringabc
mit einer neuen Zeile, gefolgt von dem Rest der erstenecho
Ausgabe, einero
und einer neuen Zeile.Das Vertauschen der beiden
echo
umwickelten Produkte nurhello
in der Ausgabedatei, da diese Zeichenfolge zuletzt geschrieben und länger als dieabc
Zeichenfolge ist. Die Reihenfolge, in der die Weiterleitungen erfolgen, spielt keine Rolle.Es wäre besser und sicherer, das Idiomatischere zu verwenden
quelle
>>
stammt) nicht der Fall , wo>>
zum Schreiben geöffnet und bis zum Ende gesucht wurde (ich nehme an, weil O_APPEND damals noch nicht erfunden war). Auch unter Solaris 10/bin/sh -c '(echo a; echo b >&2) >> file 2>> file; cat file'
gibtb
.sh
oder mit seinem Dateisystem?>>
ursprünglich getan wurde, es wurde nicht mit O_APPEND geöffnet, es wurde ohne und bis zum Ende geöffnet. Es ist nicht so sehr ein Problem, es ist, was es tat und dokumentiert wurde, um es zu tun.Es kommt darauf an, was Sie erreichen wollen. Sie müssen entscheiden, ob Fehler in derselben Datei wie die Ausgabe auftreten dürfen. Dies ist nur das Speichern von Text in einer Datei mit der Funktionalität der Shell, mit der Sie nach Belieben umleiten können. Es gibt kein absolutes Ja oder Nein. Da alles unter Linux auf verschiedene Arten gemacht werden kann, ist dies meine Art.
ls notExistingFile existingFile >> output 2>&1
Die Frage zu beantworten: In Bezug auf die Umleitung selbst ist es ja vollkommen sicher.quelle
>
stattdessen>>
einige Zeichen. Es ist also nicht nur so, dass die Shell mir erlaubt, umzuleiten, denn wenn ich mit umzuleiten>
, ist das Ergebnis anders. Also gibt es Nuancen mit>
, gibt es welche mit>>
?>
- Überschreiben.>>
- anhängen