Narzędzia użytkownika

Narzędzia witryny


Pasek boczny

so:pipes_filters

Edycja linii poleceń

Bash (i wiele innych programów) korzysta do odczytywania komend ze standardowego wejścia biblioteki readline.
Część programów z przyczyn licencyjnych wybiera do tego samego celu libedit.

Readline pozwala na wygodną edycję linii poleceń i tworzenie historii poleceń.

Lista sensownych skrótów klawiszowych do edycji linii poleceń (nie uwzględniająca strzałek) jest tutaj: https://readline.kablamo.org/emacs.html
Pełna lista komend i przypisanych do nich skrótów jest w podręczniku systemowym
(man readline i man bash).
Konwencja zapisu skrótów klawiszowych to:

Bash domyślnie dopisuje historię wykonanych poleceń do pliku ~/.bash_history w momencie wyjścia z powłoki.
Historię (tą z pliku połączoną z bieżącą) można wyświetlić komendą history. (W man bash_builtins znajduje się opis przełączników.)

Do wygodnego przeglądania historii można też użyć programu hstr

Zadanie 1 Jakim skrótem czyści się ekran?

Zadanie 2 Jakimi skrótami wyszukuje się wstecz w historii?

Zadanie 3 Jakim skrótem przesuwa się kursor o jedno słowo?

Zadanie 4 Jakim złożeniem skrótów przesuwa się kursor o 5 słów?

Zadanie 5 Jakim skrótów wstawia się ostatnie słowo z poprzedniego polecenia w historii?

Zadanie 6 Jakim złożeniem skrótów wstawia się trzecie od końca słowo z poprzedniego polecenia w historii?

Zadanie 7 Jakim skrótem zamienia się kolejnością to słowo z poprzednim?

Edycja plików w konsoli

vi i vim

vi jest często jedynym domyślnie instalowanym edytorem tekstowym.

vim to ulepszona wersja vi.

Żeby nauczyć się vim, uruchom vimtutor.

vi jest wpisane w standard POSIX.
Jest też częścią minimalistycznych zestawów narzędzi takich jak busybox i toybox.

Zadanie 8 Przejdź całą pierwszą lekcję w vimtutor.

Zadanie 9 Przejdź pozostałe lekcje w vimtutor.

nano

Nano jest stosunkowo prostym edytorem tekstowym.

Podstawowe skróty są wyświetlone na dole ekranu.

Więcej na: https://www.nano-editor.org/docs.php

Emacs

Emacs jest odwiecznym rywalem vima w konkurencji programów do edytowania tekstu w konsoli.

Po wpisaniu emacs możesz wybrać tutorial skrótem Ctrl+h t.

Inne

Potoki

Dla przypomnienia: standardowe funkcje I/O czytają ze standardowego wejścia, a piszą do standardowego wyjścia.

Uniksopodobne systemy przez długie lata1) trzymały się założenia, że każdy program ma solidnie wykonywać jedno dobrze określone zadanie.
Żeby zrobić skomplikowane zadania, należy podzielić je na mniejsze rozwiązywalne przez takie proste programy.

Dla przykładu: powiedzmy że chcesz dowiedzieć się ile procesów ma każdy z użytkowników systemu.

  1. Wiesz że ps -ef wypisuje procesy, więc zapisujesz do pliku ich listę: ps -ef > ps_output.
  2. Potrzebujesz tylko pierwszej kolumny – nazwy użytkownia,
    Żeby wyciąć tylko pierwszą (oddzielaną spacją) kolumnę, używasz komendy cut --delimiter ' ' --field 1 < ps_output > cut_output.
  3. Żeby skorzystać z programu który liczy powtarzające się linie, musisz mieć je obok siebie.
    Więc komendą sort < cut_output > sort_output sortujesz plik.
  4. Na końcu korzystasz z komendy uniq --count < sort_output która pomija powtarzające się linie i przed każdą linię wpisuje ile razy się powtórzyła.

Ale: żeby wykonać takie zadanie powstały (niepotrzebne) pliki ps_output, cut_output i sort_output.

W systemie UNIX wprowadzono możliwość połączenia standardowego wyjścia jednego programu ze standardowym wejściem innego programu.
Zamiast wykonywać powyższe komendy, można uruchomić ps -ef | cut --delimiter ' ' --field 1 | sort | uniq --count które robi to samo bez tworzenia żadnych plików na dysku.
Łączenie standardowego wyjścia jednego programu ze standardowym wejściem innego jest technicznie wykonywane za pomocą specjalnego rodzaju pliku nazwanego potokiem (pipe). Powłoka tworzy taki plik (w RAMie), zastępuje standardowe wyjście jednego programu tym plikiem oraz zastępuje standardowe wejście drugiego programu tym samym plikiem. Odczyt z potoku blokuje się do czasu aż pojawią się na nim dane lub aż wszyscy piszący do potoku go nie zamkną.

