Tags Posts tagged with "Bashowisko"

Bashowisko

przez -
12 1132
Konsola

Useless Use of X to określenie stosowane dla sytuacji, kiedy użycie polecenia X (np. cat czy echo) jest zbędne – bo istnieje możliwość użycia lepszego do tego zadania narzędzia (albo żadnego dodatkowego). Przykładowo według definicji na stronie gnu.org głównym przeznaczeniem polecenia cat jest konkatenacja (łączenie) dwóch lub więcej strumieni (np. plików) w jeden ciąg znaków a następnie skierowanie ich na standardowe wyjście. Z tego powodu użycie polecenia cat dla jednego tylko parametru jest w większości przypadków marnotrawieniem zasobów i niepotrzebnym wykonywaniem dodatkowego procesu. Dopuszcza się jednak użycie polecenia cat do wyświetlenia zawartości pliku na ekran.

Klasycznym przykładem jest użycie cat dla pliku I przekierowanie strumieniem do polecenia grep

cat <nazwapliku> | grep <fraza>

Innym często spotykanym nawykiem jest przekierowanie do polecenia less, celem wyświetlenia jego zawartości

cat <nazwapliku> | less

Istnieje małe prawdopodobieństwo, że używane przez nas narzędzie nie posiada możliwości wczytywania danych z pliku, co więcej większość z nich wymaga podania go jako parametru, jeśli uruchamiamy narzędzie samodzielnie (a nie przez potok).

Inny przykład dotyczy użycia poleceń ls, czy find dla listowania zawartości katalogu

lista_plikow=$(ls *)

gdzie problemem jest niepotrzebne wykorzystanie symbolu gwiazdki oraz zapominanie o domyślnym sortowaniu listy na wyjściu, (które również może spowalniać pracę).

Są to trywialne przykłady, które obrazują rodzaj problemu, z jakim mamy do czynienia. Na pierwszy rzut oka narzut, jaki mogą powodować to, co jedynie zmniejszenie czytelności kodu (co również jest kwestią sporną, są zwolennicy takich właśnie składni). Podobnych przykładów jest więcej i nie dotyczą one tylko cat czy ls – udokumentowano zjawiska w postaci zbędnego użycia poleceń test, wc czy kill -9. Każde z nich posiada jakiś narzut na wykonywany kod, czy to wydajnościowy, czy po prostu zmniejszający czytelność.

Nasuwać się może pytanie – jak duże są różnice w szybkości wykonywanych programów dla przedstawionych sytuacji. Postanowiliśmy sprawdzić ten oraz inne przykłady poddając testom różne warianty tych samych rozwiązań.

Metodologia testów:

W celu sprawdzenia różnic wydajnościowych przygotowaliśmy następujące środowisko testowe:

  • Serwer IBM xSeries 346 z dwoma fizycznymi procesorami Intel Xeon 3.0Ghz
  • 3072 MB pamięci RAM DDR2 ECC
  • 6 dysków SCSI, 15k obrotów na sekundę każdy, ustawione w sprzętowy RAID 5 (przybliżone transfery ~350MB/s odczyt, 90MB/s zapis)

Pomiary wykonywano na próbce 55 000 plików, 5000 o rozmiarze 1MB oraz 50000 o rozmiarze 1KB. Każdy z nich zapełniono danymi znakowymi, po 100 znaków na linię (w przybliżeniu 10 000 linii w większym oraz 10 linii w mniejszym pliku)

Porada: Operację generowania tekstowych plików można osiągnąć w następujący sposób:

dd if=/dev/urandom bs=1024 count=4096 | tr -dc a-zA-Z0-9 | sed -e "s/.\{100\}/&\n/g" > plik.txt

Z uwagi na ograniczenia jakie narzucał sprzętowy kontroler RAID (brak możliwości modyfikacji parametrów cache narzędziem hdparm) przed każdym testem czyszczono pamięć operacyjną ze zbuforowanych plików (poleceniem sysctl vm.drop_caches=3). Ma to na celu zapobiegnięcie nieprawidłowościom w wynikach następujących po sobie testów.

Do pomiaru informacji o czasie wykonywania, użycia procesora oraz pamięci wykorzystano narzędzie GNU time.

Test 1: cat vs grep

Pierwszy z testów to przedstawiony już trywialny przykład nadużycia polecenia cat. Porównujemy tutaj czas jakie potrzebowało każde z poleceń na ukończenie zadania, ilość użytej pamięci oraz obciążenie procesora. Test przeprowadzono na wymienionej wyżej próbce plików, parsując po kolei zawartość każdego z nich.

cat vs grep czas wykonywania

cat vs grep uzycie pamieci cat vs grep uzycie procesora

Jak widać różnice nie są tak znaczące jak mogło by się wydawać. Ilość użytej pamięci jest dokładnie taka sama, procent użycia procesora jest nieznacznie większy w przypadku samego polecenia grep. Różnica czasowa stanowi w przybliżeniu 1%, tj grep samodzielnie wykonuje się około 1% szybciej niż wersja wspierana poleceniem cat i potokiem.

Test 2: Użycie pętli dla dużej liczby plików

W drugim teście porównujemy dwa powyższe przykłady (cat i grep) dorzucając do tego element pętli. W poprzednim przypadku występowało ograniczenie narzucane przez system w postaci liczby parametrów jakie maksymalnie mogło przyjąć dane polecenie(w zależności od środowiska może to być np. 65 tysięcy). Przykładowo mając katalog zawierający kilkaset tysięcy plików użycie gwiazdki mogłoby nie zadziałać. Wielu początkujących programistów posłużyłoby się w takim przypadku pętlą, zapominając o znacznie wydajniejszych alternatywach (o których za chwilę).

Struktura testowanej pętli jest następująca

for i in * ; do
	cat $i | grep abc #metoda pierwsza
	grep abc $i  #metoda druga
done

Przetestujemy także ten sam skrypt ale zrealizowany przy użyciu xargs (przypomnijmy – problemem jest tutaj zbyt duża liczba plików w katalogu których nie można podać jako parametry). Składnia polecenia korzystająca z xargs jest następująca

find –type f <sciezka> | xargs grep <fraza>

Zamiast find można użyć nieco szybszego ls –U, pamiętając jednak że polecenie xargs potrzebuje pełnej ścieżki do plików, (w odniesieniu do miejsca uruchomienia skryptu).

petla czas wykonywania

petla uzycie pamieci petla uzycie procesora

