Ostrzeżenie dotyczące „>”
Początkujący w systemie Unix, którzy właśnie dowiedzieli się o przekierowaniu wejścia / wyjścia ( <i >) często próbują takich rzeczy
polecenie … plik_wejściowy > plik_same
lub
polecenie … < plik > plik_pliku
lub prawie równoważnie
plik kota | polecenie …> plik_same
( grep, sed, cut, sort, I spellsą przykłady poleceń, które ludzie będą skłonni do stosowania w konstrukcjach takich jak te.) Użytkownicy są zaskoczeni odkryciem, że te scenariusze spowodować pliku staje się pusta.
Niuans, który wydaje się nie wymieniony w drugiej odpowiedzi, znajduje się w pierwszym zdaniu sekcji Przekierowanie bash (1) :
Przed wykonaniem polecenia jego dane wejściowe i wyjściowe mogą zostać przekierowane
przy użyciu specjalnej notacji interpretowanej przez powłokę.
Pierwsze pięć słów powinno być pogrubione, pochylone, podkreślone, powiększone, migające, w kolorze czerwonym i oznaczone
ikoną, aby podkreślić fakt, że powłoka dokonuje żądanych przekierowań
przed wykonaniem polecenia . I pamiętaj również
Przekierowanie danych wyjściowych powoduje otwarcie pliku… do zapisu…. Jeśli plik nie istnieje, jest tworzony; jeśli istnieje, jest obcinany do zera.
W tym przykładzie:
sort roster > roster
powłoka otwiera rosterplik do zapisu, obcinając go (tzn. usuwając całą jego zawartość), zanim sortprogram zacznie działać. Oczywiście nic nie można zrobić, aby odzyskać dane.
Naiwnie można się tego spodziewać
tr "[:upper:]" "[:lower:]" < poem > poem
może być lepiej. Ponieważ powłoka obsługuje przekierowania od lewej do prawej, otwiera się poemdo odczytu (dla trstandardowego wejścia) przed otwarciem do zapisu (dla standardowego wyjścia). Ale to nie pomaga. Mimo że ta sekwencja operacji daje dwa uchwyty plików, oba wskazują ten sam plik. Gdy powłoka otwiera plik do odczytu, zawartość nadal tam jest, ale nadal są blokowane przed uruchomieniem programu.
Co z tym zrobić?
Rozwiązania obejmują:
Sprawdź, czy program, który uruchamiasz, ma swoją własną wewnętrzną możliwość określania, dokąd idzie wyjście. Jest to często wskazywane przez -o(lub --output=) token. W szczególności,
sort roster -o roster
jest mniej więcej równoważne z
sort roster > roster
z wyjątkiem tego, że w pierwszym przypadku sortprogram otwiera plik wyjściowy. I to na tyle, by nie otworzyć pliku wyjściowego mądry dopiero po to odczytać cały plik (ów) wejściowego.
Podobnie, przynajmniej niektóre wersje sedmają -i(zmienił i n miejsce) opcji, które mogą być używane do pisania wyjście z powrotem do pliku wejściowego (ponownie, po wszystkie wejścia zostały przeczytane). Redaktorzy lubią ed/ ex, emacs, picoi vi/ vim
pozwalają użytkownikowi edytować plik tekstowy i zapisać edytowany tekst w oryginalnym pliku. Pamiętaj, że ed(przynajmniej) można używać w sposób nieinteraktywny.
vima powiązaną funkcję. Jeśli wpiszesz , zapisze zawartość bufora edycji , odczyta dane wyjściowe i wstawi do bufora (zastępując oryginalną zawartość).:%!commandEntercommand
Proste ale efektywne:
Komenda ... input_file > temp_file && mv temp_file input_file
Ma to tę wadę, że jeśli input_filejest linkiem, zostanie (prawdopodobnie) zastąpione osobnym plikiem. Ponadto nowy plik będzie własnością użytkownika z domyślnymi zabezpieczeniami. W szczególności niesie to ze sobą ryzyko, że plik będzie czytelny na całym świecie, nawet jeśli oryginał input_filenie był.
Wariacje:
command … input_file > temp_file && cp temp_file input_file && rm temp_file
co nadal (potencjalnie) pozostawi temp_fileświat czytelny. Nawet lepiej:
cp input_file temp_file && command … temp_file > input_file && rm temp_file
Zachowują one status łącza, właściciela i tryb (ochronę) pliku, potencjalnie kosztem dwa razy więcej operacji we / wy. (Może być konieczne użycie opcji podobnej -alub -pwłączonej, cp
aby nakazać zachowanie atrybutów).
command … input_file > temp_file &&
cp --attributes-only --preserve=all input_file temp_file &&
mv temp_file input_file
(podzielone na osobne wiersze tylko dla czytelności) To zachowuje tryb pliku (i, jeśli jesteś rootem, właścicielem), ale czyni go własnością użytkownika (jeśli nie jesteś rootem), i czyni go nowym, osobny plik.
Ten blog
(edycja plików w miejscu) sugeruje i wyjaśnia
{rm plik_wejściowy && polecenie …> plik_wejściowy ; } < plik_wejściowy
Wymaga to, aby commandmóc przetwarzać standardowe dane wejściowe (ale prawie wszystkie filtry mogą). Sam blog nazywa to ryzykowną kludge i odradza jego użycie. Spowoduje to również utworzenie nowego, osobnego pliku (niepowiązanego z niczym), będącego własnością użytkownika i posiadającego domyślne uprawnienia.
Pakiet moreutils ma polecenie o nazwie sponge:
polecenie … plik_wejściowy | gąbka plik_same
Zobacz tę odpowiedź, aby uzyskać więcej informacji.
Oto coś, co mnie całkowicie zaskoczyło:
syntaxerror mówi :
[Większość tych rozwiązań] zawiedzie w systemie plików tylko do odczytu, gdzie „tylko do odczytu” oznacza, że $HOME będziesz zapisywalny, ale /tmpbędzie tylko do odczytu (domyślnie). Na przykład, jeśli masz Ubuntu i uruchomiłeś konsolę odzyskiwania, często tak jest. Ponadto, operator tutaj, dokument <<<nie będzie działać albo nie, gdyż wymaga /tmpdo odczytu / zapisu
, ponieważ będzie to napisać plik tymczasowy w również tam.
(por. to pytanie obejmuje wyjście strace„d”)
W takim przypadku mogą działać następujące elementy:
Więc jakie było pytanie?
To był popularny temat na U&L; jest rozwiązany w następujących pytaniach:
… A to nie liczy Super User ani Ask Ubuntu. W tej odpowiedzi umieściłem wiele informacji z odpowiedzi na powyższe pytania, ale nie wszystkie. (Tj., Aby uzyskać więcej informacji, przeczytaj wyżej wymienione pytania i ich odpowiedzi).
PS Nie mam żadnego powiązania z blogiem, który cytowałem powyżej.