Składnia cmd_a | cmd_b łączy standardowe wyjście cmd_a ze standardowym wejściem cmd_b.
Takie komendy są uruchamiane współbieżnie.

Programy trzymające się "filozofii UNIX'a" czytają z plików o ile podano je w argumentach lub ze standardowego wejścia jeśli nie podano plików w argumentach. Dodatkowo standardowe wejście jest używane ilekroć - pojawia się w kontekście nazwy pliku.

Do wykonania cmd_a | cmd_b powłoka tworzy potok nienazwany (anonimowy).
Można stworzyć potok nazwany używając komendy mkfifo nazwa_pliku.
Dane zapisane do potoków, zarówno nazwanego jak i anonimowego, są przechowywane w pamięci operacyjnej – nie są zapisywane na dysk. Odczytanie danych z potoku usuwa je z pamięci.

Przykłady

Zadanie 10 Wykonaj echo '2+2*2'. Potem wynik tego polecenia przekaż przez potok do bc.

Zadanie 11 Użyj echo do wyświetlenia jakiegoś teksu. Potem powtórz komendę przekazując jej wynik w potoku do xxd.

Zadanie 12 Wypisz listę plików w katalogu domowym.
Powtórz komendę przekazując w potoku jej wyniki do programu cat.
Dodaj na koniec poprzedniej komendy przekazanie jej wyniku do cat -n.

Zadanie 13 Połącz w potok komendy ps -eF i fold

Zadanie 14 Stwórz nazwany potok p. Przekieruj wejście programu fold z p w jednym terminalu, a w drugim przekieruj wyjście ps -eF do p. Powtórz komendy wykonując ps przed fold.

Filtry

Nazwą filtry określa się zbiorczo programy (w dużej części mające początki jeszcze w systemie UNIX) które czytają standardowe wejście, przetwarzają je w użyteczny sposób i piszą wynik do standardowego wyjścia.

head, tail

head i tail wypisują podaną liczbę początkowych / końcowych linii lub bajtów. Domyślnie oba programy wypisują 10 linii.
Przełącznikiem -n liczba / -c liczba określa się liczbę wypisywanych linii / bajtów.

Jeśli programowi head poda się numer poprzedzony minusem ('-'), np. head -n -10, to wypisze linie poza ostatnimi 10.
Jeśli programowi tail poda się numer poprzedzony plusem ('+'), np. tail -n +10, to wypisze linie zaczynając od linii nr 10.

Przykłady

Zadanie 15 Uruchom paste <(seq 15) <(seq 15 -1 1). Potem przetwórz w potoku wynik tego polecenia wykorzystując head i tail tak, by wyświetlić:

  • pierwsze trzy linie
  • ostatnie trzy linie
  • wszystko poza pierwszymi trzema liniami
  • wszystko poza ostatnimi trzema liniami
  • linie od 6 do 9

Ważnym przełącznikiem programu tail jest -f / --follow.
tail -f … najpierw wykona swoje normalne działanie, potem będzie na bieżąco wyświetlać wszystkie dane które będą dopisywane do pliku.

Zadanie 16 Wykonaj seq 25 > plik. Potem uruchom w jednym terminalu tail -f plik, a w drugim dopisz (przekierowaniem wyjścia) dane do pliku.

grep

Komenda grep regex [plik]... wypisuje linie z plików (lub standardowego wejścia) które pasują do wyrażenia regularnego regex.

Przełącznik -r / -R pozwala podać jako plik katalog. W takim wypadku cała jego zawartość będzie przeszukiwana.
Jeśli podano -r/ -R i nie podano żadnego pliku, to rekurencyjnie przeszukiwany jest bieżący katalog (a nie standardowe wejście).

grep pozwala na wybór jednej z kilku gramatyk wyrażeń regularnych. POSIX określa dwie: basic (domyślną) i extended (używaną przez egrep i grep -E). Szczegółów szukaj w dokumentacja twojej implementacji komendy grep.

Domyślnie wyrażenia rozróżniają wielkość liter. Aby to zmienić, dodaj opcję -i.

Opcja -v powoduje wypisywane niepasujących linii.