Tak jak w poprzednim teście, różnice czasowe pomiędzy cat a grep były dość niewielkie, wahające się w granicach 3%. Znacznie różni się natomiast użycie procesora dla tych dwóch przypadków – w przypadku pętli wywołującej samo polecenie grep użycie CPU było ponad połowę mniejsze niż przy połączeniu cat i grep potokiem. Nietrudno zatem domyślić się że gdyby mocy obliczeniowej zabrakło to właśnie procesor stałby się „wąskim gardłem” a drugi z testów wykonałby się zdecydowanie dłużej.

Powodem dla wystąpienia takiej różnicy jest problem opisywany wcześniej – pętla dla każdego pliku w katalogu tworzyła dwa nowe procesy zamiast jednego. Rezultat – w porównaniu do poprzedniego testu ten wydłużył się o prawie 35%, mimo iż był wykonywany na tej samej próbce danych (55 tysięcy plików).

Różnica między pętlą a xargs z kolei widoczna jest gołym okiem – zarówno czasowo jak i pod względem narzutu w obliczeniach. Wniosek? Należy unikać sytuacji kiedy tworzymy wiele nowych procesów i szukać alternatywnych rozwiązań w postaci np. xargs.

Test 3 – wyświetlanie zawartości katalogu

W tym teście pokazujemy inny przykład Useless use of X – różne metody na wyświetlenie zawartości katalogu. Przetestowaliśmy następujące warianty

  • echo * – czyli gwiazdka rozwiązywana bezpośrednio przez interpreter. Należy przy tym pamiętać by nie popełniać niepotrzebnie błędu useless use of echo – gwiazdka może samodzielnie odpowiadać liście plików, jedynie aby wypisać ją na ekran trzeba posiłkować się poleceniem echo
  • ls – tutaj poza dodatkowym procesem w grę wchodzi również narzut w postaci domyślnego sortowania listy
  • ls –U – to samo co wyżej, z pominięciem sortowania
  • ls * – często popełniany błąd, określany mianem useless use of ls – nie ma potrzeby stosowania obu poleceń jednocześnie, wystarczy użycie gwiazdki
  • find . – podobnie jak ls wyjście jest sortowane oraz każdy plik jest wypisywany w nowej linii

Powyższe polecenia można wykorzystać aby przekazać wiele parametrów do jednego polecenia lub stworzyć pętlę operującą na każdym z plików ( for $i in ...).

Do tego testu zwiększyliśmy wielkość katalogu – z 50 tysięcy do 500 tysięcy małych plików.

katalogi czas wykonywania

katalogi uzycie pamieci katalogi uzycie procesora

Jak widać znajomość dostępnych w danym poleceniu przełączników oraz zasady ich działania zdecydowanie się przydaje. Szczególnie w przypadku narzędzia ls, stosując proste sztuczki możemy przyśpieszyć pracę programu nawet kilkakrotnie. Dobitnie widać to na dużej liczbie plików – czas potrzebny na posortowanie ich nazw rośnie nieliniowo (w mniejszym lub większym stopniu, w zależności od użytego algorytmu). W przypadku polecenia ls zrezygnowanie z sortowania oszczędza nie tylko czas ale również moc obliczeniową (30% mniejszy narzut) oraz ilość pamięci operacyjnej (brak sortowania oznacza też brak konieczności alokacji pamięci dla dużych ilości danych).

Polecenie ls * jest natomiast często popełnianym przez programistów błędem i zyskało osobny przydomek Useless use of ls. Na tak kiepski wynik składa się kilka elementów:

  • narzut w postaci sortowania (widoczny przy samym poleceniu ls)
  • narzut spowodowany użyciem gwiazdki (widoczny częściowo w przykładzie echo *)

Test 4 – wpływ potoku na wydajność

Postanowiliśmy sprawdzić również jak duży narzut może mieć przekazywanie różnej wielkości danych przez potok do innego polecenia. W tym celu posłużyliśmy się poleceniem find z parametrem exec, który dla każdego znalezionego pliku przekazywał będzie do polecenia wc pełną nazwę pliku (w przybliżeniu 10 znaków)

find files -type f -exec echo {}  \; | wc –l

oraz, dla porównania, to samo, jedynie zamiast pełnej nazwy pojedynczy znak „x”

find files -type f -exec echo -n a \; | wc –c

Powinno to powodować szybsze przekazanie danych do danej funkcji i tym samym szybsze jej wykonanie (w tym przypadku wc). Sprawdźmy zatem wyniki testu:

potok czas wykonywania

potok uzycie pamieci potok uzycie procesora

Jak widać różnica jest bardzo znikoma. Długi czas wykonywania samego testu wynikała głównie z powodu użycia funkcji exec polecenia find. Każdorazowe jego wykonanie powodowało narzut obliczeniowy przy tworzeniu nowego procesu (echo) dla każdego z plików. Pomijając ten efekt nie widać żadnego narzutu wywołanego domniemanym „wąskim gardłem” w postaci potoku.

Podsumowanie

Z powyższych testów można wyciągnąć co najmniej dwie nauki. Pierwsza dotyczy samego Useless use of X oraz ewentualnego narzutu na obliczenia jaki może powodować. Jak wynikało z na wykresów wpływ ten jest bardzo zróżnicowany i zależny od rodzaju i sposobu użycia danego polecenia. Pojedyncze nadużycie polecenia cat czy echo w niewielkim stopniu przekłada się na czas wykonywania samego programu (różnica rzędu kilku procent), miałoby ono jednak znaczenie jeśli ten proces byłby wielokrotnie powtarzany.

Elementem który najbardziej wpływa na wydajność i który najczęściej pojawia się w dokumentacji useless use of X jest zatem niepotrzebne tworzenie procesów. Jest to element którego należy się wystrzegać, ponieważ potrzebuje dużej ilości obliczeń (a co za tym idzie czasu do wykonania) zanim docelowe polecenie będzie mogło się wykonać. Widać to szczególnie na dużej liczbie wywołań –w pętli ten sam algorytm wykonywał się prawie 35% dłużej niż przy podaniu wszystkich argumentów w momencie uruchamiania. Należy zatem unikać takich sytuacji i szukać rozwiązań alternatywnych (np. w postaci xargs gdy plików jest za dużo by podać je jako parametr).

przez -
11 2082
Internet

W tym artykule przygotujemy skrypt do regularnego pobierania obrazków z serwisu tumblr. Tumblr to serwis w którym użytkownicy mogą zamieszczać stworzone przez siebie zdjęcia i rysunki, a cechą charakterystyczną wrzuconych materiałów jest schematyczny adres URL, który możemy wykorzystać do cyklicznego ich pobierania. Artykuł ma na celu pokazanie od strony praktycznej zastosowania skryptów powłoki, których użycie może ułatwić nasze codzienne czynności.

