BASH Bushido

  1. Skróty klawiszowe
  2. Edytor Vi(m)
  3. Konfiguracja BASH
  4. Historia
  5. Desygnatory oraz modyfikatory
  6. Aliasy
  7. Menadżer zadań w UNIX-ach
  8. Fancy napisy w terminalu
  9. Obsługa sieci
  10. Porady i sztuczki
  11. Emulatory terminala
  12. Koniec

Źródła:

  1. Bash Bushido - Aleksander Baranowski - https://alexbaranowski.github.io/bash-bushido-book/
 _                      _             _ _
| |_ ___ _ __ _ __ ___ (_)_ __   __ _| | | ___   __ _
| __/ _ \ '__| '_ ` _ \| | '_ \ / _` | | |/ _ \ / _` |
| ||  __/ |  | | | | | | | | | | (_| | | | (_) | (_| |
 \__\___|_|  |_| |_| |_|_|_| |_|\__,_|_|_|\___/ \__, |
			                        |___/

Artykuł ten przedstawia bardziej z optymalizowane wykorzystnie powłoki, a konkretnie BASH. Dzięki czemu możemy wykonać wiele czynności, które do tej pory wykonywaliśmy mozolnie klepiąc polecenia znacznie szybciej co pozwoli zaoszczędzić czas, który możemy przeznaczyć na cokolwiek innego niż zarządzanie maszynami z UNIX-em.

1. Skróty klawiszowe

Kiedy zastanawiamy się nad skrótami klawiszowymi powłoki, to na myśl przychodzi nam jedno pytanie. Czy skróty nie są realizowane przez konkretny emulator terminala, z którego obecnie korzystamy? Otóż część skrótów, które zostaną tutaj przedstawione mogą zostać przechwycone przez środowisko graficzne a następnie/lub przez emulator terminala. W tym wypadku należy upewnić się, że te skróty w ww. programach są nam potrzebne i w przeciwnym razie je wyłączyć. Natomiast za obsługę skrótów, które działają nawet w konsoli serwera bez środowiska graficznego odpowiedzialna jest biblioteka GNU Readline.

Kiedy mamy jakieś dziwne klawiatury lub często korzystamy z różnych komputerów lub konsol a mimo to chcemy zachować podobną prędkość obsługi powłoki poniżej znajdują się skróty klawiszowe, dzięki którym nie będziemy już potrzebować strzałek, entera, backspace-u oraz klawiszy home end i innych. Jedyne potrzebne nam klawisze to ctrl, poźniej ewentualnie alt.

Za pomocą innych skrótów klawiszowych możemy przesuwać kursor wyraz po wyrazie, usuwać całe słowa a nawet część linii polecenia.

GNU Readline obsługuje również inne skróty, które nie tylko polegają na poruszaniu się po linii polecenia.

Wszystkie te skróty jest dostępne po wydaniu polecenia bind -P, jak czytać opisane tam skróty, otóż:

 

2. Edytor Vi(m)

Każdy edytor jest najlepszy, ale co odróżnia je od vi(m)? Nie są preinstalowane w każdym możliwym UNIX-ie o jakim pomyślimy. Wyjątkiem stanowi tu dystrybucja Gentoo, która na swoim ISO nie posiada vi(m). Implementacje vi mogą się różnić od siebie, np. na GNU/Linux-ach vi nie obsługuje poruszania kursorem w podczas edycji, z kolei w OpenBSD już tak, i to jest vi a nie vim. Poniżej umieszcze kilka poleceń vi(m). W tryb poleceń wchodzimy po przez naciśnięcie klawisza ESC, teraz możemy wydawać polecenia.

Te polecenia działają niezależnie czy jest vi czy vim. Poniżej rzeczy, które działają tylko w vim.

Uruchomienie netrw, można wywołać podając w linii polecenia vim katalog. Znacznie więcej informacji nt. vim oraz samouczek możemy uzyskać za pomocą polecenia vimtutor, jak i również wydając polecenie vi :help.

 

3. Konfiguracja BASH-a

Znak zachęty (prompt)

Znak zachęty naszej powłoki jest ustalany za pomocą wzorca zapisanego w zmiennej PS1 zdefiniowanej w pliku .bashrc w naszym katalogu domowym, inny znak możemy zdefiniować dla nowych użytkowników edytując plik /etc/skel/.bashrc lub domyślny znak zachęty dla całego systemu w pliku /etc/bash.bashrc. Jak już wcześniej wspomniałem znak zachęty ustalamy przy pomocy wzorca. Poniżej znajduje się lista elementów z jakich możemy taki wzorzec stworzyć.

Podczas tworzenia wzorca możemy wybrane przez nas elementy możemy wyróżnić, za pomocą 8 kolorów. Te kolory możemy mieszać ze sobą wykorzystując jeden na pierwszym planie a drugi natomiast umieścić w tle. Poniżej znajdują się kody kolorów.

Natomiast sam wzorzec znaku zachęty wygląda następująco,

\[\e[<kolor_pierwszego_planu>;<kolor_tła>m\]<element>\[\e[m\]

Warto zaznaczyć że kolor tła jest opcjonalny.


Polecenie zachęty

BASH daje nam do konfiguracji ciekawą rzecz. Możemy za pomocą jednej zmiennej zdefiniować polecenie, które będzie wykonywane zawsze przed pojawieniem się znaku zachęty. Zmienną PROMPT_COMMAND możemy zadeklarować w pliku .bashrc lub co w tym przypadku może okazać się lepszym rozwiązaniem, wyeksportować zmienną aby można było z niej korzystać w tej samej powłoce.

$ export PROMPT_COMMAND='date +%F-%T | tr -d "\n"'

Użycie tego polecenia spowoduje wyświetlenie pełnej daty wraz z czasem przed każdym znakiem zachęty.


Własne skróty klawiszowe GNU Readline

Pamietając ze wcześniejszych akapitów o poleceniu bind, które wraz z przełącznikiem -P wyświetli nam wszystkie dostępne już skróty, to za jego pomocą możemy utworzyć również własne mapowania kombinacji klawiszy nakonkretne polecenia. Znając wartości cytowane dla klawiszy CTRL oraz ESC/ALT, zadanie jest banalne. Wystarczy wydać konkretne polecenie. Jednak przed tym warto jednak upewnić się czy dany skrót nie jest już wykorzystywany. Jeśli rzeczywiście tak jest to dopisanie do skrótu kolejniej czynności spowoduje wywołanie tych dwóch akcji jednocześnie, co może mieć niekorzystne skutki. Aby upewnić się czy rzeczywiście dany skrót jest nie używany wydamy polecnie bind -P wraz z przekierowaniem wyjścia za pomocą potoku do polecenia grep wraz ze wzorcem przestawiającym dany skrót np. ctrl + v: '\C-v'. Dzieki temu zostaną nam wyświeltlone wszystkie akcje, które wykorzytują ten skrót.

Same skróty tworzymy rownież za pomocą polecenia bind.

$ bind '"\006":"mc\n"'

To polecnie spowoduje dodanie do skrótów w naszym systemie, skrótu klawiszowego ctrl + f wywołującego polecenie uruchamiające program Midnight Commander.

Polecenie bind przyjmuje jeden argument. Jest to ciąg znaków, który jest podzielony na dwie częsci, jedną częścią jest symbol cytowania danej kombinacji klawiszy, może on być trochę dziwny, jak ten wymieniony w przykładzie \006 jest niczym innym jak ctrl + f. Drugą częścia jest czynność jaka ma zostać wykonana po wciśnieciu danej kombinacji klawiszy. Warto zwrócić uwagę na to, że za poleceniem stoi znak przejścia do nowej linii (\n), powoduje on zatwierdzenie tego polecenia zaraz po jego podstawieniu w linii polecenia po naciśnięciu odpowiedniej sekwencji klawiszy. Wróćmy jednak do tego niezrozumiałego symbolu z pierwszej części argumentu polecenia. Taki symbol możemy uzyskać naciskąjac wybraną sekwencje klawiszy w trybie cytowania. Tryb cytowania możemy wywołać skrótem ctrl + v. Po wciśnięciu kombinacji ctrl + v, naciskamy odpowiednią sekwencje klawiszy, zatwierdzamy linię polecenia. Powłoka powinna zwrócić: bash: $'\006': nie znaleziono polecenia pomiędzy pojedyńczymi apostrofami znajduje się nasz symbol cytowania. W trybie cytowania możemy odnajdować symbole dla sekwencji z klawiszem alt/esc (użycie tych klawiszy w sekwencjach daje takie same symbole cytowania) lub ctrl. Użycie polecenia bind w danej powłoce utrzymuje skróty do momentu jej zamknięcia, aby nasze skróty zostały utrwalone musimy dodać ich definicje do pliku .bashrc. Definicje są identyczne jak wydawane polecenia bind w powłoce, po prostu wpisuje do pliku polecenie bind następnie definicje skrótu. Odnośnie skrótów, to jest pewna uwaga. Otóż nie wszystkie sekwencje z klawiszem ctrl chcą działać. Wiele znich jest na stałe przypisanych do funkcji systemowych, dlatego też bezpieczeniej korzystać z klawisza alt.


Powrót do poprzedniego katalogu

Powrót od poprzedniego katalog jest łatwy. O ile te katalogi występują po sobie. Wówczas wykorzystujemy polecenie cd ścieżka_do_katlogu oraz cd -, gdzie minus (-) oznacza poprzedni katalog, w którym się znajdowaliśmy. W wiekszości przypadków to wystarcza. Co jeśli chcemy się przenieść do katalogu, który był przed poprzednim? Z pomocą przychodzą nam polecenia pushd oraz popd. Te polecenia powodują odłożenie lub usunięcie ścieżki z konstrukcji stosu. Dzieki czemu możemy skakać z jednego miejsca w systemie na drugie i z powrotem, jednym poleceniem. To samo można zrealizować za pomocą polecenia cd z minusem. Jednak to polecenie nie pozwala na odłożenie innych ścieżek na później, jeśli przestajemy pracować z jedną ścieżką możemy ją wyrzucić poleceniem popd (po wykonaniu tego polecenia zostaniemy przeniesieni na poprzednią ścieżkę na stosie), i następnie swobodnie przenościć się pomiędzy dwoma pozostałymi ścieżkami za pomocą polecenia pushd.

Poleceń pushd, popd, można używać zamiennie do cd oraz cd -, z tą różnią że możemy cofnąć się znacznie dalej niż tylko na poprzednią ściężkę, ale również na poprzednią poprzedniej itd. Inny poleceniem związanym z stosem katalogów jest dirs, które zwraca nam katalogi, które znajdują się na stosie.


Dodatkowe ustawienia powłoki

Bash posiada dość niepozorne wbudowane polecenie, którym możemy zmienić zachowanie naszej powłoki. Tym poleceniem jest shopt. Wydając to polecenie bez żadnych argumentów możemy dowiedzieć się co możemy zmienić za jego pomocą w powłoce. Jedną z ciekawszych opcji jest autocd, dzięki któremu możemy podawać same ścieżki w linii polecenia, w ten czas zostaniemy przeniesieni na tą ścieżke. Ustawienia opcji obywa się poprzez wydanie polecenia shopt wraz z przełącznikiem -s oraz nazwą opcji. Wyłącznie opcji jest analogiczne tylko zamiast -s jest -u. Aby dowiedzieć się więcej o shopt warto odwiedzić poświęconą mu sekcję na stronie podręcznika powłoki BASH wrozdziale "Wbudowane polecenia powłoki".

 

4. Historia

Historią w powłoce BASH (ale nie i tylko), nazywamy listę poleceń, która zawiera wszyskie do tej pory wprowadzone w powłoce polecenia. Ta lista jest przechowywamna w specjalnym pliku, w katalogu głównym użytkownika. Historia może przyspieszyć nasze codzienne rutynowe zadania wykonywane w powłoce. Ponieważ zamiast klepać na nowo te same polecenia, możemy cofnąć się za pomocą strzałki w górę kombinacji klawiszy ctrl + p i tak długo naciskać ten skrót aż dostaniemy nasze polecenie oraz skrótu ctrl + n przeszukać historię choć jest znacznie bardzie efektywny sposób na wyszukiwanie poleceń mianowicie przeszukanie historii w tył, niestety wadą tego rozwiązania jest to że musimy znać fragment polecenia lub kojarzyć czego mogło dotyczyć, potrzebna jest jakaś fraza aby je wyszukać. Za wyświetlenie całej historii odpowiedzialne jest polecenie history.

Wykonajmy teraz mały eksperyment, uruchom powłokę i wydajmy jakieś nieszkodliwe polecenie np. pwd, teraz uruchomimy drugie okno z połoką, kiedy naciśniemy ctrl + p, okazuje się że nie ma polecenie, którego użyliśmy w poprzeniej powłoce. Historia danej sesji terminala (bo tak możemy nazwać czas spędzony przed pojedyńczym procesem powłoki), trafa do czegoś w rodzaju pamięci powłoki, dopóki nie zakończymy sesji nie zostanie ona utrwalona. Co może być nieco irytujące kiedy korzystamy z wielu połączeń z tym samym serwerem. Jednak tym zajmiemy się za chwilę. Kiedy na danej powłoce historia jest włączona, a my chcemy zatrzeć ślady obecności w systemie, możemy wyczyścić pamięć tej sesji wydając polecenie history z przełącznikiem -c i jeśli będziemy dalej pracować możemy przywrócić pamięć z pliku historii a jeśli nie to możemy się po prostu wylogować, jedyne co pozostanie w historii z tej sesji to polecenie exit.

Historia musi być gdzieś przechowywana skoro można ją bez problemu przywrócić, i owszem historia przechowywana jest w pliku, plik ten jest wskazywany przez zmienną środowiskową HISTFILE. Najczęściej wskazuje na /home/<username>/.bash_history. Przekierowanie do niego pustego polecenia echo usunie dotychczasową historię całkowicie. Plik ten jest również ograniczony liczbą wierszy jakie może przechowywać, po osiągnięciu tej wartości najstarsze wpisy są usuwane, aby zrobić miejsce najnowszym. Ilość wierszy jest przechowywana w zmiennej środowiskowej HISTSIZE. Jak permanentnie wyłączyć historię? Otóż w bardzo prosty sposób. Ustawiając HISTFILE na /dev/null natomiast ilość wpisów historii w pamięci sesji (zmienna HISTSIZE) na 0.

Wróćmy do przypadku wielu połączeń z serwerem z jednego komputera. Polecenie history posiada jeszcze jeden ważny przełącznik, mianowicie -a. Wydanie polecenia history z tym przełącznikiem powoduje dopisanie poleceń zebranych w pamięci do pliku historii. Jednak użycie tego przełącznika aby zadziałało wymaga zmiany zachowania powłoki, musimy przełączyć za pomocą polecenia shopt opcję histappend, na oby dwu oknach.

$ shopt -s histappend

Wykonując sekwencje poleceń w obu oknach, w postaci: dopisania zawartości pamięci do pliku; wyczyszczenia pamięci z historii oraz jej przywrócenia możemy w ten sposób zsynchronizować w historię w pamięci między różnymi sesjami terminala. Proces ten można zautomatyzować, umieszczając jego wykonanie przed pojawieniem się znaku zachęty, czyli umieszczeniu trzech poleceń oddzielonych średnikami w zmiennej PROMPT_COMMAND, tak jak poniżej:

$ export PROMPT_COMMAND="history -a; history -c; history -r; $PROMPT_COMMAND"

Odwołanie się do PROMPT_COMMAND spowoduje że jeśli coś do tej pory znajdowało się w PROMPT_COMMAND pozostanie ono na swoim miejscu. Użycie w tym wypadku polecenia export oznacza że zmiany w PROMPT_COMMAND są tylko tymczasowe. Aby zapisać to że historia się synchronizuje między sesjami, należy na stałe zmienić wartość zmiennej PROMPT_COMMAND w pliku ~/.bashrc (tylda, oznacza katalog domowy).

Wróćmy teraz do wylistowania historii za pomocą polecenia history. Listing składa się z dwóch kolumn. Tak jakby z identyfikatora z wystąpienia zdarzenia (polecenia) oraz z samego polecenia. Do pełnej historii brakuje jednak informacji na temat tego kiedy dane polecenie zostało wydane, nie wiem jak to jest w innych dystrybucjach to w GNU/Linux Debian zmienna środowiskowa HISTTIMEFORMAT jest pusta. Nadając jej wartość podobną formatem do tego jak podajemy argument poleceniu date.

$ export HISTTIMEFORMAT="%Y-%m-%d %T"

Ustawienie tej opcji może wprowadzić nas w małe zakłopotanie, kiedy po jej ustawieniu wprowadzimy kilka poleceń, wylistujemy sobie historię i wszystko wydaje się na pierwszy rzut oka w porządku, zapiszemy sobie więc to polecenie do pliku ~/.bashrc, kiedy wylogujemy się i zalogujemy się ponownie, następnie znów wylistujemy historię czasy/daty przestaną się zgadzać, okaże się że czas poleceń wydanych przed uruchomieniem opcji formatu czasu jest zbliżony do czasu wydanie polecenia history w tej powłoce, a zatem jest on późniejszy od czasu poleceń wydanych w poprzedniej sesji po uruchomieniu formatu czasu. Skąd to się wzięło? Otóż jeśli w pliku historii nie znacznika czasu to powłoka ładując go pamięci jako znacznika dla tych poleceń użycje czasu własnego startu.

Przyjrzymy się teraz przechowywaniu historii. W BASH możemy łatwo określić ilość przechowywanych przez powłokę (czy to w pamięci, czy w pliku historii) wpisów historii. Za ilość w wpisów przechowywanych w pamięci sesji odpowiada poznana już przez nas zmienna środowiskowa HISTSIZE. Z kolei za wielkość pliku historii odpowiada zmienna HISTFILESIZE. Za ich pomocą możemy kontrolować ilość zapisywanej przez sesje historii.

To co ma trafić do historii może być kontrolowane, służy do tego zmienna środowiskowa HISTCONTROL, przeważnie posiada ona wartość ignoreboth. Oznacza ona że do historii nie trafią polecenie powielone (występujące po sobie), które znajdują się już historii oraz te polecenia rozpoczynające się od spacji. Poniżej znajduje się lista możliwych wartości:

Warto wspomnieć że wartość tej zmiennej jest listą, której elementy są rozdzielane dwukropekiem (:), więc wartości możemy łączyć ze sobą. Zatem zamiast używać "ignoreboth" możemy użyć "ignorespace:ignoreboth".

Ostatnią rzeczą z historii pozostało poniekąd również zgadnienie odnośnie kontroli - co ma zostać zapisane w historii. Tą rzeczą jest zmienna HISTIGNORE. W jej wartości możem podać najczęściej używane polecenia, aby nie zaśmiecać sobie historii poleceniam typu cd lub ls. Rzeczą o której należy pamiętać jest to aby podać symbol wieloznaczności (*) zaraz po poleceniu, spowoduje to przypasowanie poleceń, które zawierają jakiekolwiek argumenty a nie tylko samych poleceń, u niektórych użytkowników HISTIGNORE może wyglądać tak:

$ export HISTIGNORE="cd*:history:htop:ls*:ll*:la:l:popd:pushd*:top"

 

5. Desygnatory słów i zdarzeń oraz modyfikatory

Pierwszym opisanym tutaj zagadnieniem będzie desygnator zdarzenia, który składa się wykrzyknika (!) oraz numeru linii z historii. Można stwierdzić że jest to jeden ze sposobów na wywołanie polecenia z historii, należy jednak znać numery linii interesujących nas poleceń, można sobie wylistować historię a następnie odfiltrować część informacji zwrotnych za pomocą polecenia grep. Z desygnatorem zdarzeń wiąże się również pewna sztuczka, otóż desygnator ostatniego zdarzenia wygląda następująco: !! - dwa wykrzykniki. Czasmi musimy wykonać w powłoce pewne zadania administracyjne. Wymagają one zazwyczaj podniesienia uprawnień. Jak wiemy uprawnienia jednorazowo podnosimy za pomoca polecenia sudo. Często jest jednak tak że wydajemy polecenia administracyjne bez sudo wtedy otrzymujemy komunikaty od systemu o braku dostępu. Możemy oczywiście wybrać ponownie to polecenie z historii następnie za pomocą skrótu przenieść się na początek linii, następnie dopisać sudo i zatwierdzić je jeszcze raz. Jest jednak prostszy sposób:

$ sudo !!

Powyższy zapis jest równoznaczny z wyżej wymienioną czynnościa, prawda że łatwiejszy? Chociaż bez wprawy w powyższej sztucze nasz mózg będzie i tak podpowiadał nam aby dopisać to sudo na początku linii. Wracając jeszcze do desygnatora zdarzenia to jego wartością nie jest tylko numer linii w historii może on przyjąć w sumie 4 wartości:

Patrząc na polecenie zapisane w linii poleceń, widzimy nazwę programu oraz przekazywane mu argumenty jednak z poziomu przetwarzania tekstów jest to lista słów rozpoczynająca się od 0, które możemy dowolnie wybierać z konkretnych wpisów z historii i co lepsze umieszczać tak zwane desygnatory słów jako elementy składowe nowej linii polecenia. Na desygnator słowa składa się desygnator zdarzenia oraz odzielony dwukropkiem (:) selektor konkretnego słowa, selektorów BASH oferuje wiele.

Wśród desygnatorów słów panuje taka zasada że jeśli przy desygnatorze zdarzenia nie zostanie podany numer linii w historii, to zostanie użyty ostatnio dodany wpis do historii.

Oprócz desygnatorów słów lub wraz z, do jeszcze lepszego dostosowania linii pobranej z historii dzięki desygnatorowi zdarzenia, możemy użyć modyfikatorów. Są to dodatkowe czynności wykonywane przez powłokę aby jeszcze bardzie móc wykorzystać już raz wpisane polecenia. Modyfikatorów używa się tak samo jak desygnatorów słów, po dwukropku, po albo samym desygnatora zdarzenia albo desygnatora słowa albo po innym modyfikatorze. Poniżej znajduje się model składni podczas używania desygnatorów zdarzenia:

![numer,ciąg_znaków,!]:[desygnator_słów]:[modyfikator1]:[modyfikator2]...

Lista dostępnych modyfikatorów:

Odnośnie opcji G, to jeśli zostanie ona skierowana wraz z s/old/new, do pracy na jednym słowie, to wyniki może być nie co dziwny. Ponieważ jeśli zostanie odnalezionych więcej niż jeden elementów old, w słowie to tylko dwa zostaną zmienione. Wynika z tego że jeden z samego modyfikatora s a drugi z G.

Jeśli musimy na szybko zmienić coś w poprzednim poleceniu, to BASH wprowadza skrót: ^old^new^, działa jak modyfikator s wraz z desygnatorem zdarzenia, ale bez zbędnego desygnatora zdarzenia oraz konstrukcji modyfikatora. Wystarczy wpisać w linii polecenia np. ^sduo^sudo^. Warto zaznaczyć, że wraz tą konstrukcją możemy używać innych modyfikatorów takich jak np. :&, aby powtórzyć zamianę wartości.

Wróćmy do historii, to zagadnienie nie było by dokońca zrozumiałe bez wcześniejszego opisu desygnatorów oraz modyfikatorów. W BASH istnieje zmienna histchars (nie jest ona zmienną środowiskową, jest po prostu zmienną powłoki, zapisaną małymi literami bez potrzeby poprzedzania jej definicji poleceniem export), w której to możemy zdefiniować znaki używane w historii. Histchars składa się z trzech znaków i każdy z nich coś oznacza.

Te symbole możemy zmieniać właśnie dzięki histchars. Podając je razem jako wartość zmiennej histchars, np.

$ histchars="+=@"
$ echo test
test
$ ++
echo test
test
$ =t=1
echo 1est
1est

Przy stosowaniu tej zmiennej warto pamiętać o innych znaczeniach użwanych przez nas znaków w powłoce.

Podstawienie historii (inaczej desygnator zdarzeń) możemy wyłączyć na dwa sposoby. Pierwszy sposób to nadanie pustej wartości zmiennej histchars:

$ histchars=

lub zmienić zachowanie powłoki za pomocą polecenia set:

/* Wyłączając */
$ set +o histexpand
/* Włączając z powrotem */
$ set -o histexpand

Jednak w wiekszości przypadków, nie potrzeba tego robić ponieważ ! (wykrzyknik) nie jest rozpoznawany w ciągach jako desygnator zdarzeń (przynajmniej w GNU/Linux Debian).

Biorąc pod uwagę to ile jest tu materiału, wypisze poniżej to co jest najczęściej stosowane i czego warto sie nauczyć:

 

6. Aliasy

Aliasy inaczej nazwy zamienne stosowane najczęściej gdy chcemy zawrzeć długie polecenie w krótkiej przyjaznej nazwie. Aliasy są umieszczane w plikach konfiguracyjnych powłoki aby miały jakiś sens. Tworzenie aliasów w sesji powłoki raczej nie ma sensu. Czemu miało by go mieć. Skoro i tak musimy zapisać nasze bardzo długie polecenie, to już można je wykonać potem ewentualnie użyć historii.

Nie mniej jednak, definicja aliasu w BASH rozpoczyna się wbudowanego polecenia alias gdzie następnie podaje się nazwę aliasu, znak równości (=) oraz w pojedynczych apostrofach polecenie, dla którego tworzony jest alias. Najprostszy alias jak przychodzi mi do głowy to ten poniżej:

$ alias diceroll='echo $(((RANDOM % 6) + 1))'
$ diceroll
6

Obecnie używane w systemie aliasy możemy wylistować za pomocą tego samego polecenia tylko że z przełącznikiem -p.

Aliasy to takie krótkie zagadnienie że zostały jeszcze tylko dwie rzecz do omówienia. Jak sprawdzić czy dane polecenie jest aliasem? Do sprawdzenia tego typu rzeczy służy polecenie type.

$ type diceroll
diceroll jest aliasem do echo $(((RANDOM % 6) + 1))'
$ type pushd
pushd jest wewnętrznym poleceniem powłoki

Warto używać tego polecenia aby sprawdzić czy dana nazwa jest wolna, bo co jeśli stworzymy alias pod nazwą programu, który już istnieje? W sumie nic takiego. Binaria albo skrypt pozostaną nietknięte. Jedynie nie będzie dostępu z poziomu powłoki w tej konfiguracja, a że konfiguracja często jest określana przez użytkowników w ich katalogach domowych, to użytkownik, który posiada taki alias nie będzie miał dostępu do tego programu. Twórcy powłoki przewidzieli taką sytuacje implementując aliasy, więc dali możliwość dostępu do programu przesłoniętego przez alias. Przed nazwą takiego programu daje się backslash czy tam wsteczy ukośnik (\), gdy powłoka natrafi na takie polecenie zacznie przeszukiwać PATH w poszukiwaniu programu lub skryptu o takiej nazwie a nie podstawiać polecenie z aliasu.

 

7. Menedżer zadań w UNIX-ach

W tych systemach, w których możemy używać powłoki takiej jaką jest BASH na pewno mamy do dyspozycji programy dzięki, którym możemy śledź procesy jakie są wykonywane w naszym systemie. Możemy robić w trybie nieinteraktywnym używając polecenia ps z odpowiednimi przełącznikami oraz odfiltrowując jego dane wyjściowe za pomocą potoków i takich poleceń jak sort oraz uniq. Jednak co przyjęło się wśród użytkowników używanie znacznie lepszych programów, które są nieco bardzie rozmowne z nimi niż polecenie ps mowa tu poleceniach top oraz htop. Top jest to program, który chyba został wpisany w kanon podstawowych narzędzi dostarczanych wraz systemami UNIX-opodbnymi i to na nim skupimy się na początku, póżniej poznamy bardzie kolorowy htop.

Po uruchomieniu programu każdy widzi co dostaje. Najprościej rzecz ujmując statystki zużycia zasobów komputera z listą procesów, które te zasoby używają aby realizować swoje zadania. Wartą wyjaśnienia informacją, która jest nie tylko wyświetlana przez top czy htop ale również przez polecenie uptime jest load average. Interpretuje się w bardzo prosty sposób, na początku ustalamy ile nasz komputer (CPU) ma wątków. To load average nie powinien przekroczyć tej wartości w pierwszym z tych pomiarów. Pomiary są ustalane w odstępach czasu 1 minuty, 5 minut oraz 15. Na podstawie wartości jaką jest load average możemy oszacować w jakim stopniu nasz komputer jest zajęty przez procesy. Ta wartość to najmnieszy monitor zasobów jaki możemy spotkać w UNIX-ach. Co może oznaczać wysokie load average? W zależności od tego do czego używamy danego UNIX-a, to jeśli na naszym PC uruchomiliśmy np konwersję plików multimedialnych to wartości mogą skoczyć. Jak również podczas kompilacji. Ta wartość ma nam przekazać informacje, czy możemy swobodnie pracować po mimo uruchomienia jakiś programów, czy też wstrzymać się do zakończenia zasobożernego zadania. Mimo iż load average wskazuje nam wartości równoważne z ilością naszych wątków, to system i tak wydaje się całkiem responsywny. Wtedy system jest w pełni załadowany (obciążony), ale nie przeciążony dlatego też pełne załadowanie systemu jest mniej odczuwalne niż jego przeładowanie gdzie te wartości mają naprawdę ogromne wartości. Nie ma górnego limitu dla load average, więc liczby mogą być na prawdę duże.

Po uruchomieniu programu na pierwszej linii, znajduje się wynik polecenia uptime, wraz z opisaną wcześniej wartością load average. Poniżej znajdują się sumaryczna ilość uruchomionych procesów, z podziałem na poszczególne grupy w zależności od stanu w jakim się one znajdują, jednak nie wszystkie grupy są wyświetlane. Nie ma procesów, które znajdują się w stanie bezczynności. Następną linią jest wskaźnik z użycia procesora przez procesy. Zużycie procesora jest podzielone na kilka grup, w zależności od tego czego dotyczą procesy. Opisy grup znajdują się na liście poniżej:

Następne dwie linie to pamięć operacyjna, z podziałem na pamięć RAM oraz przestrzeń wymiany. Nas w sumie będzie ciekawić głównie ile wolnej pamięci nam jeszcze zostało, zatem powinna nas interesować ostatnia wartość w drugiej linii (uwaga, w tej wartośći nie jest zawarta pamięć SWAP) opisana jako avail Mem. Pozostałe pola raczej nie wymagają opisów.

Do omówienia pozostała część główna programu, czyli tabelka z procesami, jej omówienie składa się głównie z opisu kolumn.

Top jest dość elastycznym programem, niektóre rzeczy możemy dostosować pod własne "widzi mi się". Jednak zanim przystąpimy do konfiguracji utworzymy, dowiązanie symboliczne do głównego programu tak jakoby byśmy działali na kopii.

$ sudo ln -s /usr/bin/top /usr/bin/my_top

A więc sprawa z konfiguracją top. Jest na tyle nie skomplikowana, że żeby ją dokładnie wyjaśnić trzeba by przepisać stronę z podręcznika. Czego robił nie będę, jeśli wybraliśmy język polski podczas instalacji powinniśmy mieć strony podręcznika w naszym rodzimym języku. Jeśli nie to niestety musimy sobie jakoś radzić. Może zamiast przepisywania podręcznika, kilka uwaga. Na początku uruchomimy program top z naszego dowiązania symbolicznego w moim przypadku będzie to my_top.

Kiedy konfiguracja zostanie zapisana, wyłączymy my_top, następnie uruchomimy oryginalne polecenie top, okaże się że nie ma żadnych ustawień. Dzieje się tak, ponieważ konfiguracja utworzona jest przypisana tylko do tej kopii utworzonej przez dowiązanie symboliczne, którą wrazie czego zawsze można usunąć.

Żeby używać top-a, w praktyce musimy pamiętać o dwóch klawiszach. Pierwszy z nich to h powodujący wyświetlenie pomocy, drugim z nich jest q, które naciśnięcie spowoduje zamknięcie programu. Jeśli coś w wyświetlanej pomocy nie jest jasne, zawsze pozostaje strona podręcznika man 1 top, ale jeśli ktoś jakimś cudem trafia właśnie na ten artykuł, w celu uzyskania pomocy odnośnie programu top, to poniżej kilka klawiszy, których trzeba się nauczyć, chcąc korzystać biegle z top-a.

Sortowanie i filtry:

Użyteczne polecenia top:

Wyświetlanie agregowane*:
* Wyświetla w jednej tabeli wszystkie tryby pracy od 1 do 4 (znane z polecenia g)top.

Wyświetlanie podsumowania (dane nad tabelką):

Obecnie w systemach GNU/Linux, istnieje wersja ulepszonego top-a. Pod nazwą htop. Różnica miedzy htop a top jest taka że przeważnie nie jest preinstalowany. Jest dostępny w repozytoriach lub trzeba go kompilować oraz jest prostszy w obsłudze. Z Htop-em możemy pracować od razu nie potrzeba go dostosowywać, ponieważ wszystko jest czytelne "out of box". Czynności mamy zmapowane pod klawiszami funkcyjnymi, gdzie na pasku na dole jest opisane, który klawisz jest do czego. Jest on na pewno bardzie interaktywny niż top. Jednak kiedy już ograniemy, konfiguracje top-a, htop staje się zbędny. Sam fakt że trzeba go doinstalowywać. Nie będę opisywał tu konfigurajcji programu htop, ponieważ wystarczy czytać ze zrozumieniem aby dostosować pod siebie ten menadżer zadań. Na koniec chciałbym dodać iż htop posiada wskaźnik baterii do włączenia w ustawieniach, może być to przydatne dla osób, które są zmuszone działać na bardzo uproszczonych (domyślnie) środowiskach graficznych.

 


8. Fancy napisy w terminalu

Ten rodział można traktować z przymrużeniem oka. Tutaj nie zostaną przestawione żadne zaawansowane techniki wykorzystania powłoki, ale jednak jeśli ktoś szuka jakiegoś napisu na MOTD na serwer FTP czy IRC, lub nawet jako ładny nagłówek dla wyświetlenia pomocy w skrypcie/programie to tutaj znajdzie kilka rozwiązań.

Pierwszym, najstarszym programem tego jest banner, który domyślnie wypisze do co podamy w argumentach za pomocą kratek (#), po jedenej linii dla każdego argumentu. Dla GNU/Linux Debian pakiet nazywa się sysvbanner, podaje tą informacje dlatego że prawdobnie trzeba będzie go do instalować.

$ banner GNU/Linux
 #####  #     # #     #       # #
#     # ##    # #     #      #  #           #    #    #  #    #  #    #
#       # #   # #     #     #   #           #    ##   #  #    #   #  #
#  #### #  #  # #     #    #    #           #    # #  #  #    #    ##
#     # #   # # #     #   #     #           #    #  # #  #    #    ##
#     # #    ## #     #  #      #           #    #   ##  #    #   #  #
 #####  #     #  #####  #       #######     #    #    #   ####   #    #

Banner nie posiada żadnych przełączników, ani opcji do wyboru. To co widać powyżej jest jego główną i jedyną funkcjonalnością.

Inny programem, którego możemy użyć do tworzenia tekstowych banerów jest figlet. Ten jest już nieco bardziej dziej rozbudowany. Posiadający wiele tak zwanych czcionek, z których mozemy tworzyć napisy.

$ figlet GNU/Linux

Tak wygląda klasyczny font polecenia figlet.

  ____ _   _ _   _   ___     _
 / ___| \ | | | | | / / |   (_)_ __  _   ___  __
| |  _|  \| | | | |/ /| |   | | '_ \| | | \ \/ /
| |_| | |\  | |_| / / | |___| | | | | |_| |>  <
 \____|_| \_|\___/_/  |_____|_|_| |_|\__,_/_/\_\

Poniżej drugi dośc popularny font slant.

$ figlet -f slant GNU/Linux
   _______   ____  __   ____    _
  / ____/ | / / / / / _/_/ /   (_)___  __  ___  __
 / / __/  |/ / / / /_/_// /   / / __ \/ / / / |/_/
/ /_/ / /|  / /_/ //_/ / /___/ / / / / /_/ />  <
\____/_/ |_/\____/_/  /_____/_/_/ /_/\__,_/_/|_|

Dla figlet istnieje masa różnych fontów. Jednego z nich użyłem do utworzenia baneru na górze tego dokumentu, przedstawiającego jego kategorię. Więcej czcionek znajduje się tutaj:

http://www.figlet.org/examples.html. Polecam również zapoznać się ze stroną podręcznika tego polecenie w poszukiwaniu bardzie zaawansowanych opcji tego polecenia. Za pomocą poniższego polecenia możemy sprawdzić jakie czcionki zostały z zainstalowane wraz z pakietem:

$ ls -al /usr/share/figlet/*.flf

W powszechnym użytku znajduje się znajdują się jeszcze dwa programy, które możemy wykorzystać do dowcipów w postaci "easter eggów" w skryptach, lub MOTD. Pierwszy z nich raczej może posłużyć do tego pierwszego lub otaczania istotnych informacji np. na LiveCD. Cowsay. Ten pakiet posiada dwa odrębne polecenia cowsay oraz cowthink. Przestawiające tekst z pierwszego argumentu jako wypowiedź lub myśli krowy.

$ cowsay "Login: user | Hasło: user1"
____________________________
< Login: user | Hasło: user1 >
----------------------------
\   ^__^
 \  (oo)\_______
    (__)\       )\/\
	||----w |
	||     ||

To polecenie możemy połączyć z jeszce jednym poleceniem fortune instalowanym z pakietu fortune-mod, wynik przełączenia wyjścia z polecenia fortune na cowsay lub cowthink może przynieść całkiem zabawne rezulataty. Np. krowa może rzucić jakimś cytatem Marka Twaina, albo dowcipem o tym ilu psyhiatrów potrzeba do zmiany żarówki. Teraz wiemy również co robi polecenie fortune. Wypisuje jakiś losowo wybrany tekst z swojej bazy.

 $ fortune | cowsay
_______________________________________
/ Don't hate yourself in the morning -- \
\ sleep till noon.                      /
---------------------------------------
\   ^__^
 \  (oo)\_______
    (__)\       )\/\
	||----w |
	||     ||

Ostatnim programem tego typu, jeśli chodzi jakieś ładne napisy, jest myślę najlepszy pomysł na MOTD. Mianowicie chodzi o program neofetch, który oprócz wypisywania dużego loga dystrybucji w ASCII Wyświetla takie podsumowanie odnośnie maszyny jakiej używamy, przypomina ono troche informacje o systemie z macOS, którą otwiera każdy aby zobaczyć co to za mac i co ma w środku. Poniżej wynik polecenia z mojej maszyny, na której redagowałem fragment tekstu tego dokumentu.

$ neofetch
       _,met$$$$$gg.          xf0r3m@vostro-3580
    ,g$$$$$$$$$$$$$$$P.       ------------------
  ,g$$P"     """Y$$.".        OS: Debian GNU/Linux 10 (buster) x86_64
 ,$$P'              `$$$.     Host: Vostro 3580
