Jak opróżnić („obciąć”) plik w systemie Linux, który już istnieje i jest w jakiś sposób chroniony?

113

Mam na serwerze plik o nazwie error.log, który muszę często skracać. Mam uprawnienia rw do pliku. Otwieranie pliku w vi> usuwanie całej zawartości> zapisywanie prac (oczywiście). Ale kiedy spróbuję poniżej

cat /dev/null > error.log

Dostaję wiadomość

File already exists.

Oczywiście na serwerze wykonano jakąś konfigurację, aby zapobiec przypadkowemu nadpisaniu plików. Czy ktoś może powiedzieć, jak mam „obciąć” plik jednym poleceniem?

Sumeet Pareek
źródło
2
W przypadku niezabezpieczonego pliku działa obcięcie pliku -s 0.
Pramod

Odpowiedzi:

158

Masz noclobberzestaw opcji. Wygląda na to, że błąd pochodzi z csh, więc powinieneś zrobić:

cat /dev/null >! file

Jeśli się mylę i używasz basha, powinieneś zrobić:

cat /dev/null >| file

w bash możesz również skrócić to do:

>| file
R Samuel Klatchko
źródło
masz rację co do powłoki będącej csh. Skąd wiedziałeś?
Sumeet Pareek
6
@Wikidkaka - na podstawie komunikatu o błędzie. csh w moim systemie daje podobny File existsbłąd, podczas gdy bash daje zupełnie inny cannot overwrite existing filebłąd.
R Samuel Klatchko
6
@Jarmund - ponieważ użytkownik ma ustawiony noclobber, >filenie działa.
R Samuel Klatchko
Jaka jest różnica między > filei >| file?
Will
1
@Will - jeśli masz noclobberustawioną opcję, próba przekierowania do istniejącego pliku nie powiedzie się. Aby nadpisać określone przekierowanie, pozostawiając włączony >|
noclobber
71

Możesz także użyć funkcji obcinania

$truncate -s0 yourfile

jeśli odmówiono pozwolenia, użyj sudo

$sudo truncate -s0 yourfile

Pomoc / Podręcznik: man truncate

testowane na systemie Ubuntu Linux

risnandar
źródło
1
truncate dotyka również czasu modyfikacji pliku - podczas gdy "> file" nie zmienia się, jeśli plik jest niezmieniony.
dsteinkopf
Nie zwalnia miejsca na dysku, które posiada plik. Na początku pokazuje 0 bajtów. Ale kiedy zapisujesz coś w tym pliku, rozmiar pliku wynosi = przed obcięciem + nowy rozmiar danych.
Aniket Kulkarni
48

To wystarczy, aby ustawić rozmiar pliku na 0:

> error.log
SIFE
źródło
6
właściwie to nie działa z noclobber (sam to przetestowałem), więc NIE jest to poprawne rozwiązanie w tym przypadku ("-bash: error.log: nie można nadpisać istniejącego pliku"); zobacz komendę powyżej ("@Jarmund - ponieważ użytkownik ma ustawiony noclobber,> plik nie działa."). Zastanawiam się jaki rodzaj „inteligentnych ludzi” upvote oczywiście błędne odpowiedzi tak ...
9

zasługa mojego starszego kolegi:

:> filename

Nie spowoduje to zepsucia plików dziennika, więc możesz go używać na przykład na syslog.

petermolnar
źródło
8
Proszę wytłumacz. Jak to działa? Co robi ta notacja?
user31986
2
@ user31986 :to polecenie nie wywołujące efektu (prawie komentarz), a następnie >przekierowanie jak zwykle, więc to po prostu przekierowuje brak wyjścia polecenia, które nic nie robi do pliku. Jeśli noclobber jest włączony, potrzebujesz :>| filename(bash) (i zakładam, że :>! filenamew csh przy założeniu, że csh ma :).
Rhubbarb
4

false | tee fileToTruncate

może również działać

Dodger Web
źródło
To po prostu głupie. A jeśli jest to przydatne, niejasne ddwyjście z wyjścia nie byłoby nawet lepsze niż zwykły czytelny false?
tripleee
2

Ponieważ sudo nie będzie działało z przekierowaniem > , podoba mi się teepolecenie do tego celu

echo "" | sudo tee fileName
sakhunzai
źródło
cóż, w rzeczywistości tak, jak opisano zarówno w pytaniu, które utworzyłeś, jak i tutaj powyżej. "sudo sh -c '> error.log'" ...
zależy to od uprawnień do pliku docelowego error.log, jeśli jest już zapisywalny, nie ma potrzeby używania sudo. Myślę, że drugą kwestią jest to, że przekazujesz polecenie jako argument łańcuchowy do sh, nie wiem, jak to jest obsługiwane wewnętrznie, ale jest to kolejna warstwa złożoności / dodana przekierowanie
sakhunzai
1
W rzeczywistości nie spowoduje to obcięcia pliku, ponieważ echo ""doda nową linię. Możesz użyć echo -n ""do pomijania nowej linii
Seb
0

Każdy może spróbować tego polecenia, aby obciąć dowolny plik w systemie Linux

To na pewno zadziała w każdym formacie:

truncate -s 0 file.txt
user3301460
źródło
0

Lubię to: cp /dev/null file

Den129
źródło
-4

Możesz także spróbować:

echo -n > /my/file

Oden
źródło
8
Widzisz odpowiedź z mnóstwem głosów? Spróbuj go przeczytać, popatrz w górę, noclobbera następnie zadaj sobie pytanie, czy twoja odpowiedź ma w ogóle sens.