Na potrzeby artykułu wybrałem blog: pointlessxnostalgic.tumblr.com.

Przede wszystkim oglądamy jak strona główna wygląda w przeglądarce internetowej. Strona jest prosta – są na niej miniatury prowadzące do strony z pełnym obrazkiem. Wniosek nasuwa się prosty – powinniśmy ściągnąć stronę główną, następnie podstronę z obrazkiem, a później sam obrazek. Ale może jest prostszy sposób. W drugiej zakładce otwieramy pierwszy rysunek, klikamy na niego drugim przyciskiem i kopiujemy adres obrazka. W pierwszej zakładce klikamy drugim przyciskiem na miniaturce i również kopiujemy adres obrazka. Wklejamy oba adresy jeden pod drugim otrzymując:

http://25.media.tumblr.com/tumblr_m9iw61Ad3L1rohj25o1_1280.jpg
http://24.media.tumblr.com/tumblr_m9iw61Ad3L1rohj25o1_500.jpg

Patrzymy czym różnią się adresy. Widzimy, że różnią się w dwóch miejscach – na początku adresu (24 lub 25) oraz pod koniec nazwy pliku (_500 lub 1280). Sprawdzamy następny obrazek:

http://25.media.tumblr.com/tumblr_m8cumsZYxg1rohj25o1_1280.jpg
http://25.media.tumblr.com/tumblr_m8cumsZYxg1rohj25o1_500.jpg

Tutaj obrazki różnią się tylko na końcu. Sprawdźmy zatem, czy zadziała adres

http://24.media.tumblr.com/tumblr_m9iw61Ad3L1rohj25o1_1280.jpg

Zadziałał, zatem początek nie ma dla nas znaczenia. Być może są to serwery cachujące, które trzymają kopię plików. Chociaż nie zawsze mogą ją posiadać. Różnica jest tylko na końcu nazwy pliku.

Wiemy już jak strona działa i wiemy również, że nie jest aż tak trudna do rozłożenia. Z tej analizy wychodzi, że są 3 etapy działania programu

  • pobranie strony głównej z linkami do najnowszych zdjęć,
  • wyciągnięcie linków do zdjęć z pobranej strony,
  • zapisanie obrazków w folderze ze zdjęciami.

Etap pierwszy – pobranie strony głównej

Ważną rzeczą jest dopilnować, aby pobrany plik zawsze nazywał się tak samo. Wykorzystamy do tego znane nam już polecenie wget:

wget http://pointlessxnostalgic.tumblr.com/ -O strona.html

Etap drugi – wyciągnięcie linków do zdjęć

Zaczynamy od obejrzenia kodu strony (możemy to zrobić dowolnym edytorem tekstu). Wyszukujemy frazę “_500.jpg”. Znajdujemy linię:

<a href="http://pointlessxnostalgic.tumblr.com/image/30456035787"><img src="http://24.media.tumblr.com/tumblr_m9iw61Ad3L1rohj25o1_500.jpg" alt="letting go and holding on" /></a>

Czyli w zasadzie, jeśli wykonalibyśmy polecenie:

cat strona.html | grep _500.jpg

to w wyniku otrzymamy tekst:

<a href="http://pointlessxnostalgic.tumblr.com/image/30456035787"><img src="http://24.media.tumblr.com/tumblr_m9iw61Ad3L1rohj25o1_500.jpg" alt="letting go and holding on" /></a>
<a href="http://pointlessxnostalgic.tumblr.com/image/30133228668"><img src="http://24.media.tumblr.com/tumblr_m9aa6aMckr1rohj25o1_500.jpg" alt="a note, discovered in a piano bench" /></a>
<a href="http://pointlessxnostalgic.tumblr.com/image/30108217080"><img src="http://25.media.tumblr.com/tumblr_m99q1nKPJz1rohj25o1_500.jpg" alt="j.m. barrie" /></a>
<a href="http://pointlessxnostalgic.tumblr.com/image/29626521703"><img src="http://25.media.tumblr.com/tumblr_m8wqpzJUM81rohj25o1_500.jpg" alt="thirstthank you to braver-than-you-believe for this quote!&nbsp;" /></a>
<a href="http://pointlessxnostalgic.tumblr.com/image/29563426006"><img src="http://25.media.tumblr.com/tumblr_m8v29cDFoX1rohj25o1_500.jpg" alt="today and today and todaythank you to sorry-about-the-mad-person for sharing this lovely quote!" /></a>
<a href="http://pointlessxnostalgic.tumblr.com/image/29494222929"><img src="http://24.media.tumblr.com/tumblr_m8t8ifQwXb1rohj25o1_500.jpg" alt="eternity" /></a>
<a href="http://pointlessxnostalgic.tumblr.com/image/29202711916"><img src="http://25.media.tumblr.com/tumblr_m8lp2qwt5G1rohj25o1_500.jpg" alt="alone" /></a>
<a href="http://pointlessxnostalgic.tumblr.com/image/29010846306"><img src="http://25.media.tumblr.com/tumblr_m8glflj9v21rohj25o1_500.jpg" alt="TRUST LIFE" /></a>
<a href="http://pointlessxnostalgic.tumblr.com/image/28863823900"><img src="http://25.media.tumblr.com/tumblr_m8cumsZYxg1rohj25o1_500.jpg" alt="I hope." /></a>

Widzimy, że nasz plik z obrazkiem jest umieszczony w kodzie między cudzysłowami. Należałoby go stamtąd wyciągnąć. Możemy to zrobić za pomocą prostego użycia polecenia trs:

cat strona.html | grep _500.jpg | trs -e '\" \n' | grep _500.jpg

Mamy zatem bezpośrednie linki do miniatur, teraz wypadałoby jeszcze zamienić tekst _500 na _1280:

cat strona.html | grep _500.jpg | trs -e '\" \n' | grep _500.jpg | trs -e '_500 _1280'

W wyniku otrzymujemy taką treść:

http://24.media.tumblr.com/tumblr_m9iw61Ad3L1rohj25o1_1280.jpg
http://24.media.tumblr.com/tumblr_m9aa6aMckr1rohj25o1_1280.jpg
http://25.media.tumblr.com/tumblr_m99q1nKPJz1rohj25o1_1280.jpg
http://25.media.tumblr.com/tumblr_m8wqpzJUM81rohj25o1_1280.jpg
http://25.media.tumblr.com/tumblr_m8v29cDFoX1rohj25o1_1280.jpg  
http://24.media.tumblr.com/tumblr_m8t8ifQwXb1rohj25o1_1280.jpg
http://25.media.tumblr.com/tumblr_m8lp2qwt5G1rohj25o1_1280.jpg
http://25.media.tumblr.com/tumblr_m8glflj9v21rohj25o1_1280.jpg
http://25.media.tumblr.com/tumblr_m8cumsZYxg1rohj25o1_1280.jpg

