Pamiętaj, aby używać
--
podczas przekazywania dowolnych argumentów do poleceń (lub przekierowań, jeśli to możliwe). Taksort -- "$f1"
lub lepiejsort < "$f1"
zamiastsort "$f1"
.
Dlaczego warto używać --
i przekierowywać?
Dlaczego jest sort < "$f1"
preferowany sort -- "$f1"
?
Dlaczego jest sort -- "$f1"
preferowany sort "$f1"
?
Dzięki.
Odpowiedzi:
kończy się niepowodzeniem dla wartości
$f1
rozpoczynających się od-
lub tutaj w przypadkusort
niektórych, które zaczynają się od+
(może mieć poważne konsekwencje dla pliku wywoływanego-o/etc/passwd
na przykład).(gdzie
--
sygnalizuje koniec opcji) rozwiązuje większość tych problemów, ale nadal nie działa w przypadku wywoływanego pliku-
(cosort
oznacza, że oznacza to jego standardowe wejście).Nie ma tych problemów.
Tutaj jest powłoka, która otwiera plik. Oznacza to również, że jeśli pliku nie można otworzyć, pojawi się również potencjalnie bardziej przydatny komunikat o błędzie (na przykład większość powłok wskaże numer wiersza w skrypcie), a komunikat o błędzie będzie spójny, jeśli użyjesz przekierowania, tam gdzie to możliwe, do otwierania plików.
I w
(w przeciwieństwie do
sort -- "$f1" > out
), jeśli"$f1"
nie można go otworzyć,out
nie zostanie utworzony / obcięty, asort
nawet nie uruchomiony.Aby usunąć pewne możliwe nieporozumienia (następujące komentarze poniżej), nie uniemożliwia to komendzie
mmap()
wejścia do pliku lublseek()
wejścia do niego (nie tylkosort
to), pod warunkiem, że sam plik jest widoczny. Jedyna różnica polega na tym, że plik jest otwierany wcześniej i na deskryptorze pliku 0 przez powłokę, w przeciwieństwie do późniejszej komendy na innym deskryptorze pliku. Polecenie może nadal szukać / mmap tego fd 0, jak mu się podoba. Nie należy tego mylić zcat file | cmd
tym, że tym razemcmd
stdin jest rurą, której nie można kształtować / szukać.źródło
sort
do sekwencyjnego odczytu danych, ammap
pliku nie można . Chociażsort
może nie mieć z tym większych problemów, rozważ wydajnośćless <file
iless file
. W pierwszym przypadkuless
musi zachować całą zawartość pliku w pamięci, w drugim przypadku wolno odczytać tylko te części, które chce. Teraz wyobraź sobie, żefile
to plik dziennika 100 GB ...less <file
przechowuje cały plik w pamięci, ale nie jest do tego zmuszony, jest to wada mniej. Tylkocat file | less
jest zmuszony. Sprawdźless /dev/fd/0 <f
, który nie przechowuje pliku w pamięci, nawet jeśli odbiera go na standardowym wejściu. Jest powszechnym błędnym przekonaniem, że stdin w Uniksie jest nie do zobaczenia. W rzeczywistości może być widoczny, w zależności od typu pliku.read()
odczytujesz dane sekwencyjnie z pliku, jednocześniemmap()
odczytując cały plik do pamięci na raz?sort
przez POSIX. Ale prawdą jest, że nie zawsze jest obsługiwana.getopt()
funkcji C rozpoznaje to znaczenie argumentu--
. Ale główny punkt to ten, który akceptujesz: obsługa argumentów jest domeną poszczególnych programów i nie wszystkie traktują--
specjalnie.Problemem są nazwy plików zaczynające się od myślnika.
sort "$f1"
nie działa, jeśli wartośćf1
zaczyna się od,-
ponieważ polecenie zinterpretuje wartość jako opcję. Zwykle powoduje to błąd, ale może nawet spowodować lukę w zabezpieczeniach . Dziękisort -- "$f1"
, argument podwójna kreska--
oznacza „brak opcji poza ten punkt” Tak więc wielkośćf1
nie będą interpretowane jako opcja. Ale jest jeszcze jeden przypadek na krawędzi: jeśli wartościąf1
jest myślnik i nic więcej, to nie jest to opcja, to argument-
, który oznacza „standardowe wejście” (ponieważ argument jest plikiem wejściowym; dla pliku wyjściowego oznaczałoby to „standardowe wyjście”).Korzystanie z przekierowania pozwala uniknąć tych wszystkich pułapek.
Dotyczy to większości poleceń, nie tylko
sort
.źródło
sort < "$f1"
to zadziałałoby, gdyby wartość była równa-
? Nie ma go w żadnej skorupie, której próbowałem.seq 10 > -; sort -
zseq 10 > -; sort < -
.