Przełącznikami programu grep można wybrać m. inn. czy pokazane mają być wszystkie pasujące linie, ileś pierwszych pasujących linii bądź tylko nazwa pliku z pasującymi liniami. Można też wybrać czy wyniki mają być poprzedzone nazwą pliku i numerem linii w pliku.
(Jeśli podano wiele plików, nazwa pliku jest domyślnie dodawana; jeśli plik jest binarny zdaniem grepa, domyślnie wyświetlane jest tylko czy pasuje.)

grep może wyświetlić dodatkowo N linii przed (-B N), po (-A N) lub przed i po (-C N) każdej pasującej linii.
Przełączniki są nazwane od before, after i context

Przykłady

Zadanie 17 Przefiltruj seq 75 używając grep tak by wyświetlone były linie:

  • zawierające 5
  • kończące się na 5
  • kończące się na 5 lub 0
  • zawierające 33 wraz z 3 liniami które je poprzedzają
  • zawierające 33 wraz z 2 liniami kontekstu

Zadanie 18 Wyświetl linie zawierające 10 w plikach /etc/passwd i /etc/group.

Zadanie 19 Wylistuj pliki zawierające ecdsa w katalogu ~/.ssh.

cut

Program cut wyświetla w każdej linii wybrane znaki (-c spec) / bajty (-b spec) / pola (-f spec).
Pole to dowolna ilość znaków oddzielona jednoznakowym separatorem (-d sep, domyślnie tab).

Specyfikacja pól/bajtów/… to zakres[,zakres]..., gdzie każdy zakres to pozycja, lub start-koniec, lub start-, lub -koniec.
Dla przykładu, echo 123456789abcdef | cut -c -3,6,9-11,14- wypisze 12369abef (kolory dodano ręcznie dla lepszego zrozumienia).

Przykłady

Zadanie 20 Przefiltruj wynik komendy mount (lub pliku /etc/mtab) tak by wyciąć piąte (lub trzecie dla pliku /etc/mtab) oddzielane spacjami pole (które zawiera typ systemu plików).

Zadanie 21 Usuń z wyniku komendy egrep '^[Ee]{2}' /usr/share/myspell/en_US.dic ukośnik i wszystko za nim.

sort

Program sort domyślnie sortuje linie alfabetycznie (łącznie wszystkich plików wejściowych lub standardowego wejścia).

Kolejne opcje -k definiują klucze sortowania. (Pola są oddzielane białymi znakami i naturalnie numerowane.)

  • sort -k4 używa pól 4,5,6,7,8,…
  • sort -k4,4 używa tylko pola 4
  • sort -k4,6 używa pól 4, 5 i 6
  • sort -k5,4 jest nieprawidłowe
  • sort -k5,5 -k4,4 używa pól 5 and 4

Klucze sortowania mogą mieć opcje, np. -n sortuje numerycznie a -r odwraca kierunek.
Opcje można ustawić dla wszystkich kluczy naraz bądź dla każdego klucza z osobna:

  • sort -r -k5,5 -k4,4 sortuje malejąco zarówno po polu 5 i 4
  • sort -k5,5r -k4,4 sortuje malejąco po polu 5 i domyślnie (rosnąco) po polu 4
  • sort -k5,5 -k4,4r sortuje domyślnie (rosnąco) po polu 5 i malejąco po polu 4

Domyślnie sortowanie nie jest stabilne; można zażądać stabilnego sortowania opcją -s.

Informacje o dalszych możliwościach programu sort znajdziesz w podręczniku.

Przykłady

Zadanie 22 Stwórz plik wejściowy dla następnych zadań kopiując i wklejając w powłokę następujące polecenie:

make_random_data
paste \
  <(perl -e 'printf "%d\n", rand(10) for(1..20)') \
  <(perl -e 'print((K,Q,J)[rand(3)]."\n") for(1..20);') \
  <(perl -e 'printf "%d\n", rand(1500) for(1..20)') \
  <(perl -e 'my @a=("a","b","c"); print $a[rand(@a)] . $a[rand(@a)] ."\n" for(1..20);') \
  <(perl -e 'printf "%d\n", rand(1500) for(1..20)') \
  <(perl -e 'my @a=("x","y","z"); print $a[rand(@a)] . $a[rand(@a)] ."\n" for(1..20);') \
  <(seq -w 20) \
  > random_data

Zadanie 23 Wyświetl plik random_data. Potem go posortuj (domyślnie).

Zadanie 24 Posortuj plik random_data ignorując dwa pierwsze pola. Potem znów posortuj ten plik ignorując dwa pierwsze pola, ale tym razem numerycznie.