W ten sposób otrzymujemy listę plików do ściągnięcia. Etap drugi zakończony, ale widzimy, że możemy to polecenie nieco skrócić. Po pierwsze – możemy wyrzucić pierwsze odsiewanie grepem:

cat strona.html | trs -e '\" \n' | grep _500.jpg | trs -e '_500 _1280'

Po drugie – możemy lekko modyfikując frazę wyszukiwaną grepem przenieść wszystkie warunki dla trs w jedno wywołanie:

cat strona.html | trs -e '\" \n _500 _1280' | grep _1280.jpg

W ten sposób otrzymaliśmy listę, którą możemy zapisać w pliku lista.txt

cat strona.html | trs -e '\" \n _500 _1280' | grep _1280.jpg > lista.txt

Ok, mamy zatem to co chcieliśmy osiągnąć w etapie drugim.

Etap trzeci – ściągnięcie plików z listy

Standardowo, posługujemy się w tym miejscu wgetem z przełącznikiem -i (od input-file)

wget -c -i lista.txt

Dobra, podsumujmy to co zrobiliśmy:
Zapisujemy nasz plik z całym kodem pod nazwą skr_tumblr, powinien on wyglądać w ten sposób:

#etap pierwszy:
wget http://pointlessxnostalgic.tumblr.com/ -O strona.html
#etap drugi:
cat strona.html | trs -e '\" \n _500 _1280' | grep _1280.jpg > lista.txt
#etap trzeci:
wget -c -i lista.txt

Uruchamiamy wpisując bash skr_tumblr. Zadziałał? Gratulacje!

No ale zawsze można pomarudzić – dziś ściągnęliśmy kilka plików, ale za miesiąc może być tych plików tysiące. Nasz skrypt się w tym po prostu zgubi. Zatem trzeba w wgecie wpisać folder zapisu obrazków (musi wcześniej istnieć):

#etap pierwszy:
wget http://pointlessxnostalgic.tumblr.com/ -O strona.html
#etap drugi:
cat strona.html |trs -e '\" \n _500 _1280' | grep _1280.jpg > lista.txt
#etap trzeci:
wget -c -i lista.txt -P ./obrazki

No dobra, ale jak znów odpalę skrypt, to znów się ściągają i to trwa i trwa i trwa. No cóż, trzeba zatem wymyślić jakiś mechanizm, który zablokuje ściąganie już pobranych plików. Pomyślmy – fajnie by było, jakby ściągnięte pliki zapisywały się na jakiejś liście i ta lista byłaby wykluczona z pobierania a do tego jakby sama się aktualizowała.

Zatem po kolei:

  • wyciągamy listę obrazków do pobrania z pliku strona.html
  • porównujemy ją z istniejącą listą usuwając powtarzające się wpisy
  • ściągamy tylko pliki z nowej listy

Zajmujemy się zatem tym etapem:

cat strona.html | trs -e '\" \n _500 _1280' | grep _1280.jpg > lista.txt

Chcielibyśmy, aby lista pobranych plików znajdowała się w pliku lista_pobrane.txt a lista plików do ściągnięcia w pliku lista_sciagane.txt. Najprostszy sposób – linię modyfikujemy dodając polecenie grep, które z pliku lista.txt odsieje to, co znajduje się w pliku lista_pobrane.txt.

cat lista.txt | grep -v -f lista_pobrane.txt > lista_sciagane.txt

Po tej operacji chcielibyśmy zaktualizować listę z pobranymi obrazkami:

cat lista.txt lista_pobrane.txt | sort | uniq > lista_pobrane1.txt
mv lista_pobrane1.txt lista_pobrane.txt

Niestety, podanie tego w jednej linii z pominięciem pliku lista_pobrane1.txt spowodowałoby, że okazyjnie plik lista_pobrane.txt stawałby się pusty. Czyli nasz etap drugi zamykałby się w kodzie:

cat strona.html |trs -e '\" \n _500 _1280'|grep _1280.jpg > lista.txt
cat lista.txt | grep -v -f lista_pobrane.txt > lista_sciagane.txt
cat lista.txt lista_pobrane.txt | sort | uniq > lista_pobrane1.txt
mv lista_pobrane1.txt lista_pobrane.txt

Należy pamiętać, aby przed pierwszym uruchomieniem stworzyć plik lista_pobrane.txt. Po jakimś miesiącu zauważymy, że skrypt wywołuje się coraz wolniej i po analizie okazuje się, że spowalnia go grep. W zastosowaniach, w których grep ma odsiać bardzo długą listę, program ten nie do końca się sprawdza. W takich przypadkach możemy zastąpić go poleceniem sort połączonym z uniq z opcją -u:

cat strona.html |trs -e '\" \n _500 _1280'|grep _1280.jpg > lista.txt
cat lista.txt lista_pobrane.txt | sort | uniq -u > lista_sciagane.txt
cat lista.txt lista_pobrane.txt | sort | uniq > lista_pobrane1.txt
mv lista_pobrane1.txt lista_pobrane.txt

Pamiętamy również, że w etapie trzecim powinniśmy używać pliku lista_sciagane.txt.

Etap czwarty – efekt końcowy

Reasumując, nasz skrypt po tych kilku zmianach wygląda w ten sposób:

#etap pierwszy:
wget http://pointlessxnostalgic.tumblr.com/ -O strona.html
#etap drugi:
cat strona.html |trs -e '\" \n _500 _1280'|grep _1280.jpg > lista.txt
cat lista.txt lista_pobrane.txt | sort | uniq -u > lista_sciagane.txt
cat lista_sciagane.txt lista_pobrane.txt | sort |uniq > lista_pobrane1.txt
mv lista_pobrane1.txt lista_pobrane.txt
#etap trzeci:
wget -c -i lista_sciagane.txt -P ./obrazki

No dobra, mamy skrypt, który działa, ale trochę niewygodnie jest go codziennie odpalać z palca. Dobrze by było go umieścić w CRONie z. Aby to zrobić, należy przygotować do tego nasz skrypt przez podanie mu folderów w których ma pracować. Ja to zrobię definiując zmienną $folder jako /home/arek/tumblr a następnie wpisując ją w każdym koniecznym miejscu. Dodatkowo wyjście wgeta będę kierował do pliku wget.log również w zdefiniowanym folderze. Wskazane jest również w pierwszej linii zdefiniować powłokę bash, w której ma działać nasz skrypt:

