Dlaczego miałbyś cat / dev / null na czymkolwiek?
Zrobisz to, aby obciąć zawartość pliku, zachowując nienaruszony i-węzeł. Wszystkie programy, które mają ten plik otwarty do odczytu lub zapisu, nie miałyby wpływu poza tym, że rozmiar pliku zostałby zresetowany do zera.
Fałszywą często znajdowaną alternatywą jest usunięcie pliku, a następnie utworzenie go ponownie:
rm file
touch file
lub podobny:
mv file file.old
gzip file.old
touch file
Problem polega na tym, że te metody nie zapobiegają zapisywaniu starego pliku przez jakiekolwiek procesy, w których usunięty plik jest otwarty podczas usuwania. Powodem jest to, że w systemach plików Unix, kiedy usuwasz plik, odłączasz tylko jego nazwę (ścieżkę) od jego zawartości (i-węzła). I-węzeł jest utrzymywany przy życiu tak długo, jak istnieją procesy, które otwierają go do czytania lub pisania.
Prowadzi to do kilku negatywnych skutków: dzienniki zapisane po usunięciu pliku są tracone, ponieważ nie ma prostego / przenośnego sposobu otwarcia usuniętego pliku. Tak długo, jak proces zapisuje do usuniętego pliku, jego zawartość nadal zajmuje miejsce w systemie plików. Oznacza to, że jeśli usuniesz / utworzysz plik, ponieważ wypełniał on dysk, dysk pozostanie wypełniony. Jednym ze sposobów rozwiązania tego ostatniego problemu jest ponowne uruchomienie procesów rejestratora, ale możesz tego nie chcieć w przypadku krytycznych usług, a dzienniki pośredniczące zostaną ostatecznie utracone. Istnieją również skutki uboczne, ponieważ tworzony plik może nie mieć takich samych uprawnień, właściciela i grupy jak oryginalny. Może to na przykład uniemożliwić analizatorowi dziennika odczytanie nowo utworzonego pliku lub, co gorsza, uniemożliwić procesowi zapisywania własnych dzienników.
Pierwsza metoda, cat /dev/null > fileosiągnij cel właściwie, jednak pomimo wytrwałej miejskiej legendy, jej cat /dev/nullczęść nie robi absolutnie nic pożytecznego. Otwiera pseudoplik, który z założenia jest pusty, niczego nie czyta, a na koniec wychodzi. Użycie tego polecenia jest wówczas marnotrawstwem naciśnięć klawiszy, bajtów, wywołań systemowych i cykli procesora, i można je zastąpić bez żadnych zmian funkcjonalnych niewątpliwie szybszym poleceniem no-op, :a nawet, w przypadku większości powłok, żadnym poleceniem.
Pozwól mi spróbować metafory, aby wyjaśnić, jak bezużyteczne cat /dev/nulljest. Powiedzmy, że Twoim celem jest opróżnienie szklanki.
Najpierw usuwasz z niego płyn. Jest to wystarczające i właśnie to ( > file) robi, biorąc pod uwagę fakt, że przekierowania są zawsze przetwarzane jako pierwsze.
Następnie wybierz pustą butelkę ( /dev/null) i wlej ją do pustej szklanki ( cat). To bezcelowy krok ...
Jeśli czytasz połączony dokument do końca, możesz zauważyć komentarze w tym wierszu z ulepszonej wersji skryptu:
cat / dev / null> wtmp # ':> wtmp' i '> wtmp' mają ten sam efekt.
Oni rzeczywiście; szkoda cat /dev/nullbyła trzymana w kodzie.
To oznacza, że następujący kod będzie działać we wszystkich wspólnych muszli (zarówno cshi shrodziny):
cd /var/log
: > messages
: > wtmp
echo "Log files cleaned up."
i to będzie działać ze wszystkimi muszli przy użyciu składni Bourne, jak ash, bash, ksh, zshi lubi:
cd /var/log
> messages
> wtmp
echo "Log files cleaned up."
Zauważ jednak, że w starożytnych powłokach Bourne'a sprzed POSIX-a dowolne z tych poleceń, w tym cat /dev/nullnie obcinają pliku, jeśli zostanie on później napisany przez wciąż działający skrypt powłoki dołączający się do niego. Zamiast pliku z bajtami zerowymi byłby to plik rzadki z niezmienionym rozmiarem. To samo stałoby się, gdyby plik został napisany przez proces dążący do pozycji, którą uważa za aktualną przed zapisaniem.
Uwaga: niektóre alternatywne rozwiązania często sugerowane do obcięcia pliku mają wady.
Oba poniższe po prostu nie wykonują zadania. Wynikowy plik nie jest pusty, ale zawiera pustą linię. Spowodowałoby to uszkodzenie plików dziennika takich jak te, wtmpktóre przechowują rekordy o stałej szerokości.
echo > file
echo "" > file
Kolejny oparty na shopcji BSD nie jest przenośny, POSIX nie określa żadnych dozwolonych opcji echa, więc możesz skończyć z plikiem zawierającym wiersz z „ -n”:
echo -n > file
Ten też nie jest przenośny przy użyciu shsekwencji ucieczki Systemu V. Niektóre powłoki utworzą plik zawierający wiersz z „ \c”:
echo "\c" > file
Ten używa polecenia zaprojektowanego do wykonania zadania. Problem polega na truncatetym, że nie można go przenosić, ponieważ w systemie Unix / Linux może brakować tego polecenia, które nie zostało określone przez POSIX.
truncate -s 0
Wreszcie, oto kilka alternatyw, które są przenośne i właściwie wykonają zadanie:
Jawne drukowanie pustego ciągu do pliku:
printf "" > file
Za pomocą truepolecenia, które jest ściśle równoważne poleceniu no-op, :choć bardziej czytelne:
true > file