Odpowiedzi:
cat /dev/null > file.txt
to bezużyteczne użycie kota .
Zasadniczo cat /dev/null
po prostu powoduje, że cat
nic nie jest generowane. Tak, to działa, ale wielu z nich nie lubi, ponieważ powoduje wywołanie zewnętrznego procesu, który nie jest konieczny.
Jest to jedna z tych rzeczy, które są wspólne, ponieważ są wspólne.
Użycie just > file.txt
będzie działać na większości powłok, ale nie jest całkowicie przenośne. Jeśli chcesz być całkowicie przenośny, poniższe są dobrą alternatywą:
true > file.txt
: > file.txt
Zarówno :
a true
wyjście żadnych danych i są powłoki builtins (podczas gdy cat
jest narzędzie zewnętrzne), a więc, że są lżejsze i bardziej „właściwa”.
Aktualizacja:
Jak wspomniał Tylerl w swoim komentarzu, istnieje również >| file.txt
składnia.
Większość powłok ma ustawienie, które uniemożliwi im obcięcie istniejącego pliku przez >
. Musisz użyć >|
zamiast tego. Ma to na celu zapobieganie błędom ludzkim, gdy naprawdę chcesz dołączyć >>
. Możesz włączyć zachowanie za pomocą set -C
.
Tak więc myślę, że najprostszą, najodpowiedniejszą i najbardziej przenośną metodą obcinania pliku byłoby:
:>| file.txt
:
jest również wymagane przez POSIX do wbudowania, a tak naprawdę różni się od true
tego, że jest uważane za wbudowane „specjalne” .
>| file
jest bardziej wyraźnym obcięciem.
true
jest wymagane, aby nie było wbudowane i tradycyjnie nie było. :
jest wbudowany we wszystkie muszle rodziny Bourne. :
jest specjalnym wbudowanym w POSIX (więc : > file
na przykład opuści powłokę, jeśli file
nie może być otwarty do pisania w powłokach POSIX) i true
nie jest. POSIX wspomina nawet, że :
może być bardziej wydajny niż true
w niektórych systemach.
Bourne POSIX zsh csh/tcsh rc/es fish
> file Y Y N(1) N(1) N N
: > file N/Y(2) Y(3) Y Y(4) N(5) N(5)
true > file Y(5) Y Y Y(5) Y(5) Y(5)
cat /dev/null > file Y(5) Y Y(5) Y(5) Y(5) Y(5)
eval > file Y(3,8) Y(3) Y Y(6) Y Y
cp /dev/null file (7) Y(5) Y Y(5) Y(5) Y(5) Y(5)
printf '' > file Y(5) Y Y Y(5) Y(5) Y
Uwagi:
sh
lub ksh
, dla przekierowań bez polecenia, w zsh przyjmuje się polecenie domyślne (pager tylko dla przekierowania standardowego, w cat
przeciwnym razie), które można dostroić za pomocą zmiennych NULLCMD i READNULLCMD. Jest to inspirowane podobną funkcją w(t)csh
:
w UnixV7, co :
zostało zinterpretowane w połowie drogi między linią odniesienia komentarza a poleceniem zerowym. Później były i jak we wszystkich wbudowanych, jeśli przekierowanie nie powiedzie się, to wychodzi z powłoki.:
i eval
będąc specjalnymi wbudowanymi funkcjami, jeśli przekierowanie nie powiedzie się, wychodzi z powłoki ( bash
robi to tylko w trybie POSIX).(t)csh
tym definiuje się etykietę zerową (for goto
), więc goto ''
tam będzie rozgałęzienie. Jeśli przekierowanie nie powiedzie się, nastąpi wyjście z powłoki.$PATH
( :
na ogół nie jest, true
, cat
, cp
i printf
na ogół są (POSIX wymaga ich)).file
jest dowiązaniem symbolicznym do nieistniejącego pliku, niektóre cp
implementacje, takie jak GNU, odmówią jego utworzenia.(ta sekcja jest wysoce subiektywna)
> file
. To >
zbyt przypomina podpowiedź lub komentarz. Pytanie, które zadam podczas czytania (i większość powłok narzeka na to samo), to jakie dane dokładnie przekierowujecie? .: > file
. :
jest znany jako polecenie no-op. Czyli to od razu jako generowanie pustego pliku. Jednak tutaj ponownie :
można to łatwo przeoczyć i / lub uznać za monit.true > file
: co ma wartość logiczna w przypadku przekierowania lub zawartości pliku? Co tu mamy na myśli? to pierwsza rzecz, jaka przychodzi mi do głowy, kiedy to czytam.cat /dev/null > file
. Łączy się /dev/null
w file
? cat
są często postrzegane jako polecenia zrzucić zawartość pliku, który może jeszcze sens: zrzucić zawartość do pliku w pustymfile
, trochę jak pokrętny sposób powiedzieć, cp /dev/null file
ale nadal zrozumiałe.cp /dev/null file
. Kopiuje zawartość pustego pliku do file
. Ma sens, jeśli ktoś nie wie, jak cp
ma zrobić domyślnie może pomyśleć, starasz się, aby file
do null
urządzenia, jak również.eval > file
lub eval '' > file
. Nic nie uruchamia i przekierowuje dane wyjściowe do file
. Dla mnie to ma sens. Dziwne, że to nie jest powszechny idiom.printf '' > file
: jawnie drukuje nic do pliku. Ten, który ma dla mnie największy sens.Różnica polega na tym, czy używamy wbudowanej powłoki, czy nie. Jeśli nie, należy rozwidlić proces, załadować i wykonać polecenie.
eval
gwarantuje się, że będzie wbudowany we wszystkie powłoki. :
jest wbudowany tam, gdzie jest dostępny (lubi Bourne / csh). true
jest wbudowany tylko w powłoki podobne do Bourne'a.
printf
jest wbudowany w najbardziej nowoczesne powłoki podobne do Bourne'a i fish
.
cp
i cat
generalnie nie są wbudowane.
Teraz cp /dev/null file
nie wywołuje przekierowań powłoki, więc rzeczy takie jak:
find . -exec cp /dev/null {} \;
będą bardziej wydajne niż:
find . -exec sh -c '> "$1"' sh {} \;
(choć niekoniecznie niż:
find . -exec sh -c 'for f do : > "$f"; done' sh {} +
).
Osobiście używam : > file
w powłokach podobnych do Bourne'a i obecnie nie używam niczego innego niż powłoki podobne do Bourne'a.
dd of=file count=0
?
dd
(takich jak przynajmniej Solaris 10), count=0
jest ignorowany. dd if=/dev/null of=file
byłby bardziej przenośny. W każdym razie jest to niezależne od powłoki.
cp /dev/null file
, prawda?
cp /dev/null file
jest powszechnym idiomem. Ograniczam się do tych, nie chodzi o to, żeby wymienić wszystkie możliwe sposoby.
Możesz spojrzeć na to truncate
, co robi dokładnie to: obciąć plik.
Na przykład:
truncate --size 0 file.txt
Jest to prawdopodobnie wolniejsze niż używanie true > file.txt
.
Jednak moim głównym celem jest: truncate
jest przeznaczone do obcinania plików, podczas gdy używanie> ma efekt uboczny obcinania pliku.
truncate
byłby dostępny, ale >
ani unistd
biblioteki C nie byłyby dostępne?
truncate
jest narzędziem FreeBSD, stosunkowo niedawno (2008) dodanym do jądra GNU (choć --size
długi styl opcji GNU jest specyficzny dla GNU), więc nie jest dostępny w systemach innych niż GNU lub FreeBSD i nie jest dostępny w starszych systemach GNU, Nie powiedziałbym, że jest przenośny. cp /dev/null file
działałby bez przekierowania powłoki i byłby bardziej przenośny.
Odpowiedź zależy trochę od tego file.txt
, co jest i od tego , jak proces do tego napisze!
Przytoczę typowy przypadek użycia: masz rosnący plik dziennika o nazwie file.txt
i chcesz go obrócić.
Dlatego kopiujesz na przykład file.txt
do file.txt.save
, a następnie obcinasz file.txt
.
W tym scenariuszu, JEŻELI plik nie zostanie otwarty przez another_process
(np. another_process
Program może wyświetlać dane w tym pliku, na przykład program rejestrujący coś), wówczas dwie propozycje są równoważne i obie działają dobrze (ale druga jest preferowana jako pierwszy „cat / dev / null> file.txt” to Bezużyteczne użycie Cat, a także otwiera i czyta / dev / null).
Ale prawdziwym problemem byłoby, gdyby other_process
nadal był aktywny i nadal miał otwarty uchwyt przechodzący do pliku.txt.
Następnie powstają 2 główne przypadki, w zależności od tego, jak other process
plik został otwarty:
Jeśli other_process
otworzy się w normalny sposób, uchwyt będzie nadal wskazywał poprzednią lokalizację w pliku, na przykład z przesunięciem 1200 bajtów. Następny zapis rozpocznie się zatem z przesunięciem 1200, a zatem znów będziesz mieć plik 1200 bajtów (+ cokolwiek napisał inny_proces), zawierający 1200 wiodących znaków zerowych! Zakładam, że nie to, czego chcesz .
Jeśli zostanie other_process
otwarty file.txt
w „trybie dołączania”, to za każdym razem, gdy pisze, wskaźnik aktywnie szuka końca pliku. Dlatego, kiedy go obetniesz, będzie „szukał” aż do bajtu 0 i nie będziesz miał złego efektu ubocznego! Tego właśnie chcesz (... zwykle!)
Pamiętaj, że oznacza to, że po przycięciu pliku musisz upewnić się, że wszystkie osoby other_process
nadal zapisujące w tej lokalizacji otworzyły go w trybie „dołącz”. W przeciwnym razie musisz je zatrzymać other_process
i uruchomić ponownie, aby zaczęły wskazywać początek pliku zamiast poprzedniej lokalizacji.
Odniesienia: /programming//a/16720582/1841533 w celu uzyskania bardziej przejrzystych wyjaśnień oraz miły krótki przykład różnicy między rejestrowaniem w trybie normalnym a dołączaniem w /programming//a/984761/1841533
cat /dev/null > file
a > file
to cat /dev/null
a, która nie ma znaczenia dla pliku.
Lubię to i używam go często, ponieważ wygląda na czystszego, a nie tak, jakby ktoś przypadkowo nacisnął klawisz powrotu:
echo -n "" > file.txt
Powinien też być wbudowany?
echo
wdrożeń nie obsługuje -n
(i dane wyjściowe -n<SPC><NL>
tutaj. printf '' > file.txt
Byłyby bardziej przenośne (przynajmniej w nowoczesnych systemach / POSIX).