#!/bin/bash
#definicje zmiennych:
folder=$(echo -n "/home/arek/tumblr")
#etap pierwszy:
wget http://pointlessxnostalgic.tumblr.com/ -O $folder/strona.html -a $folder/wget.log
#etap drugi:
cat $folder/strona.html |trs -e '\" \n _500 _1280'|grep _1280.jpg > $folder/lista.txt
cat $folder/lista.txt $folder/lista_pobrane.txt | sort | uniq -u > $folder/lista_sciagane.txt
cat $folder/lista_sciagane.txt $folder/lista_pobrane.txt | sort | uniq > $folder/lista_pobrane1.txt
mv $folder/lista_pobrane1.txt $folder/lista_pobrane.txt
#etap trzeci:
wget -c -i $folder/lista_sciagane.txt -P $folder/obrazki -a $folder/wget.log

Teraz możemy już nadać skryptowi prawa wykonywania przez użytkownika i wstawić go w CRONie. Jeśli dany blog by dodawał więcej zdjęć, lub polecenie chcielibyśmy używać znacznie rzadziej, to zawsze możemy zmodyfikować pierwszy etap na przykład tak:

wget http://pointlessxnostalgic.tumblr.com/ http://pointlessxnostalgic.tumblr.com/page/2 http://pointlessxnostalgic.tumblr.com/page/3 -O ./strona.html -a ./wget.log

przez -
14 7184
Programowanie

Jeśli używasz jakiegokolwiek Linuksa, to wiesz, że już “czysty” system posiada mnóstwo programów. Zwyczajnemu użytkownikowi aż nadto. Ale czasami okazuje się, że masz jakieś węższe zastosowanie i co prawda możesz męczyć się z istniejącym oprogramowaniem, ale w zasadzie lepiej by było, jakby gdzieś znalazł się bardziej wyspecjalizowany program. Poszukiwania w google nie dają żadnych rezultatów, programować za bardzo nie umiesz, a napisanie przez kogoś odpowiedniego programu kosztuje majątek. W pewnym momencie przypominasz sobie, że jednym z największych atutów Linuksa są skrypty powłoki.

Gdzieś już widziałeś jakiś skrypt, jak go podejrzałeś, to nie wyglądał na taki straszny. W sieci jest mnóstwo poradników, które mówią o skryptach powłoki, każdy z nich daje olbrzymią ilość przykładów, ale to zazwyczaj są skrypty, które spełniają podstawowe funkcje. Poniżej postaram się przedstawić kilka prostych rad odnośnie tego od czego zacząć i na co zwrócić uwagę zacząć, żeby w efekcie działań powstał skrypt, który jest przydatny, nie zaś czysto teoretyczny. Nie będę przedstawiał tego na przykładach, jest ich od groma choćby na tym portalu. Osobiście piszę skrypty w powłoce bash, ale w zasadzie dla początkującego nie ma zbyt wielkiej różnicy między poszczególnymi powłokami (no, chyba, że są dedykowane do konkretnych celów jak np nologin czy wish).

1. Zdefiniuj konkretny cel

Zanim zaczniesz cokolwiek robić i pisać – pomyśl czego dokładnie chcesz. Jeśli nie zdefiniujesz sobie celu, nie będzie szans osiągnięcia go.

2. Zdefiniuj etapy

Jeśli już masz konkretny cel, pomyśl jak twoim zdaniem najłatwiej go osiągniesz. Spróbuj podzielić go na etapy. Na przykład, jeśli twoim celem byłoby chodzenie w czystych ubraniach, to etapami byłoby zdjęcie ubrań, włożenie ubrań do pralki, wsypanie proszku, odpalenie prania, wyjęcie z pralki i powieszenie na sznurkach, oczekiwanie na wyschnięcie ubrań, założenie czystych ubrań i chodzenie w czystych ubraniach. Podobnie sprawa wygląda ze skryptami – też musisz przemyśleć całą drogę do realizacji swojego pomysłu. Jest to najtrudniejszy element całego procesu, niestety też najrzadziej wymieniany. To za ten schemat postępowania płacisz programistom. Tutaj nie chodzi o znalezienie najprostszego sposobu, który ma jak najmniej kroków, tutaj chodzi o znalezienie sposobu, który wiesz jak zrealizować. Jeśli dobrze podzielisz cały swój skrypt na elementy składowe, to napisanie go zajmie ci niewiele czasu.

3. Pracuj nad jednym etapem jednocześnie

Jeśli już masz skrypt podzielony na kolejne etapy – zacznij realizować je w liniach kodu. Każdy z etapów oddzielaj komentarzem opisującym dany fragment. Jeśli piszesz etap drugi – sprawdź, czy na pewno otrzymuje z etapu pierwszego, wszystko co jest mu potrzebne. Korzystając przykładu z pralką – aby włożyć ubrania do pralki, musisz je mieć w ręku, nie zaś na sobie. Jeśli chcesz w jakimś etapie przeanalizować ściągnięty plik, to plik ten musi zostać pobrany we wcześniejszym etapie.

4. Używaj komentarzy

Zostawiaj w skrypcie notatki. Masz do tego możliwości, możesz nawet zostawić pół strony notatek przy każdej linii kodu. To właśnie notatki pozwolą Ci bezproblemowo poprawić skrypt, jeśli trzeba będzie to zrobić za pół roku.

5. Korzystaj z dokumentacji

Jeśli gdzieś utkniesz – sięgnij do mana lub użyj google. Jeśli nie wiesz co dalej zrobić, jak wywołać jakieś polecenie, co z nim zrobić – poszukaj pomocy. Wszelkie przełączniki polecenia znajdziesz w manie, mniej standardowe zastosowania znajdziesz za pomocą google. Jeśli nie wiesz jakiego polecenia użyć – wpisz w google co chcesz zrobić, na pewno znajdziesz podpowiedź.

6. Unikaj skrótów na siłę

Czasami można sobie skrócić polecenie, za pomocą przełączników innego polecenia. Wtedy kod jest “czystszy” i bardziej trendi. Przy okazji często mniej zrozumiały. Najprostszym przykładem jest tutaj polecenie grep. Za jego pomocą możemy wszystko wykonać na dwa sposoby przekazując mu tekst, który obrobi np.

cat plik.txt | grep poszukiwania

jak i wywołać samodzielnie

grep poszukiwania plik.txt

