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 spell
są 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 roster
plik do zapisu, obcinając go (tzn. usuwając całą jego zawartość), zanim sort
program 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ę poem
do odczytu (dla tr
standardowego 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 sort
program 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 sed
mają -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
, pico
i 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.
vi
ma powiązaną funkcję. Jeśli wpiszesz , zapisze zawartość bufora edycji , odczyta dane wyjściowe i wstawi do bufora (zastępując oryginalną zawartość).:%!command
Entercommand
Proste ale efektywne:
Komenda ... input_file > temp_file && mv temp_file input_file
Ma to tę wadę, że jeśli input_file
jest 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_file
nie 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 -a
lub -p
włą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 command
mó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 /tmp
bę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 /tmp
do 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.