it-swarm.com.de

Warum würden Sie "cat/dev/null>/var/log/messages"?

Auf dieser Bash-Skript-Beispielseite präsentiert der Autor dieses Skript:

# Cleanup
# Run as root, of course.

cd /var/log
cat /dev/null > messages
cat /dev/null > wtmp
echo "Log files cleaned up."

Warum würden Sie auf etwas cat /dev/null? Ich kann nicht verstehen, was hier beabsichtigt ist (ist es so, als würde man while TRUE; sleep 1; elihw für {some busy program} verwenden?). Der Autor nennt es jedoch „nichts Ungewöhnliches“.

76
isomorphismes

Normalerweise cat /dev/null > [something], wenn Sie den Dateiinhalt löschen möchten und gleichzeitig sicherstellen möchten, dass das Risiko einer Unterbrechung des tatsächlichen Dateizustands absolut Null ist. Der Inhalt der Datei wird eindeutig durch den cat /dev/null gelöscht, aber die Datei selbst - wie sie existiert und dem Dateisystem, in dem sie sich befindet, bekannt ist - wird weiterhin mit derselben Inode-Nummer, demselben Besitz und denselben Berechtigungen vorhanden sein.

Im Fall einer Protokolldatei kann es sein, dass die Protokolldatei selbst von einem anderen Prozess als "in Verwendung" markiert wird. Wenn Sie also beispielsweise einen rm /var/log/messages && touch /var/log/messages erstellen, kann dies andere Prozesse stören und dazu führen, dass laufende Prozesse ersticken. Das bedeutet, dass ein Prozess, der irgendwie an eine bestimmte Inode-Nummer gebunden ist, die mit der Datei /var/log/messages verbunden ist, plötzlich in Panik geraten und sagen kann: „Hey! Was ist mit /var/log/messages passiert! ”, Auch wenn die Datei noch vorhanden ist. Ganz zu schweigen von potenziellen Problemen, bei denen Eigentum und Berechtigungen falsch wiederhergestellt werden.

Aufgrund dieser Unsicherheit in Bezug auf die Verwendung/den Status einer Datei wird die Verwendung von cat /dev/null > [something] von Systemadministratoren bevorzugt, die ein Protokoll löschen möchten, jedoch nicht möglicherweisein den Betrieb bereits vorhandener Prozesse eingreifen möchten.

Auch im Kontext der Seite, auf die Sie verlinken gibt der Autor Folgendes an:

Hier gibt es nichts Ungewöhnliches, nur eine Reihe von Befehlen, die genauso einfach einzeln über die Befehlszeile auf der Konsole oder in einem Terminalfenster aufgerufen werden könnten. Die Vorteile der Platzierung der Befehle in einem Skript gehen weit über die Notwendigkeit hinaus, sie nicht immer wieder neu eingeben zu müssen.

Das „Nichts Ungewöhnliches“, das der Autor erwähnt, bezieht sich auf das gesamte Konzept dieses speziellen Bash-Skripts: Es handelt sich nur um eine Reihe einfacher Befehle, die genauso einfach über die Befehlszeile ausgeführt werden können, aber in einer Textdatei abgelegt werden vermeiden Sie es, sie immer wieder neu eingeben zu müssen.

41
JakeGould

Warum würden Sie/dev/null auf irgendetwas setzen?

Sie tun dies, um den Inhalt einer Datei zu kürzen, während der Inode intakt bleibt. Alle Programme, in denen diese Datei zum Lesen oder Schreiben geöffnet ist, wären nicht betroffen, außer die Dateigröße würde auf Null zurückgesetzt.

Eine falsche Alternative, die oft gefunden wird, ist das Entfernen der Datei und das erneute Erstellen:

rm file
touch file

oder ähnliches:

mv file file.old
gzip file.old
touch file

Das Problem ist, dass diese Methoden nicht verhindern, dass die alte Datei von allen Prozessen geschrieben bleibt, bei denen die gelöschte Datei zum Löschzeitpunkt geöffnet ist. Der Grund, warum Sie unter Unix-Dateisystemen beim Löschen einer Datei nur deren Namen (Pfad) vom Inhalt (Inode) trennen. Die Inode bleibt so lange am Leben, wie es Prozesse gibt, bei denen sie zum Lesen oder Schreiben geöffnet ist.

Dies führt zu mehreren negativen Auswirkungen: Die Protokolle, die nach dem Löschen der Datei geschrieben wurden, gehen verloren, da das Öffnen einer gelöschten Datei nicht auf einfache/tragbare Weise möglich ist. Solange ein Prozess in die gelöschte Datei schreibt, belegt sein Inhalt immer noch Speicherplatz im Dateisystem. Das heißt, wenn Sie die Datei entfernen/erstellen, weil sie Ihren Datenträger gefüllt hat, bleibt der Datenträger gefüllt. Eine Möglichkeit, dieses letztere Problem zu beheben, besteht darin, die Protokollierungsprozesse neu zu starten. Möglicherweise möchten Sie dies jedoch nicht für kritische Dienste tun, und zwischengeschaltete Protokolle würden definitiv verloren gehen. Es gibt auch Nebenwirkungen, da die von Ihnen erstellte Datei möglicherweise nicht dieselben Berechtigungen, Eigentümer und Gruppen wie die ursprüngliche besitzt. Dies könnte beispielsweise verhindern, dass ein Protokollanalysator die neu erstellte Datei liest, oder, schlimmer noch, dass der Protokollierungsprozess seine eigenen Protokolle schreibt.