Wszystko jest czytelne, ale do pewnego momentu. Jeśli dodamy grepowi kilka opcji, do tego za pomocą opcji -e każemy mu wyszukiwać więcej zwrotów, to nagle może się okazać, że zgubiliśmy gdzieś nazwę pliku w którym szukamy. Pierwsze wywołanie jest mniej trendy (i bardziej zużywa klawisze na klawiaturze), ale za to zmniejsza ryzyko naprawdę głupiej pomyłki. Czasami też widzimy, że wszystko tak ładnie się ze sobą składa, że możemy wszystkie kilkadziesiąt elementów skryptu umieścić w jednej linii. Wszystko w porządku, jeśli nie będzie trzeba poprawiać kodu. Rozłożenie tej pojedynczej linii na kilkanaście mniejszych linijek i zrobienie tymczasowego pliku (lub plików) a także dopisanie kilku komentarzy może w przyszłości znacznie ułatwić analizę i poprawienie lub dostosowanie całego skryptu. Przy okazji może okazać się, że część takiego skryptu da się wykorzystać w innym skrypcie.

7. Unikaj nieznanych elementów

Zawsze staraj się pisać w oparciu o znane Ci komendy. Oczywiście, szczególnie na początku jest to trudne. Ale staraj się w skrypcie nie zawierać zbyt wiele nowych poleceń. Jeśli wiesz, że coś zadziała, to nie szukaj na siłę alternatyw celem szeroko rozumianego samorozwoju. Awangardowe rozwiązania są świetne gdy projektujesz knajpę, w zwykłych skryptach często zawadzają. Zazwyczaj lepiej jest iść prosto do celu niż z finezją wylądować w koszu.

8. Definiuj wszystkie zmienne

Zawsze pisząc skrypt zwracaj uwagę na zdefiniowanie wszystkich zmiennych. O ile w językach programowania kompilator zazwyczaj poinformuje cię, że czegoś nie zdefiniowałeś, o tyle w skryptach powłoki brak definicji nie jest przeszkodą, po prostu efekt może być inny od spodziewanego.

9. Nietypowe wywołania

Jeśli twój skrypt wymaga jakiegoś parametru wpisywanego z linii poleceń – sprawdź co się stanie, jeśli zapomnisz go wpisać. Sprawdź co się stanie, jeśli wpiszesz dziwny (na przykład litery zamiast cyfr) parametr. A co się stanie, jeśli wpiszesz cyfrę z siedemnastoma zerami? Albo wręcz zero/liczbę ujemną? Jeśli często zdarzają Ci się przypadkowe pomyłki – może warto pomyśleć nad zabezpieczeniem skryptu i sprawienie, że źle wywołany po prostu nie zadziała (np prosty warunek wykonania – tylko jeśli zmienna leży w zakresie 1-100).

10. Etapy spowalniające

Jeśli widzisz, że któryś etap mocno spowalnia działanie całego skryptu – pomyśl co możesz z tym zrobić. Czasami droga naokoło zajmuje więcej kroków, ale jest znacznie szybsza. Warto też pomyśleć o zmniejszeniu danych wejściowych przed obróbką przez choćby odsianie ich poleceniem grep.

11. Testuj w bezpiecznym środowisku

Jeśli chcesz testować skrypt – spokojnie możesz wykorzystać konto utworzone specjalnie do tego celu. Jeśli przez błąd skryptu stracisz wszystkie dane (w zasadzie raczej się to nie zdarzy, ale lepiej zapobiegać niż leczyć) do których masz prawa zapisu – może ogarnąć cię złość (gdy zrobisz to na domyślnym koncie) lub rozbawienie (gdy wykonasz to na pustym koncie).

12. Uzyskuj zgodę właściciela maszyny

Jeśli masz skrypt, który wykonuje się codziennie, to warto zapytać o zgodę właściciela maszyny. Może podpowie o jakiej godzinie tego nie robić. Niektóre skrypty potrafią zamulić komputer (u mnie w systemie są takie dwa). Jeśli dwa takie spotkają się o jednej porze dnia, to mogą narobić niezłego bigosu.

przez -
13 1182
Konsola

Program trs służy do zamiany łańcuchów znakowych. Jego działanie jest podobne do polecenia tr, jednak zamienia napisy a nie tylko pojedyncze znaki. Program ten jest częścią pakietu konwert służącego do konwersji plików z różnymi kodowaniami znaków.

Instalacja trs

Jeśli używamy dystrybucji zarządzającej pakietami za pomocą yuma, wpisujemy:

yum install konwert

Jeśli używamy dystrybucji zarządzającej pakietami za pomocą apt, wpisujemy:

apt-get install konwert

Niestety, część dystrybucji nie posiada tego programu w repozytoriach. Ze względu na fakt, że ostatnie wydanie powstało w 1998 roku, kompilacja może przysporzyć odrobinę trudności. Poniżej metoda polegająca na pobraniu źródeł programu konwert wraz z patchem, a następnie wyciągnięciu, spatchowaniu i skompilowaniu samego programu trs (wraz z plikiem man):

wget https://launchpad.net/ubuntu/+archive/primary/+files/konwert_1.8.orig.tar.gz --no-check-certificate
wget https://launchpadlibrarian.net/40339444/konwert_1.8-11.2build1.diff.gz --no-check-certificate
tar xzvf konwert_1.8.orig.tar.gz konwert-1.8/bin/trs.cc
gzip -d konwert_1.8-11.2build1.diff.gz
cat konwert_1.8-11.2build1.diff |head -n 991 | tail -n 67
konwert-1.8/bin/trs.cc.patch
cd konwert-1.8/bin/
patch trs.cc trs.cc.patch
g++ -Wall -O2 -fomit-frame-pointer -pipe trs.cc -o trs
cd ../..
mv konwert-1.8/bin/trs ./trs
rm -r konwert-1.8

Po skompilowaniu warto umieścić program w katalogu, który jest dopisany do zmiennej $PATH, czyli na przykład /usr/bin.

Sposób użycia trs

Program trs służy do kopiowania strumienia wejściowego do strumienia wyjściowego przy okazji zmieniając znaki. Przykład użycia:

echo "Ala ma kota" |trs -e 'm sprzedał'

Powyższe polecenie da nam w efekcie zdanie “Ala sprzedała kota”. Podczas podawania reguł można stosować standardowych eskejpów. Najczęściej używane:

  • \n – kod znaku końca linii
  • \s – kod spacji
  • \t – kod tabulatora
  • \\ – kod znaku \
  • \/ – kod znaku /
  • \nnn – nnn to kod oct znaku
  • \xnn – nn to kod hex znaku
  • \! – pusty łańcuch