Zadanie 25 Posortuj plik random_data używając pól z K/Q/J i pól ze znakami xyz (w tej kolejności).

Zadanie 26 Posortuj plik random_data używając tylko drugiego pola zarówno bez jak i z opcją -s (--stable).

Zadanie 27 Posortuj plik random_data po drugim polu (alfabetycznie) i trzecim polu (numerycznie).

shuf wypisuje linie w losowej kolejności.

Zadanie 28 Wykonaj seq 20 | shuf.

wc, uniq, nl

Program wc (word count) liczy linie, słowa i bajty.
Jeśli w argumentach poda mu się wiele plików, wypisuje zarówno informacje o każdym pliku z osobna jak i łączne wyniki.
Przełącznikami -l, -w i -c można wybrać liczenie linii, słów i bajtów.
Przełącznik -m liczy znaki (włączając niedrukowalne).
Liczba bajtów i znaków będzie różna jeśli plik zawiera wielobajtowe znaki, np. wc -mc <<< "‡∞♣" zliczy 10 bajtów i 4 znaki (trzy widoczne i znak nowej linii).

Program uniq domyślnie usuwa powtarzające się linie. Z przełącznikami pozwala też między innymi na:

  • -c — wpisanie przed każdą linię ilości powtórzeń
  • -d — wypisanie tylko powtarzających się linii
  • -u — wypisanie tylko niepowtarzających się linii

nl numeruje linie. Pozwala też numerować linie w ustrukturyzowanych plikach tekstowych.

Przykłady

Zadanie 29 Przefiltruj man wc przez cat. Potem przefiltruj man wc przez wc. Ile słów jest w man wc?

Zadanie 30 Sprawdź wynik wc /etc/motd /etc/SUSE-brand.

Zadanie 31 Polecenie perl -e 'printf "%d\n", (int rand(6)+1)+(int rand(6)+1) for(1..100)' rzuca 100 razy 2d6.
Przefiltruj wyniki tego polecenia przez uniq tak żeby zobaczyć kolejne rzuty z tymi samymi wynikami.
Przefiltruj wyniki tego polecenia przez sort i uniq tak żeby zobaczyć ile razy był uzyskany każdy wynik.

tac, rev

tac wyświetla linie w odwrotnej kolejności (w każdym podanym pliku z osobna).

rev wyświetla znaki w każdej linii w odwrotnej kolejności.

Zadanie 32 Obejrzyj wynik komendy echo -e '1 2 3\n4 5 6\n7 8 9'. Potem przefiltruj tą komendę przez tac, następnie przez rev.

tr, sed

Program tr zamienia lub usuwa podane znaki.

Polecenie tr -d LISTA usunie wszystkie znaki z LISTy.

Polecenie tr KTÓRE NACO zamienia każdy n-ty znak z listy KTÓRE na n-ty znak z listy NACO.
Jeśli NACO jest krótsze niż KTÓRE, nadmiarowe znaki z KTÓRE są zmieniane na ostatni znak z NACO.

Przełącznik -s powoduje, że (po dokonaniu zwykłej zamiany) ciągi identycznych znaków x z listy NACO są zastępowane pojedynczym znakiem x. Np. tr -s 123 npn <<< 123_132_13n_ppp wypisze npn_np_n_p.

Przełącznik -c powoduje zamianę znaków których nie ma w liście.

Listy mogą zawierać zakresy znaków (np. [0-9], [a-f]) i klasy znaków (np. [:alnum:], [:space:]).

Uwaga: tr nie przyjmuje nazw plików w liście argumentów - potrafi czytać tylko ze standardowego wejścia.

Przykłady

Zadanie 33 Przefiltruj wynik komendy ls -l przez tr tak, aby:

  • zastąpić wszystkie cyfry znakiem -,
  • zmienić wszystkie małe litery (z zakresu znaków ASCII) na wielkie,
  • zastąpić wszystkie ciągi spacji pojedynczymi spacjami
  • usunąć wszystkie litery rwx

Do bardziej złożonego zastępowania tekstu powszechnie używa się programu sed.
sed (stream editor) czyta wejście po linii naraz i wykonuje podany (zwykle w linii poleceń jako argument) skrypt działający na linii i domyślnie wypisuje ją po jego wykonaniu. Najprostsza komenda wykonująca znajdź/zastąp to sed 's/regexp/replacement/'. sed jest kompletne w sensie Turinga. Jeśli starczy czasu w semestrze, sed będzie omawiany później.

awk