',$$P       ,ggs.     `$$b:   Kernel: 4.19.0-13-amd64
`d$$'     ,$P"'   .    $$$    Uptime: 9 hours, 2 mins
 $$P      d$'     ,    $$P    Packages: 1818 (dpkg), 3 (snap)
 $$:      $$.   -    ,d$$'    Shell: bash 5.0.3
 $$;      Y$b._   _,d$P'      Resolution: 1920x1080
 Y$$.    `.`"Y$$$$P"'         DE: GNOME 3.30.2
 `$$b      "-.__              Theme: Adwaita [GTK2/3]
  `Y$$                        Icons: Adwaita [GTK2/3]
   `Y$$.                      Terminal: terminator
     `$$b.                    CPU: Intel i5-8265U (8) @ 3.900GHz
       `Y$$b.                 GPU: Intel UHD Graphics 620
          `"Y$b._             Memory: 2426MiB / 7835MiB
              `"""

Jak widać, jest tu wiele informacji, których musieli byśmy szukać róznymi poleceniami.

 

9. Obsługa sieci

Na pierwszy ogień weźmiemy problem, z którym chyba spotkał się każdy kto chciał za pomocą swojego ulubionego edytora, dokonywać zmian w plikach znajdujących się na serwerze. Rozwiązania tego problemu są dwa. Pierwszy z nich klasyczny: sciągamy plik z serwera, zmieniamy co trzeba, wrzucamy ponownie. Drugi to z kolei edycja zdalna, tylko aby jej użyć musimy mieć do dyspozycji ssh, plik możemy wyedytować za pomocą vim-a, ale co jeśli nie pamiętamy jego dokładnej nazwy? No właśnie, i tu przychodzi montowanie odległego systemu plików za pomocą ssh - sshfs. Program możemy za instalować z repozytorium. Poźniej tworzymy na punkt montowania gdzieś w swoim katalogu domowym. Sama procedura montowania jest banalna.

$ sshfs xf0r3m@192.168.8.4:/home/xf0r3m xf0r3m@sapphire

Gdzie:

Teraz możemy wykonywać wszystkie możliwe operacje na plikach (z pewnymi ograniczeniami), tak jak byśmy wykonywali je na plikach lokalnych. Po zakończeniu prac, warto katalog odmontować, za pomoca poniższego polecenia:

$ fusermount -u /home/xf0r3m/xf0r3m@sapphire

Żeby zbytnio nie owijać w bawełne, przedstawie chyba naciekawszy problem który możemy rozwiązać kilkunastu stuknięć w klawiaturę. Powiedzmy że żyjemy w małej miejscowości (nie mowię, że na wsi), gdzie internet jest albo z osiedlówki albo z sieci komórkowej. Aby nie cieszyć się 200 Mb/s przez 20 dni, ponieważ w taki okres czasu jesteśmy w stanie wypompować 300GB pakietu danych, wybraliśmy osiedlówkę bujającą się na 10Mb/s. Po podłączeniu routera do modemu DOCSIS, okazałow się że adres na WAN-ie mamy prywatny 10.x.y.z/8. Chcemy jednak mieć dostęp do naszego serwera plików poprzez ssh. W pracy możemy skonfigurować sobie jedną z maszyn jako serwer stricte ssh (wystarczy zainstalować openssh-server) co pozwoli uruchomić nasz tunel, dzięki któremu będziemy mogli połączyć się z pracy z serwerem w domu bez otwierania portów na domowym routerze. Nie będe opisywał tutaj procedury, ponieważ już to zrobiłem przy okazji sieci VPN. Zainteresowanych zapraszam do linku poniżej: https://morketsmerke.net/articles/terminallog/laboratorium_vpn.html

Do realizacji tego realizacji tego zadania użyjemy prawdopodobnie najpopularnieszego języka na świecie. A będzie on nam potrzebny do udostępnienia swojego katalogu domowego bez brudzenia w systemie i instalowania różnych usług w systemie, wystarczy jedno polecenie. Obecnie chyba w każdym GNU/Linux-ie preinstalowany jest Python w wersji 3.

$ python3 -m http.server 8080

Wydanie tego polecenia spowoduje uruchomienie bardzo prostego serwera, który udostępni zawartość katalog domowego o ile nie znajduje się w nim plik o nazwie index.html, wtedy zamiast plików zobaczymy jego zawartość. Domyślnie serwer HTTP Python-a nasłuchuje na wszystkich dostępnych interfejsach w systemie, za pomocą przełącznika -b możemy wymusić wykorzystanie tylko konkretnego interfejsu podając jako wartość przełącznika adres interfejsu. Np.

$ python3 -m http.server 8080 -b 127.0.0.1

Oczywiście nasłuchiwanie na pętli zwrotnej w tym przypadku akurat nie ma sensu. Podczas uruchamiania serwera najlepiej wybierać porty powyżej 1024, ponieważ do niższych portów będzie potrzebne uruchomienie polecenia z uprawnieniami administratora.

Kolejną ciekawą rzeczą jest skanowanie sieci, nie tylko pod kątem dostępności, ale również pod kątem zainstalowanych na danych hostach usług. Tutaj należy pamiętać aby wykonywać te czynności tylko na systemtach którymi administrujemy. Tak niewielka czynność jak skanowanie portów, może podnieść alarm i dzięki czemu możemy mieć poźniej problemy z prawem. Dlatego wpisując adres musimy upewnić się dwa razy, że wpisaliśmy poprawny.. Skanowania dokonujem za pomocą programu nmap, który dziś już ma renomę kultowego. Do wyszukiwania komputerów w sieci możemy użyć poniższego polecenia:

$ sudo nmap -sP 192.168.8.1/2

Jeśli upatrzymy sobie już jakiś serwer możemy go wyskanować pod kątem obecności usług, jakie posiada uruchomione, w zależności od używanego przez usługę rodzaju transmisji.

Skanowanie TCP:

$ sudo nmap -sS 192.168.8.4

Tutaj małe wyjaśnienie, do skanowania TCP używam skanowania SYN, żeby odkryć czy port jest otwarty nie potrzeba kończyć połączenia, wystarczy że otrzyma się wiadomość zwrotną o tym że można nawiązać połączenie. Skanowanie SYN jest znacznie szybsze od skanowania TCP, jednak może dać czasami nie miarodajne efekty, chociaż aby to nastąpiło serwer musi być nieco bardziej zabezpieczony. Wiec jeśli zależy nam jednak na wynikach skanowania, możemy użyć stricte skanowania TCP za pomocą poniższego polecenia.

$ sudo nmap -sT -T 4 192.168.8.4

Opcja -T - wskazuje na szablon zależności czasowych, mamy 6 stopni od 0 do 5, im niższy tym dokładniejsze skanowanie, jednak trwa ono dłużej. Więcej na ten temat w na stronie podręcznika man nmap, po uruchmieniu naciskamy ukośnik (/) po nim wpisujemy "szablonu\ zależności", następnie naciskamy enter, i powiniśmy zostać przeniesieni pod sekcje opisującą opcje -T.

Skanowanie UDP:

$ sudo nmap -sU 192.168.8.4

Często wykorzystywanym trybem jest tryb pełnego skanowania, który poza samym skanowaniem portów, stara się ustalić wersje wykorzystywanych usług, dodatkowe informacje już z samych usług oraz ustalić system operacyjny jaki jest używany na serwerze. Poniżej uruchomienie pełnego skanowania:

$ sudo nmap -A -T 4 192.168.8.4

Nmap sam w sobie jest dość niebezpiecznym programem w rękach osoby, która ma opananowane do perfekcji testy penetracyjne (oczywiście mającej złe intencje, nie można winić broni za morderstwa). Za pomocą skryptów rozszerzających ten sam program dla administratorów, który służy do lokalizowania drukarek można za pomocą kilku stuknięć w klawisze włamać się do systemu. Strasznie negatywanie nacechowany wyszedł ten paragraf, jednak myślę że zachęciłem do nauki nmap-a nim więcej osób niż mówił bym jaki to nie jest użyteczny, mimo tego właśnie w nim to zrobiłem. Ludzką naturę kręci wszystko co niebezpieczne.

Pośród ciekawych programów sieciowych mamy dyspozycji monitory ruchu sieciowego, oprócz Wiresharka, który jest niestety programem wymagającym środowiska graficznego oraz tshark, który jest nieco nieinteaktywny mamy ciekawą alternatywę: iptraf-ng, który jest troche jak wireshark tylko że interfejsem przeznaczonym na terminale. Innym programem jest minimalistyczny nload, który przy domyślnej konfiguracji zwraca tylko podsumowanie z prędkością oraz ilością przesyłanych przez nas danych. Jednak konfigracja nload wymaga przeczytania strony podręcznika.

Kiedyś aby zobczyć jakie porty są otwarte w systemie wydawało się polecenie netstat, obecnie czasy się zmieniły i do tego rodzaju czynności używa się polecenia ss. Jeśli wydamy poniższe polecenie zobaczymy wszystkie nawiązane połączenia w systemie.

$ ss

Większość wygląda nieco nie zrozumiale, te połączenia są to wewnętrzne połączenia procesów z użyciem gniazd, procesy mogą się tak komunikować z innymi procesami. Póki co nas to nie za bardzo interesuje. Poniżej znajduje się lista przełączników, dzięki której będziemy stanie wybrać interesujące nas połączenia.

Za pomocą prawdopodobnie dowolnego UNIX-a mamy możliwość komunikacji z dowolnym innym UNIX-em podwarunkiem że posiada on w swoim systemie program netcat (nc), za pomocą tego programu możemy np. połączyć się z dowolnym portem, lub tez otworzyć port i oczekiwać na nim na połączenie, od zwyczajnych tekstów przesyłanych z jednego systemu na drugi, które mogą wyglądać jak najzwyklejszy czat, po przez przesyłanie całych katalogów z użyciem metod kompresji, ale najpierw podstawy.

Nawiązywanie połączenie TCP:

$ nc <HOST> <PORT>

Nawiązywanie połączenie UDP:

$ nc -u <HOST> <PORT>

Zrzut danych z sesji do pliku:

$ nc -o <nazwa_pliku> <HOST> <PORT>

Jak możemy przetestować naszego nc? Otoż sposób w samej funkcjonalności jest dość prosty. Połączmy się z jakimś lokalnym serwerem WWW, ale najpierw przygotujemy sobie żądanie. W pustym pliku wpiszymy te 3 linie:

GET / HTTP/1.0
Host: <HOST>

Pusta linia jako trzeci wiersz w pliku, nie jest błędem, jest wręcz wymagana. Jeśli posiadamy polecenie unix2dos, to możemy skonwertować UNIX-owe znaki nowej linii, na te DOS-owskie, które są wymagane przez protokół HTTP. Jeśli nie mamy to musimy doinstalować (apt install dos2unix). Po instalacji konwertujemy znaki nowej linii.

$ unix2dos payload.txt

Gdzie payload.txt, jest moim plikiem z żądaniem, po konwersji możemy już wysłać nasze żądanie do serwera:

$ cat payload.txt | nc 192.168.8.4 80

W odpowiedzi powinniśmy dostać kod strony. Z testowaniem usług przy użyciu netcat po nawiązaniu połączenia musimy wydawać polecenia zgodne ze specyfikacją danych usług, które są dostępne w plikach RFC, pod poniższym adresem: https://www.rfc-editor.org/rfc-index.html Teraz przetestujemy sobie połączenia. Do tego ćwiczenia potrzebujemy dwóch UNIX-ów w sieci LAN, aby nic nie zaburzało połączenia. Na powiedzmy hoście A, który będzie naszym serwerem wydajemy proste polecenie:

$ nc -l -p 9090

Z kolei na hoście B, który będzie pełnił funkcje klienta, podłączymy się pod otwarty na serwerze port.

$ nc 192.168.8.4 9090

Teraz dosłownie możemy porozmawiać z komputerem. Możemy również przesłać plik, na komputerze B nadajemy plik na komputer A, jednak przed nadaniem pliku, musimy wiedzieć że komputer A na niego oczekuje:

/* KOMPUTER A */
$ nc -l -p 9090 > file.txt
/* KOMPUTER B */
$ cat file.txt | nc 192.168.8.4 9090

Polecenie po przesłaniu pliku nadal będzie oczekiwać dalsze dane, możemy zakończyć połączenie za pomocą skrótu ctrl + c. Ostatnią rzeczą do przedstawienia tutaj odnośnie netcat jest przesłanie całego katalogu za pomocą polecenia tar z algorytmem kompresji gzip, jak to wygląda po względem technicznym? Otóż tworzymy skompresowane archiwum za pomocą tar wraz z gzip na standardowym wyjściu, które następnie przekazywane jest za pomocą potoku do ustawionego połączenia sieciowego przez nasz netcat do odbiorcy, gdzie znów potokiem przekierowane jest do dekompresji. Jednak kolejność wydawania poleceń jest odwrotna do sposobu działania, to odbiorca w tym przypadku komputer A musi czekać na katalog.

/* KOMPUTER A */
$ nc -l -p 9090 | tar -xzvf -
/* KOMPUTER B */
$ tar -czvf - sciezka/do/katalogu/ | nc 192.168.8.4 9090

Gdzie myślniki (-) oznaczają stardardowe wyjście.

Odnośnie sprawdzania odległych portów, to istnieje jeszcze jeden sposób, nieco przestarzały, ale nadal spełniający swoje zadanie. Mianowicie chodzi o telnet. Jest to protokół, który umożliwiał połączenie ze zdalną powłoką gdzieś na odległym serwerze. Jak każdy protokół, musi mieć programy go obsługujące, tak protokół telnet posiada program, o jakżeby innej nazwie jak telnet. Jestem ciekaw okoliczności w jakich ktoś pomylił się przy wpisywaniu portu i doszedł do wniosku że telnet można wykorzystać do skanowania portów na hostach w sieci, i takie zadanie przychodzi realizować temu programowi, w 95% przypadków jego użycia w obecnych czasach, innym zastosowanie jest bardziej zaawansowana konfiguracja nieco starszych urządzeń sieciowych lub też obsługa protokół TFTP. Zatem jak sprawdzić za pomocą telenetu czy port jest otwarty, najprościej wydając poniższe polecenie

$ telnet 192.168.8.4 22

Odpowiedź:

Trying 192.168.8.4...
Connected to 192.168.8.4.
Escape character is '^]'.
SSH-2.0-OpenSSH_7.9p1 Debian-10+deb10u2

Protocol mismatch.
Connection closed by foreign host.

Po tej odpowiedzi możemy bardzo, ale to bardzo wiele wywnioskować.

  1. Port 22 jest otwarty
  2. Host używa SSH w wersji 2.0
  3. Do obsługi SSH używa daemon OpenSSH w wersji 7.9p1
  4. System operacyjny jest GNU/Linux-em Debian w wersji 10 lub opartym na GNU/Linux Debian 10 (buster)

Oczywiście nie ma się co łudzić niewiele jest tak gadatliwych protokołów, ale jeśli tylko zobaczymy linijkę Connected to <HOST>. To nasz cel został osiągnięty, połącznie zostało nazwiązane i możemy sobie wpisać ten port jako otwarty. Zatem aby sprawdzić telenetem port wystarczy podać adres hosta następnie port i czekać na informacje o nawiązaniu połączenia.

 

10. Porady i sztuczki

Powtarzaj do skutku

Czasami może zdarzyć się że nie możemy wykonać pewnej czynności ponieważ serwer z którego potrzebujemy danych sam ich jeszcze nie posiada. Zatem jedyną rzeczą jaką możemy zrobić to stworzyć skrtypt, który zapętli nasz skrypt do momentu, gdy ten zróci poprawne wykonanie. Możemy wykorzystać do tego poniższy skrypt.

#!/bin/bash
while [ true ]; do . $1 && break; done

W dobie dzisiejszych komputerów pozostawienie skryptu na nieskończonej pętli, nie spowoduje jakiegoś nadmiernego obciążenia, jeden wątek może zostać obciążony na 100%. Co tu się tak naprawdę dzieje? Otóż skrypt uruchamia jakieś polecenie, nie wiadomo jakie, podawana przez użytkownika w parametrze pozycjnym, na podstawie wartości zwracanej przez skrypt określane jest przy użyciu && czy pętla wykona się ponownie czy też nie. Jednak generalnie w sztuce programowania przyjeło się kontrolowanie w jakiś sposób konstrukcji tego typu. Opcje są dwie. Albo ustawimy jakiś limit jej wykonań albo też możemy użyć czasu. Rozpatrzymy pierwszy przypadek użycia limitu.

i=1;
while [ $i -le 1000 ]; do echo "$i: "; . $1 && break; i=$((i + 1)); done

Tutaj dodałem licznik, który ma pewny limit. Warto zwrócić uwagę na to iż nie jest już to pętla nieskończona. Oczywiście można ten kod przerobić w taki sposób że warunek true pozostanie i wewnątrz pętli zimplementować mechanizmy jej kontroli. Jednak nie widze sensu w tym konkretnym przypadku. Identycznie jest ustawieniem pętli na czas. Zatem na początku pętli zdefiniowałem zmienną, której nadałem wartość 1, mniej więcej wyzerowałem licznik. Warunek ustawiłem, wartość licznika mniejszą lub równą 1000. Pod linią definiująca dalsze wykonianie pętli została umieszczona inkrementacja licznika i to jest wszystko. Teraz zajmiemy się limitem czasowym

if [ ! "$2" ]; then limit=10;
else limit=$2; fi
i=1;
starttime=$(date +%s);
while [ $(($(date +%s) - starttime)) -lt $limit ]; do
	echo "Sekund: $(($(date +%s) - starttime))";
	echo "Numer obrotu: $i";
	. $1 && break;
	i=$((i + 1));
done

Tutaj to znów pętla nie jest nieskończona, został ustawiony warunek, w którym sprawdzane jest czy różnica sekund pomiedzy czasem zmierzonym w momencie sprawdzenia warunku a czasem rozpoczęcia pętli jest mniejsza od limitu, w ten czas wykonywane jest ciało pętli, licznik tutaj został umieszczony dla celów badawczych aby sprawdzić ile obrotów pętli zostanie wykonanych na danym odcinku czasu. Lepiej nie tworzyć nieskończonych pętli. Dlaczego tutaj też zmieniłem warunek, mogła pozostać pętla nieskończona i ustawić limit czasowy z timeout-em w środku. Otóż jeśli w konstrukcji kontrolnej zdarzył by się błąd, pętla leciała by ku nieskończoności.


Wydrukowanie konkretnych linii z pliku

Omawiając to zagadnienie, warto wspomnieć jak możemy wyświetlić sobie plik wraz z numerami linii przy każdej z nich kiedy używamy polecenia cat wystarczy dodać przełącznik -n. Dla przykładu wylistujemy sobie fragment pliku /etc/passwd.

$ cat -n /etc/passwd | head -n 10
1 root:x:0:0:root:/root:/bin/bash
2 daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
3 bin:x:2:2:bin:/bin:/usr/sbin/nologin
4 sys:x:3:3:sys:/dev:/usr/sbin/nologin
5 sync:x:4:65534:sync:/bin:/bin/sync
6 games:x:5:60:games:/usr/games:/usr/sbin/nologin
7 man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
8 lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
9 mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
10 news:x:9:9:news:/var/spool/news:/usr/sbin/nologin

Polecenie head -n 10 odfiltrowuje z wyjścia na potoku ze wszystkich linii pozostawiają tylko 10 początkowych. Kiedy wiemy jak wypisać sobie plik wraz z numerami możemy teraz spokojnie, przejść do głównego tematu, który jest realizowany za pomocą polecenia sed z przełącznikiem -n. Po przełączniku podajemy polecenie dla sed. Sam sed jest edytorem strumienia, coś ala nieinteraktywny edytor tekstu, gdzie wiele rzeczy robi się za pomocą specjalnych poleceń i teraz tak też zrobimy.

$ cat -n /etc/passwd | head -n 10 | sed -n '3,8p'
3 bin:x:2:2:bin:/bin:/usr/sbin/nologin
4 sys:x:3:3:sys:/dev:/usr/sbin/nologin
5 sync:x:4:65534:sync:/bin:/bin/sync
6 games:x:5:60:games:/usr/games:/usr/sbin/nologin
7 man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
8 lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin

Polecenie sed podajemy w pojedyńczych apostrofach, na początku zawsze podajemy numery linii, na których mamy wykonać polecenie, którym jest mała literka po zakresie linii. Zakres linii może być pojedyńczą liczbą wtedy polecenie wykonywane jest na tej jednej konkretnej linii. Wszystkie polecenia sed są dostępne na stronie podręcznika polecenia, dostępnej chyba w każdym UNIX-ie.


Podgląd pliku na żywo.

Podgląd pliku w momencie wypełniania go informacjami jest niezwykle przydatny. Szczególnie gdy administrujemy usługami. Sam pamiętam gdzie dla zleceniodawcy monitorowałem serwer WWW ponieważ ciągle był problem z dostępnością udostępnionych na nim zasobów, po zresetowaniu połączeń wyszystko wracało do normy. Podejrzewałem jedno, atak DoS. Własnie za pomocą podglądu na żywo accesslog-u daemon'a Apache2 upewniłem się że to rzeczywiście atak DoS. Zatem aby uruchomić plik w taki sposób aby przyjrzeć się jak wypełnia się on danymi wystarczy wydać poniższe polecenie

$ tail -f sciezka/do/pliku

Plik będzie wyświetlał się i wypełniał ekran w miarę wypełniania go treścią.


Nieinteraktywne find and replace w strumieniu

Za pomocą już wcześniej poznanego programu sed możemy odnajdować i zamieniać ciągi znaków w strumieniu. Składnia tego polecenia jest nieco dziwna. Jednak jej opanowanie nie powinno przysporzyć problemów. W tym poleceniu zakres linii również może zostać użyty, poźniej następuje polecnie: s/old/new/[mods]. Polecenie poszuka piewszego wystąpienia ciągu old i zamieni je na new. Modyfikatory jakie możmy użyć z tym poleceniem to:

Warto wspomnieć że sed jest tutaj bardzo elastyczny, gdy będziemy musieli operować np na ukośnikach (/), to ukośniki z polecenia możemy zmienić na dowolny inny znak. Na przykład na małpę (@). Sed przyjmuje plik/ściezkę do pliku jak kolejny argument za poleceniem, użycie pliku jednak spowoduje, że wszelkie zmiany jakie na nim dokonamy, dokonamy tak naprawdę na utworzonym z pliku strumieniu, jeśli chcemy zapisać nasze zmiany musimy użyć przełącznika -i przed poleceniem.

Skrypt kończy swoje działanie po napotkaniu pierwszwgo błędu

Często problemem przy obszernych skryptach jest jeden błąd, może narobić niezłego bałaganu w plikach samego skryptu, jak nie gorzej w samym systemie. Jest na sposób oczywiście. Na początku skryptu należy ustawić opcje powłoki, aby kończyła działanie po pierwszym napotkanym błędzie, ustawienie to wymaga jedynie drobnego polecenia zapisanego przez pierwszymi poleceniami. Poniżej znajduje się to polecnie:

$ set -e

Możemy je sobie przestestować wykonując je w zwykłej powłoce, a następnie wpisać byle co w powłoce np. 'asdasdsdsdfa' przy zwykłych ustawieniach dostaniem informacje że nie odnaleziono takiego polecenia, ale w tym wypadku powłoka po prostu się zamknie. Tak samo będzie ze skryptem. BASH posiada jeszcze jedną dość przydatną rzecz jeśli chodzi o bardziej restrykcyjne działanie skryptów. Przy uruchamianiu skryptu bez tego ustawienia, możemy definiować puste zmienne. Po włączeniu tej opcji puste zmienne będą oznaczane jako błąd, a jeszcze opcja -e spowoduje zakończenie wykonywania skryptu. Ustawienie opcji bardziej restrykcyjnego traktowania zmiennych zawsze jest ustawiene wraz z kończeniem wykonywania skryptu na pierwszym błędzie. Ustawianie bardziej restyrkcyjnego traktowania zmiennych służy przełącznik -u polecenia set.

$ set -eu

Debugowanie skryptów powłoki BASH

Debugowanie skryptu powłoki, nie jest tak bardzo zawansowane ja w przypadku innych języków. Nie co liczyć na manualne uruchamianie linia po linii i tego typu rzeczy. Jedyne co dostaniemy to rozwinięte linie o ile korzystaliśmy z podstawień oraz wartości zmiennych, które muszą być wynikiem jakiś operacji. I to wystarczy. Jedyne co warto zmienić to jeśli skrypt korzysta z innego skryptu to ciężko się połapać, które linie są od czego, więc zmienimy znak zachęty odpowiedzialny oznaczenia BASH w trybie debugowania.

export PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
Gdzie:

Sekcja z FUNCNAME[0] nie zostanie użyta do momentu wywołania przez skrypt funkcji.


Twórz lepsze skrypt powłoki

Dawniej istniały oddzielne programy, których zadaniem była analiza kodu po względem jakości, takie programy były w stanie wystawić nawet programiście ocenę zgodną z anglosaskim system szkolnictwa, takie programy zwały się linterami. W obenych czasach lintery są zintegrowane w nowoczesne IDE, przekazując programistom różnego rodzaju wskazówki. Z racji tego że dla skryptów powłoki nie ma jakoś IDE, ponieważ są one tworzone w razie potrzeby, to ktoś w trosce o jakość tych skryptów stworzył własnie linter, skryptów powłoki BASH. Taki program nazywa się shellcheck i nawet posiada paczkę w repozytorium dystrybucji GNU/Linux Debian. Użycie go jest dziecinnie protste, jako pierwszy argument podajemy ścieżkę do skryptu.

$ shellcheck sciezka/do/skryptu

Wynik działania shellcheck przedstawiam poniżniej:

In RUS.sh line 18:
while [ $(($(date +%s) - starttime)) -lt $limit ]; do
				 ^-- SC2086: Double quote to prevent globbing and word splitting.


In RUS.sh line 21:
. $1 && break;
^-- SC1090: Can't follow non-constant source. Use a directive to specify location.
  ^-- SC2086: Double quote to prevent globbing and word splitting.

Niestety nie będzie tego widać na powyższym przykładzie, ale shellcheck swoje uwagi zwraca w kolorze. Tak więc błedy są oznaczone na kolor wiadomo - czerwony, ostrzeżenia - na zółty, a uwagi na zielony. Każda uwaga zwrócona przez shellcheck rozpoczyna się od pewnego rodzaju kodu identyfikującego komunikat, każdy kod na stronie wiki projektu na GitHub, posiada swoją stronę rozszerzającą informacje na jego temat z przykładami. Dlatego można zajrzeć w link poniżej https://github.com/koalaman/shellcheck/wiki, rozwijając zakładkę "Pages", znajduje się wyszukiwarka, gdzie możemy wrzucić kod interesującego nas błędu lub podać po ukośniku na końcu adresu linku.

Wykonanie polecenia o podanym czasie

Chcemy wykonać pewne polecnie, ale nie teraz powiedzmy że za dwie minuty, to możemy to zrealizować za pomocą polecenia at. Jeśli nasze polecenie za powiedzmy 2 minuty ma zostać uruchomione to na początku wskazujemy poleceniu at czas, który jest wynikiem dodawania pożądanego czasu do obecnego jak w przykładzie poniżej.

$ at now + 2 minutes

Następnie zostanie nam wyświetlony znak zachęty programu at>, po którym wpisujemy polecenia jakie mają się wykonać. Warto pamiętać o przekierowaniu wyjścia do pliku, ponieważ polecenie at, podczas wykonywania zadań nie zwrócić żadnych danych, chyba że mamy zainstalowany program mailx. Więc jeśli nam na tym zależy musimy te dane przekierować. Zatwierdzenie listy poleceń i wyjście z trybu polecenia at> dokonujemy za pomocą skrótu klawiszowego ctrl + d. Więcej informacji znajduje się na stronie podręcznika polecenia at.

AWK wyświetla linie wg. zakresu

Awk, podbnie jak sed za pomocą specjalnych poleceń może wyświetlić linie z konkretnego zakresu, jednak tutaj konstrukcja polecenia jest nieco bardziej skomplikowana. Kiedy otwieramy plik lub przekazujemy strumień to w awk jest specjalna zmienna, która przechowuje numer linii NR, i to na niej oprzemy warunki naszego polecenia.

$ awk 'NR>=2 && NR<=8' /etc/passwd

dos2unix, unix2dos

Przypomnijmy sobie ten drobny programik, który zamieniał znak końca wiersza w pliku z żądaniem HTTP dla telnet. To czasami może być potrzeba aby zamienić te znaki w drugą stronę, kiedy edytowaliśmy coś na MS Windows i nagle przeniesiemy to na UNIX-a, to nagle mamy takie znaczki jak ^M, to jeśli to kod źródłowy, to interpreter/kompilator może sypać błędami. Zamiast usuwać te znaki ręcznie możemy użyć właśnie programu o przeciwynym działaniu od tego którego używaliśmy przy żądaniu HTTP dla telnet, dos2unix

$ dos2unix hello.c

Tablica ASCII

Tablica ASCII jest dostępna w prawie każdym GNU/Linux za pomocą poniższego polecenia:

$ man 7 ascii

Automatyczne wylogowanie z połoki

Kiedy pracujemy bez GUI, możemy ustawić sobie automatyczne wylogowanie podczas bezczynnosci na podstawie wartość zmiennej TMOUT, której wartość przechowuje ilość czasu bez żadnego wydanego polecenia w wyrażonego w sekundach, po upływie tego czasu zostaniemy wylogowanii z połoki. Jeśli jednak w naszej powłoce działa jakiś proces to wylogowanie nie będzie możliwe, z kolei mimo procesów w tle wylogowanie nastąpi. Aby ustawić sobie autowylogowanie wystarczy zdefiniować w powłoce zmienną TMOUT i jeśli nie wydamy przez ten czas żadnego polecenia zostaniemy wylogowani. Zmienną również możemy dopisać do naszego pliku .bashrc, pamiętając poprzedzeniu deklaracji słowem export.

$ TMOUT=30

Timeout dla procesów

Za pomocą spcjalnego polecenia zakończyć działanie procesów jeśli przekroczą limit czasowy. Najprostszym przykładem żeby to zaprezentować jest ustawienie limitu czasu za pomocą polecenia timeout dla polecenia sleep.

$ timeout 5 sleep 7 || echo "It fails!"

Zwróćmy uwagę na to iż polecenie dla któremu checemy nadać czas oczekiwania podajemy jak argument polecenia timeout za raz po limicie czasowym.


Jaki jest mój publiczny adres IP?

Na to pytanie może odpowiedzieć nam jedna strona, jednak wymagane jest posiadanie w systemie polecenia curl. Kiedy mamy zainstalowany pakiet w systemie, wystarczy że wydamy poniższe polecenie aby dowiedzieć się jaki jest nasz publiczny adress IP.

$ curl ifconfig.co

Podgląd wielu plików na żywo

Może zdarzyć się tak że musimy podejrzeć kilka plików na żywo na jednym oknie. Możemy wspomóc się multiplekserami terminali takimi jak GNU Screen czy TMUX. Jednak nie jest to konieczne jeśli jesteśmy w stanie zainstalować w systemie taki program jak multitail, program jako argumenty przymuje kolejne pliki do podglądu, dzieli ekran na równe części a w każdej z tych części mamy jeden z naszych plików. Multitail zawiera wiele przełączników i konfigurowalnych opcji, które są opisane w wyczerpujący sposób na stronie podręcznika polecenia multitail.

$ sudo multitail /var/log/messages /var/log/auth.log

Wykonywanie poleceń co jakiś czas

Tytuł może być mylący. Może wskazywać na harmonogram zadań, jednak w tym akapicie nie o to chodzi. Na UNIX-ach istnieje takie polecenie jak watch, które uruchamia nam polecenie co jakiś interwał czasu, domyślnie są to 2 sekundy, ale oczywiście za pomocą przełącznika -n możemy ustawić dowolny interwał.

$ watch uptime

Warto wspomnieć o dwóch rzeczach. Watch najmniejszy interwał jaki może przyjąć to 0.1 sekundy. Drugą rzeczą jest największy możliwy interwał, który wynosi wielkość 32-bitowej zmiennej integer bez znaku czyli 2^32. Watch może być naprawdę użytecznym programem, o wiele więcej informacji znajduje się na stronie podręcznika polecenia watch.


Konwersja z użyciem ImageMagick

ImageMagick jest programem graficznym, którego obsługa nie należy do najbardziej przyjaznych użytkownikowi. Ma on jednak jedną bardzo ważną rzecz. Można niektóre czynności wykonać z poziomu terminala, a wraz z pakietem ImageMagick dostajemy polecenie convert, za pomocą którego możemy w prosty sposób konwertować obrazki. Skonwertujemy sobie na początek PNG na JPEG.

$ convert obrazek.png obrazek.jpg

Niezbyt skomplikowane? Innymi czynnościami jakie możemy wykonać za pomocą polecnie convert jest kompresja.

$ convert original.jpg -strip -sampling-factor 4:2:0 -quality 80 -interlace JPEG -colorspace RGB compressed.jpg

Za pomocą naszego polecenia możemy również zmienić wielkość naszego obrazka.

$ convert huge_image.png -resize 500x500 resized_image.png

Obrazek zostanie przeskalowany za pomocą w uzwględnieniem proprocji, aby wyłączyć tę funkcję wydamy poniższe polecnie.

$ convert huge_image.png -resize 500x500! resized_image.png

Najciekawszą rzeczą jaką możemy zrobić za pomocą polecenia convert jest stworzenie gifa wskazując np. wszystkie obrazki w danym folderze za pomocą symbolu wieloznaczności.

$ convert -delay 80 -loop 0 *.png my.gif

Połączenie wielu plików PDF w jeden

Pracujemy cięzko w systemie GNU/Linux, usprawniając nasze skrypty i nagle ktoś prosi nas o to aby połaczyć kilka PDF-ów w jeden żeby miał łatwiej do wydrukowania. Możemy spędzić znaczną częsć czasu na poszukiwanie odpowiedniego oprogramowania, chyba że użyjemy polecenia gs, skrótu od nazwy programu Ghostscript, służacego do manipulowania PostScript-em oraz PDF-ami.

$ gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=out.pdf file1.pdf file2.pdf file3.pdf ...

Łatwiejsze kopiowanie lub zmiana nazwy

Te zagadnienie mogą się przydać przy tworzeniu pierwotnej kopii pliku, przed wprowadzeń zmian oraz gdy utworzony plik powinien mieć jakieś przyrostek na końcu nazwy.

$ cp /etc/fstab{,.bak}

To polecenie spowoduje utworzenie kopii pliku /etc/fstab z rozszerzeniem .bak. Podobne polecenie możemy wykonać gdy jesteśmy w takiej typowej sytuacji, że do pliku tekstowego stworzonego na UNIX-ie musimy do dodać rozszerzenie .txt.

$ mv wazne_dane{,.txt}

du oraz ncdu

Programy takie jak du, pomagają monitorować użycie miejsca na dysku, jednak samo wydanie polecnie wydaje się mało przydatne więc poniżej umieszcze kilka przydatnych przełączników, aby du zwracało bardzie przystępne wyniki.

/* Wyświetlenie przestrzeni zużytej przez nasz katalog domowy */
$ du -sh ~/*

Innym ciekawym rozwiązaniem w monitorowaniu przestrzeni na dysku/dyskach może być program ncdu, do zainstalowania z repozytorium (przynajmniej w GNU/Linux Debian). Pozwala on w sposób bardziej interaktywny zaprezentowanie wykorzystania przestrzeni dyskowej. Program nie jest jakość bardzo skomplikowany, więc nie ma sensu go tu opisywać. Uruchomienie go bez żadnego argumentu pokaże zużycie dla katalogu, w którym się obecnie znajdujemy.

$ ncdu

Podgląd potoku

Istnieje narzędzie, dzięki któremu możemy podejrzeć kopiowanie danych, pv - Pipe Viewer. Dosłownie podglądacz potoku. Zasada korzystania z pv jest dosyć prosta, otóż chcąc skopiować zwyczajny plik, podajemy ścieżkę zródłową jako pierwszy argument następnie przekierowujemy standardowe wyście na ścieżkę docelową pamiętając po podaniu nazwy kopiowanego pliku.

$ pv Dokumenty/oldVM.ova > Pobrane/oldVM.ova

Inny przykładem tutaj może być tworzenie pendrive-ów bootowalnych z GNU/Linux-em.

$ dd if=Pobrane/manjaro-xfce-20.2.1-210103-linux59.iso | pv | dd  of=/dev/sdc bs=4M conv=fsync

Możliwe jest również użycie polecenia z przykładu ze zwykłym plikiem, jako ścieżkę źródłową podajemy ścieżkę do plik, natomiast jako ścieżkę dysk, tylko należy pamiętać aby podać cały, nie jedną partycje.

$ pv Pobrane/manjaro-xfce-20.2.1-210103-linux59.iso > /dev/sdX

Pewne działania w systemie działają bardzo długo...

Tak jak w tytule tego akapitu, niektóre operacje kopiowania działają bardzo długo a jeszcze jeśli nie damy żadnych dodatkowych opcji zwiększających gadatliwość tych programów to zobaczymy jedynie migający kursor. Jednak jest na jakieś rozwiązanie. Polecenie progress, jest wstanie wyciągnąć informacje na temat działania, niektórych poleceń systemowych takich jak cp, rsync itp. Poniżej lista:

cp, mv, dd, tar, cat, rsync, grep, fgrep, egrep, cut, sort, md5sum, sha1sum,
sha224sum, sha256sum, sha384sum, sha512sum, adb, gzip, gunzip, bzip2, bunzip2, xz, unxz, lzma, unlzma, 7z, 7za, zcat, bzcat, lzcat, split, gpg

Wystarczy że polecenie działa w tle lub na innym terminalu. Wystarczy wydać polecnie progress, już on sam je odnajdzie.


Wysyłanie komunikatów wewnątrz systemu w postaci maili

Aby móc wysyłać maile wewnątrz systemu, potrzebujemy programu mailx, wraz z nim zainstaluje się exim4. Pod czas jego konfiguracji wybierzemy konfiguracje lokalną. Po zainstalowaniu programu samo wysyłanie komunikatów jest proste za pomocą potoku przekazujemy komunikat, czy to log z pliku, wyjście ze skryptu czy zwykły napis za pomocą polecnie echo, temat podajemy po przełączniku -s po temacie podajemy nadawcę, przeważnie nazwa_uzytkownika@localhost.

$ echo "TEST" | mail -s "Komunikat testowy" xf0r3m@localhost

Lista otwartych plików

Po skopiowaniu danych pendrive, chcemy go odmontować jednak dostajemy komunikat o tym że cel jest zajęty. W tym przypadku możemy podejrzeć otwarte pliki za pomocą polecenia lsof i sprawdzić czy jakiś proces korzysta z plików z naszego pendrive'a, kiedy wydamy jest od tak po prostu w systemie ukaże nam się bardzo długa lista wyszystkich otwartych plików systemie, z racji konstrukcji UNIX-ów, gdzie prawie wszystko jest plikiem ta lista może być naprawdę długa. Możemy ją jednak ograniczyć za pomocą potoku oraz polecenia grep.

$ lsof | grep "bushi"
vim 4504 xf0r3m 4u REG 254,3 122880 7735057 /home/xf0r3m/Nextcloud/Devel/morketsmerke/articles/terminallog/.bash_bushido.html.swp

Automatyczne potwierdzenie wykonania polecenia

Czasami działanie, niektórych programów może mieć bardzo destrukcyjny wpływ na systemem, wiec same programy pytają czy kontynuować. Takie zachowanie jest bezpieczne, ale jeśli chcemy użyć tego polecenia w skrypcie? Czasami sami twórcy implementują opcje wymuszenia potwierdzenia zazwyczaj za pomocą przełącznika -f lub --force, nie jest to jednak standardem. Dla wszystkich poleceń, których działanie wymaga potwierdzenia a chcemy ich użyć w skrypcie to możemy przekierować do takiego polecenia wyjście polecenia yes, które po prostu potwierdzi automatycznie działanie takich programów.


Jednoczesne przekierowanie wyjścia do pliku i wyjście standardowe

Polecenie tee przekierowuje wszystko co dostanie na standardowe wejście na swoje standardowej wyjście oraz do pliku, który podamy jako pierwszy argument, polecenie to ma tyle zastosowań że aż ciężko wymienić. Na przykład:

$ bash -x script.sh 2>&1 | tee script.debug

W tym wypadku podczas debugowania sporych pętli możemy użyć polecnia tee. Jednak nie jest to najlepszy przykład ponieważ tracelog, BASH-a jest wyświetlany na strumieniu błędów więc musiałem podłączyć wyjście diagnostyczne do standardowego wyjścia.


Zapisanie sesji terminala

Tytuł może wprowadzić w błąd, ponieważ jeśli ktoś czytał rodział o historii wie, że każda sesja jest zapisna w historii sztuką jest ją tylko odnaleźć, jednak tutaj "Zapisanie sesji termianala" możemy określić jako nagranie sesji terminala do pliku tekstowego. Program script do uruchomienia potrzebuje pliku jako pierwszego argumentu po uruchomieniu zapisuje do niego wszystkie wpisane polecenia kiedy chcemy zakończyć nagrywanie wydajemy po prostu polecenie exit. Polecenie script może być niezwykle przydatne podczas tworzenia skryptów czy tutoriali.


Miekki restart powłoki

Czasami nasza powłoka może zachowywać się dziwnie, szczególnie gdy wyświetlimy jakiś przypadkiem jakiś plik binarny. To teraz możemy albo wyłączyć terminal i włączyć go ponownie lub wykonać miękki restart powłoki. Dlaczego miękki? Ponieważ jest on wykonywany z polecenia wydawanago właśnie w uszkodzonej powłoce, jeśli czujemy że coś jest nie tak, wywołajmy po prostu polecenie reset.


Uruchomienie polecenia na podstawie odpowiedniego obciążenia systemu (load average)

Za pomocą polecnie batch, możey ustawić odpowiedni program, który zostanie uruchomiony kiedy wartość load average osiągnie konkretną wartość. Warto zwrócić uwagę że jest polecnie podobne do polecenia at, nawet znak zachęty jest identyczny, więc konfiguracja jest już znana z at, warto wspomnieć że domyślną wartością załadowania systemu dla programu batch jest 0.8. Możemy to zmienić wykorzystując zmienną OPTS, w której to zdefiniujemy wartość load average, po której osiągnięciu zostanie uruchomione polecenie zdefiniowane w przy użyciu polecnia batch.

 

11. Emulatory terminala

Tworząc maszyny dla projektu VTMP, podczas instalacji dystrybucji BlackArch skierowanej pod testy penetracyjne po wybraniu środowiska zostaniemy nazwani noobami - nowicjuszem/słabiakiem. Daje to trochę do myślenia. Sam RMS nie korzysta ze srodowiska graficznego zatem tekstowa konsola systemu jest najlepszym emulatorem terminala, oparta na wyżej wspomnianej bibliotece GNU Readline. Jednak rzeczywistość weryfikuje nasze marzenia bycia pro, musimy skorzystać z przeglądarki albo jak odpalić muzykę na Spotify bez GUI. Na GitHub jest kilka projektów, z których możemy skorzystać, ale i tak poprawne skonfigurowanie programów odpowiedzialnych za dźwiek na UNIX-ach przypada konfiguracji środowiska graficznego, więc puki co radzę przy tym pozostać. Szanujmy nasz czas oraz pracę tych wszystkich osób zaangażowanych w tworzenie GUI. Ile środowisk tyle różnych emulatorów, ale jeden się wybija ponad wszystkie i trzeba go zainstalować. Mianowicie terminator, najciekawszą z funkcji jest możliwość podzielenia jednego okna na kilka odrębnych powłok

Na liście specjalnie napisałem panelu, ponieważ każdą wydzieloną częsć również możemy znów podzielić na kolejne dwie części w dowolnym kierunku. Samo początkowe okno jest pojedyńczym panelem. Inną ciekawą rzeczą jest możliwość zmiany nazw kart jeśli już ich używamy. Terminator daje znacznie więcej możliwości, pomoc jest dostępna pod klawiszem F1, niestety potrzebny jest internet. Wiem że Twój ulubiony emulator jest najlepszy jednak serdecznie polecam wypróbować terminator.


12. Koniec

To było by na tyle jeśli chodzi jakąś bardziej zaawansowaną naukę obsługi powłoki. Jeśli ktoś jest "powłokofilem", to polecam użyć poniższego polecenia.

$ man bash

Poziomu mistrzowskiego w obsłudze powłoki.