Podczas używania programu pierwsze reguły mają pierwszeństwo, dzięki czemu możemy uzyskać taki efekt:

$ echo Leeloo |trs -e 'el n e i i aqq o\}\n x o u'
Linux

Przykłady zastosowania trs

Programu można używać w skryptach, jest prostszy niż sed, a przy okazji pozwala na łatwe używanie znaku tabulatora czy znaku końca linii. Pozwala też zoptymalizować i przyspieszyć niektóre czynności.

Porównajmy ściąganie wszystkich plików *.jpg ze strony http://osworld.pl/spotkania. Pierwszy skrypt będzie używał opcji zaszytych w programie wget, drugi zaś będzie posiłkował się programem trs.

Skrypt 1

date
wget -m -l 1 -A jpg http://osworld.pl/spotkania -o wget_skr_1
date
cat wget_skr_1 |tail -n 2

Wynik działania

nie, 26 sie 2012, 16:19:41 CEST
nie, 26 sie 2012, 16:21:00 CEST
ZAKOŃCZONO --2012-08-26 16:21:00--
Pobrano: 113 plików, 11M w 49s (232 KB/s)

Skrypt 2

date
wget http://osworld.pl/spotkania -O poczatek.html -o wget_skr_2
cat poczatek.html|trs -e '\x27 \n \" \n'|grep jpg >lista
wget -m -i lista -o wget_skr_2
date
cat wget_skr_2 |tail -n 2

Wynik działania

nie, 26 sie 2012, 16:23:35 CEST
nie, 26 sie 2012, 16:24:06 CEST
ZAKOŃCZONO --2012-08-26 16:24:06--
Pobrano: 26 plików, 6,6M w 27s (249 KB/s)

Czas wykonywania zadań w pierwszym przypadku to 1:19, w drugim 0:31. Nie bez znaczenia jest też fakt, że oba skrypty zapisały na dysku taką samą liczbę obrazków, natomiast pierwszy skrypt tak naprawdę pobrał 113 plików, drugi zaś 27 plików. W tym, przypadku nie była to wielka różnica, jeśli jednak na stronie byłyby komentarze lub więcej linków, wtedy różnica w czasie i ilości ściągniętych (niekoniecznie zapisanych) plików byłaby znacznie większa.

przez -
12 2084
Konsola program

Skrypty powłoki mają tą przewagę nad programami pisanymi w klasycznych językach programowania, że nie trzeba ich kompilować. Czasami jednak zachodzi taka konieczność, wtedy pomocą służy nam mały program – shc.

Opis działania shc

Działanie programu polega na zamianie skryptu na program w języku C a następnie skompilowaniu go. Kompilacja skryptów bash najczęściej jest używana w przypadku konieczności ukrycie hasła, które musimy umieścić w skrypcie, dzięki czemu użytkownik może nawet nie zauważyć, że do wykonania polecenia niezbędne jest jakiekolwiek hasło. Ponadto jest dobrym zabezpieczeniem przed analizą naszych skryptów na maszynie do której dostęp ma wielu użytkowników.

Programu tego można użyć również podczas zajęć dydaktycznych ze skryptów powłoki, gdy chcemy pokazać szkolonym osobom sposób działania jakiegoś mechanizmu nie dając jednocześnie możliwości wglądu w źródła. Dzięki opcji “-e” pozwala na ograniczenie czasowe wykorzystania skompilowanego programu, gdy chcemy zademonstrować skrypt potencjalnemu klientowi.

Instalacja shc

Program ten znajduje się w repozytoriach niektórych dystrybucji, można go też pobrać ze strony autora datsi.fi.upm.es/~frosal/ i samodzielnie skompilować (informacje na ten temat można znaleźć w pliku shc.README zawartym w paczce programu).

Program wywołujemy poleceniem

"shc -f skrypt"

Powstają dwa pliki

  • skrypt.x.c, który jest konwersją skryptu na język C
  • skrypt.x który jest plikiem binarnym.

Kompilator ten nie ma problemów z kompilowaniem nawet bardziej rozbudowanych skryptów bash. Należy jedynie pamiętać, że aby działał poprawnie musi mieć dostęp do wszystkich przywoływanych podprogramów.

przez -
3 4478
Konsola

Pracując z powłoką Basha, bardzo często korzystamy z polecenia history, aby przejrzeć ostatnie polecenia jakie były wykonywane na maszynie. Przydaje się to nam do przypomnienia sobie poleceń, pozwala sprawdzić jakie programy były uruchamiane w ostatnim czasie. Jeżeli na danym koncie pracuje kilu użytkowników, możemy zobaczyć jakie wydawali oni polecenia. Domyślne ustawienia historii Basha możemy łatwo zmienić. Dzięki temu wzbogacimy naszą historię o wiele użytecznych informacji.

Zmiana rozmiaru Bash History

Za wielkość pliku historii odpowiedzialna jest zmienna HISTFILESIZE. Domyślnie zmienna ta, przechowuje wartość 500. Polecenie history zatem 500 ostatnich poleceń wydanych w powłoce.

  490  fuser -a szafir.php
  491  fuser -a /home/kamil/
  492  vim szafir.php
  493  cat .htpasswd
  494  service httpd restart
  495  vim index.php
  496  vim .htpasswd
  497  vim .htpasswd
  498  vim wsinf.php
  499  echo $HISTFILESIZE
  500  history

Dodając do pliku ~/.bashrc, polecenie export HISTFILESIZE=2000, zwiększymy ilość linii do 2000.

Zmiana formatu pliku historii

Domyślny format historii pokazuje numer polecenia oraz polecenie. Niestety taki format nie informuje nas o dacie wykonania polecenia. Możemy to zmienić za pomocą zmiennej HISTTIMEFORMAT. Przechowuje ona format historii basha.

Możemy ustawić zmienną w taki sposób, aby przed każdym poleceniem zapisywała datę i czas wykonania polecenia: HISTTIMEFORMAT="[%d/%m/%y %T] ". Wtedy historia będzie wyglądała następująco:

  299  [15/01/11 13:41:21] wget http://ftp.cc.uoc.gr/mirrors/linux/moonos/moonos-2-kachana-desktop-i386.iso
  300  [15/01/11 13:41:21] uptime
  301  [15/01/11 13:41:21] w
  302  [15/01/11 13:41:21] date
  303  [15/01/11 13:41:21] cd svn/
  304  [15/01/11 13:41:21] ls
  305  [15/01/11 13:41:21] cd www/
  306  [15/01/11 13:41:21] svn update
  307  [15/01/11 13:41:21] cat /etc/hosts