Die erste Methode, cat /dev/null > file, erreicht das Ziel richtig trotz einer hartnäckigen urbanen Legende ist der cat /dev/null-Teil absolut nicht nützlich. Es öffnet eine Pseudodatei, die vom Design her leer ist, es kann nichts daraus lesen und wird schließlich einfach beendet. Die Verwendung dieses Befehls ist dann eine Verschwendung von Tastenanschlägen, Bytes, Systemaufrufen und CPU-Zyklen und kann ohne Funktionsänderung durch den zweifellos schnelleren No-Op-Befehl : oder bei den meisten Shells sogar durch überhaupt keinen Befehl ersetzt werden.

Lassen Sie mich eine Metapher versuchen, um zu erklären, wie nutzlos cat /dev/null ist. Nehmen wir an, Ihr Ziel ist es, ein Glas zu leeren.

  • Sie entfernen zuerst die Flüssigkeit. Das ist ausreichend und genau das, was (> file) tut, da Umleitungen immer zuerst verarbeitet werden.

  • Dann nehmen Sie eine leere Flasche (/dev/null) und schütten sie in das leere Glas (cat). Dies ist der sinnlose Schritt ...

Wenn Sie Ihr verlinktes Dokument bis zum Ende lesen, werden Sie möglicherweise die Kommentare in dieser Zeile in der erweiterten Version des Skripts bemerken:

 cat/dev/null> wtmp # ':> wtmp' und '> wtmp' haben den gleichen Effekt.

Sie haben in der Tat; Schade, cat /dev/null wurde im Code behalten.

Das bedeutet, dass der folgende Code mit allen gängigen Shells (sowohl csh als auch sh Familien) funktioniert:

cd /var/log
: > messages
: > wtmp
echo "Log files cleaned up."

und dies wird mit allen Schalen arbeiten, um die Bourne-Syntax, wie ash, bash, ksh, zsh und Konsorten:

cd /var/log
> messages
> wtmp
echo "Log files cleaned up."

Beachten Sie jedoch, dass bei alten Bourne-Shells vor POSIX keiner dieser Befehle, einschließlich cat /dev/null, eine Datei abschneidet, wenn sie anschließend von einem noch laufenden Shell-Skript geschrieben wird, das daran angehängt wird. Anstelle einer Null-Byte-Datei wäre dies eine Sparse-Datei mit unveränderter Größe. Dasselbe würde passieren, wenn die Datei von einem Prozess geschrieben wird, der vor dem Schreiben nach der Position sucht, die er für die aktuelle hält.

Beachten Sie auch, dass einige alternative Lösungen, die häufig zum Abschneiden einer Datei vorgeschlagen werden, Fehler aufweisen.

  • Die beiden folgenden erledigen den Job einfach nicht. Die resultierende Datei ist nicht leer, sondern enthält eine leere Zeile. Dies würde Protokolldateien wie wtmp beschädigen, in denen Datensätze mit fester Breite gespeichert sind.

    echo > file
    echo "" > file
    
  • Die nächste, die auf einer BSD-Option sh basiert, ist nicht portierbar. POSIX gibt keine zulässigen Optionen für echo an, sodass Sie möglicherweise eine Datei mit einer Zeile mit "-n" erhalten:

    echo -n > file
    
  • Dieser ist auch nicht portierbar, wenn eine System V sh-Escape-Sequenz verwendet wird. Einige Shells erstellen eine Datei, die eine Zeile mit "\c" enthält:

    echo "\c" > file
    
  • Dieser verwendet einen Befehl, der für die Ausführung der Aufgabe vorgesehen ist. Das Problem bei der Verwendung von truncate ist nicht portierbar, da dieser Befehl, der nicht von POSIX angegeben wird, möglicherweise auf einem Unix/Linux-System fehlt.

    truncate -s 0
    

Schließlich sind hier einige Alternativen aufgeführt, die portabel sind und die Arbeit ordnungsgemäß erledigen:

  • Explizites Drucken einer leeren Zeichenfolge in die Datei:

    printf "" > file
    
  • Verwenden Sie den Befehl true, der genau dem Befehl no-op entspricht, :, wenn auch besser lesbar:

    true > file
    
121
jlliagre

Es ist eine umständliche Methode, die Datei auf die Größe Null zu bringen.

cd /var/log
> messages
> wtmp
echo "Log files cleaned up."
6
Cyrus