awk jest językiem stworzonym do przetwarzania tekstu, również przetwarzającym tekst linia po linii na podstawie podanego skryptu. W awk skrypt składa się z reguł – par warunek {instrukcje}, gdzie warunek określa dopasowanie do linii (bądź początku/końca przetwarzania/pliku).
awk nie jest omawiany na zajęciach z SOp; jest omawiany w ramach obieralnego przedmiotu Języki formalne i kompilatory.

more, less

Do wyświetlania tekstu nie mieszczącego się w terminalu można użyć jednego z programów nazywanych zbiorczo pagerami.
Pager wyświetla naraz tyle tekstu ile zmieści się w terminalu ("stronę" tekstu) i pozwala na przejście do kolejnej porcji tekstu (zwykle naciskając właściwy klawisz, np. spacja).

Z większością systemów operacyjnych instalowany jest program more będący prostym pagerem.
more jest też częścią standardu POSIX.

Uniksopodobne systemy zwykle są wyposażone w program less (którego hasło marketingowe brzmi: less > more).

Jeśli zmienna środowiskowa $LESSOPEN jest ustawiona, less nie pokazuje danych bezpośrednio, tylko najpierw przekazuje je do wskazanego przez tą zmienną polecenia (np. zmieniając poleceniem LESSOPEN='|rev %s' tą zmienną dla bieżącej powłoki, less będzie wypisywać w każdej linii znaki w odwrotnej kolejności).
Takie programy zwykle próbują rozpoznać rodzaj pliku i dla znanych sobie nieczytelnych dla człowieka typów plików wyświetlają czytelny dla człowieka ekwiwalent zawartości żądanego pliku.
lesspipe jest wiodącą implementacją tej funkcji.

less wspiera między innymi przełączniki:

  • -S – nie zawijaj wierszy
  • -R – (sensowne) sekwencje sterujące są wypisywane (domyślnie są usuwane)
  • -L – wyłącza przetwarzanie wejścia przez polecenie wskazane w $LESSOPEN
  • -N – numeruje wiersze

Po uruchomieniu less można wyświetlić pomoc naciskając h. Wybór przydatnych skrótów:

  • spacja lub PgDown / PgUp – idź do następnej / poprzedniej strony
  • liczba – skacze do linii o tym numerze
  • liczba zakończona % – skacze do tej części dokumentu
  • g / G – skacze na początek / koniec dokumentu
  • /wzorzec / ?wzorzec — wyszukuje wzorca do przodu / do tyłu
    n / N – powtarza wyszukiwane w tym samym / odwrotnym kierunku
  • s – zapisuje dane do pliku (przydatne jeśli less czyta z potoku)
  • v – otwiera plik do edycji w domyślnym edytorze (wskazanym przez zmienną $EDITOR; dostępne jeśli less wyświetla plik)
  • F – czeka na pojawienie się w pliku nowych danych (jak tail -f)

Program man używa programu less jako domyślnego pagera.

Zadanie 34 Wpisz man less żeby wyświetlić stronę dokumentacji dla less przy pomocy programu less. Przetestuj powyższe skróty.

Zadanie 35 Otwórz plik PDF (np. /usr/share/doc/packages/apparmor-docs/techdoc.pdf) używając less, bez opcji oraz z opcją -L.
Otwórz archiwum tar używając less (np. /usr/share/doc/packages/automake/amhello-1.0.tar.gz).
Otwórz katalog (np. /usr/include) używając less.

Program bat, pretendujący do bycia lepszą wersją programu cat, automatycznie uruchamia pager jeśli dane do wyświetlenia nie mieszczą się w terminalu.

tee

Polecenie tee [-a] plik... przepisuje dane ze standardowego wejścia na standardowe wyjście oraz do każdego plików.
Domyślnie pliki są nadpisywane przez program tee. Przełącznik -a powoduje że pliki są otwierane w trybie dopisywania.

tee jest często używane do jednoczesnego wyświetlania na ekranie wyniku długo działającej komendy (dla monitorowania postępu) i zapisywania wyniku do pliku (do późniejszego przetwarzania).

Zadanie 36 Wynik tree przepuść w potoku przez tee zapisującego do pliku. Potem wyświetl plik używając less.

1) Od jakiegoś czasu wiele dystrybucji opiera się na programach które robią jak najwięcej się da i rozrosły się do tego stopnia że nikt już do końca nie panuje nad tym co i w jaki sposób robią (jak np. systemd).
so/pipes_filters.txt · ostatnio zmienione: 2024/04/02 20:50 przez jkonczak