Szybkie uruchamianie poprzednich poleceń

Bash udostępnia nam kilka skrótów, dzięki którym możemy wykonań ponownie polecenie jakie właśnie się zakończyło. Istnieje kilka metod na wykonanie tej czynności:

  1. Wciskając strzałkę do góry pojawi się nam poprzednie polecenie
  2. !! – uruchomione zostanie poprzednio wydane polecenie
  3. !-1 – uruchomione zostanie poprzednio wydane polecenie
  4. [Ctrl] + P – wyświetli się poprzednio wydane polecenie

Możemy również w prosty sposób odwołać się do polecenia o konkretnym numerze w historii za pomocą znaku ! poprzedzającego numer polecenia.

  518  [15/01/11 14:24:00] pwd
  519  [15/01/11 14:24:05] ping wp.pl
  520  [15/01/11 14:24:08] history
kamil@muszelka:~$ !518
pwd
/home/kamil

Znak ten pozwoli nam również na przywołanie z historii polecenia, które zaczyna się na konkretne słowo. Jeżeli wcześniej wykonaliśmy np. polecenie ps -efww | grep mysql, możemy je przywołać poleceniem !ps.

Kontrolowanie historii

Do kontrolowania wpisów w historii służy zmienna HISTCONTROL. Pozwala ona na eliminowanie duplikatów poleceń w historii. Wystarczy ustawić: export HISTCONTROL=ignoredups.

Aby usunąć duplikaty z historii należy wydać polecenie export HISTCONTROL=erasedups. Jeżeli z jakiegoś powodu nie chcemy aby dane polecenie zapisało się w historii możemy ustawić zmienną jako: export HISTCONTROL=ignorespace. Poprzedzając wtedy polecenie spacją, nie zostanie ono zapisane w historii.

Aby wyczyścić całkowicie historię należy wydać polecenie history -c. Aby specyficzne polecenia nie były zapisywane w historii możemy ustawić zmienną: export HISTIGNORE="pwd:ls:ls -ltr:". W parametrze podajemy polecenia jakie będą ignorowane.

PROMPT_COMMAND

Bash udostępnia nam jeszcze jedną bardzo ciekawą zmienną środowiskową. Jest nią PROMPT_COMMAND. Zawartość tej zmiennej jest wykonywana jako zwykłe polecenie Basha, przed wyświetleniem prompta.

Bash provides an environment variable called PROMPT_COMMAND. The contents of this variable are executed as a regular Bash command just before Bash displays a prompt. Dzięki temu możemy wykonywać różne polecenia automatycznie, podczas pracy w konsoli. Pozwoli to na wyświetlenie np. aktualnej godziny przez promptem PS1.

kamil@muszelka:~$ export PROMPT_COMMAND="echo -n [$(date +%k:%m:%S)]"
[18:01:29]kamil@muszelka:~$ uptime
 18:32:00 up 37 days, 17:27, 10 users,  load average: 0.55, 0.52, 0.47
[18:01:29]kamil@muszelka:~$

Inny przykład wykorzystania zmiennej. Pokazuje i koloruje aktualną ścieżkę w jakiej się znajdujemy.

export PROMPT_COMMAND='if (($? > 0)); then echo -ne "\033[1;31m"; fi'; export PS1='[\[\]\u\[\033[0m\] \[\033[1;34m\]\w\[\033[0m\]]\$ '

Aby wyłączyć tę właściwość wystarczy wpisać unset PROMPT_COMMAND.

przez -
1 3562
menedżer plików, pliki, katalogi, foldery

Z biegiem czasu nasze kopie zapasowe stają się coraz większe. Archiwa jakie są tworzone stają się bardzo duże. Rozpakowanie ich trwa również długo. I nagle pojawia się problem z jakim spotyka się każdy administrator systemu. Jakiś użytkownik na naszym serwerze prosi o przywrócenie jednego pliku, gdyż do przypadkowo usunął. Ten plik jest dla niego kolosalnie ważny, a sam użytkownik nie posiada kopii zapasowej.

I pojawia się problem. Okazuje się, że archiwum jakie posiadamy zajmuje około 4 GB. Rozpakowanie tego zajmie nam wieki o ile starczy nam miejsca na dysku.

Większość początkujących administratorów chwyci za narzędzie typu Midnight Commander. Otworzy nim archiwum (poczeka aż się całe rozpakuje), przywróci jeden plik a następnie zamknie program. Tak! Jest to jakaś metoda, pytanie czy najszybsza i najlepsza?

Otóż nie! Narzędzie tar, posiada jedną bardzo ciekawą funkcjonalność. Najpierw możemy w prosty sposób podejrzeć pliki:

kamil@muszelka:~/Pulpit$ tar tfz prestashop.tar.gz
prestashop/
prestashop/readme_fr.txt
prestashop/sitemap.php
prestashop/img/
prestashop/img/favicon.ico
prestashop/img/scenes/
prestashop/img/scenes/3.jpg
prestashop/img/scenes/1-large_scene.jpg
prestashop/img/scenes/3-large_scene.jpg
prestashop/img/scenes/2.jpg
...

Aby rozpakować wybrany plik, wystarczy go wskazać: tar xzvf prestashop.tar.gz prestashop/img/scenes/3-large_scene.jpg. Tak samo można wypakować dowolny katalog lub kilka plików. Wypakowywać można również dla archiwów bzip2 (przełącznik ‘j’).

Nie ma konieczności wypakowywania wszystkich plików, aby odszukać ten jeden ważny.

Konsola

Pracując w konsoli na wielu terminalach możemy chcieć szybko zsynchronizować historię pomiędzy nimi. Pozwoli to na pracę w nowym terminalu z zachowaniem historii z poprzednich.

Aby włączyć synchronizację historii pomiędzy powłokami, należy edytować plik ~/.bashrc w swoim ulubionym edytorze tekstowym.

Dopisujemy tam następujące polecenia:

shopt -s histappend
PROMPT_COMMAND="history -n; history -a"
unset HISTFILESIZE
HISTSIZE=2000

Polecenia te zwiększą limit linii historii z domyślnych 500 do 2000. Przy każdym wydanym poleceniu, historia zostanie zsynchronizowana i będzie dostępna dla pozostałych terminali.

Polecane

Jesień Linuksowa

1 1175
Polska Grupa Użytkowników Linuksa ma zaszczyt zaprosić na konferencję Jesień Linuksowa 2017, która odbędzie się w dniach 22 – 24 września 2017 roku. Jako...