Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

Zrozumieć powłokę tekstową - standardowy strumień wyjściowy

Kilka pochlebnych komentarzy pod ostatnim wpisem przekonało mnie do rozwinięcia nieco tematu "śmierdzącej" konsoli. Pisał o tym roobal, później pisałem o tym również ja. Zarzucano mi jednak, że niewiele osób zrozumie coś z mojego tekstu, więc tym razem postaram się napisać trochę jak dziecku. Będzie może mniej fachowo ale bardziej zrozumiale. Moim celem jest udowodnienie Wam, że powłoka tekstowa wcale nie jest taka "śmierdząca", ale można to stwierdzić wyłącznie poznając ją bliżej. Dlatego chciałbym czytelnikom przybliżyć nieco charakterystyczne cechy języka programowania powłoki bash. Dlaczego bash? Bo jest najpopularniejszy, standardowy w każdej znanej mi dystrybucji Linuksa i możliwy do zainstalowania w każdym innym systemie operacyjnym - również w Windows.

Prawdopodobnie większość czytelników DP korzysta z systemu Windows. Wielu z nich może sobie nawet nie zdawać sprawy z tego, że interfejs który widzi przed sobą to powłoka explorer.exe. Ta jest obsługiwana myszką i jest to dla nich coś zupełnie normalnego. Ale Windows standardowo jest wyposażony jeszcze w powłokę tekstową cmd - gdzieniegdzie zwaną wierszem poleceń. Jej uruchomienie powoduje otwarcie okna konsoli, a oczom użytkownika ukaże się "znienawidzone" czarne tło i migający kursor. Powłoka ta służy oczywiście do uruchamiania programów, które nie mają interfejsu graficznego i dane wyjściowe wyświetlane są w formie tekstowej. Zatem z jakiego programu możemy skorzystać... hmmm... jest tu pewien problem, bo programów użytkowych po prostu nie ma. Dlatego właśnie użytkownicy Windows uważają, że konsola jest zła, bo jest zwyczajnie bezużyteczna. Ale uparcie szukamy i dowiadujemy się, że istnieje takie polecenie jak ping do diagnozowania połączeń sieciowych, którego na próżno szukać w "okienkach". Dlatego pośpiesznie wpisujemy ping dobreprogramy.pli naszym oczom ukazują się przydatne informacje. Chciałbym Wam pokazać jakie, ale w konsoli tekstowej cmd nie działa metoda Copy'ego-Paste'a. Właściwie nawet nie wiem, czy w jakikolwiek sposób wynik polecenia da się jakoś zapisać. Więc zamykam okno i stwierdzam, że ta konsola mi się do niczego nie przyda.

W powłoce tekstowej w Unix'ach sprawa wygląda zupełnie inaczej. Tutaj mamy pełną kontrolę nad danymi wejściowymi i wyjściowymi, a jak to działa postaram się wyjaśnić poniżej na przykładzie powłoki bash i systemu Linux. Należy też pamiętać, że większość (jak nie wszystkie) z metod opisanych poniżej działa również w powłoce sh i innych. Zdaję sobie sprawę, że opisywane przeze mnie techniki to absolutne podstawy i dla niektórych mogą wydawać się wręcz śmieszne, ale z pewnością przydatne. W końcowej fazie cyklu artykułów, w oparciu o poznane techniki, napiszemy skrypt, za pomocą którego zrobimy coś bardzo zaawansowanego, ale będziemy stosować wyłącznie bardzo proste przekształcenia. Prawdopodobnie niektórym opadną wtedy szczęki, jak zobaczą ile da się napisać w czterech linijkach :)

Każdy proces uruchomiony w Linuksie jest połączony z terminalem za pomocą trzech standardowych strumieni.
- STDIN - standardowy strumień wejściowy - to strumień, z którego program pobiera dane. Domyślnie jest to zawsze klawiatura.
- STDOUT - standardowy strumień wyjściowy - tutaj kierowane są wyniki programu. Domyślnie jest to ekran.
- STDERR - standardowy strumień błędów - tutaj kierowane są wszystkie informacje o błędach. Domyślnie jest to ekran.

Dziś skupimy się na STDOUT.

Oprogramowanie nie jest nic warte, jeżeli nie generuje pewnego rodzaju danych wyjściowych. Ale z doświadczenia wiemy, że mamy wiele typów tych danych, które muszą być zapisywane na różnych rodzajach pamięci. Wyświetlanie czegokolwiek na ekranie różni się znacznie od zapisu określonej treści w pliku czy karcie pamięci (przynajmniej z pozoru). Dlatego jednym z podstawowych założeń systemu operacyjnego Unix (a co za tym idzie i Linux) jest zagwarantowanie możliwości traktowania każdego elementu jako pliku. Odpowiedzialnością za udostępnienie takiego mechanizmu został obarczony system operacyjny. Zatem bez znaczenia stało się to, czy dane są przekazywane są do pliku dyskowego, terminala, karty pamięci czy innego urządzenia.

Jak to działa postaram się przedstawić za pomocą prostego polecenia echo. Jego zadaniem jest wyświetlenie wpisanego tekstu, np.

chomik@zhp:~$ echo dobreprogramy.pl to moja ulubiona strona internetowa dobreprogramy.pl to moja ulubiona strona internetowa

Jak widać powyżej efektem polecenia jest wyświetlenie w terminalu zdania "dobreprogramy.pl to moja ulubiona strona internetowa". Z technicznego punktu widzenia wspomniane zdanie zostało przekazane do standardowego strumienia wyjściowego polecenia echo, czyli zostało wyświetlone na ekranie. Jednak tutaj, w przeciwieństwie do powłoki cmd, domyślny STDUOT można zmienić za pomocą odpowiednich operatorów. Najprostszym i chyba najczęściej używanym jest operator przekierowania ">". Przekierujmy zatem nasze zdanie do pliku plik.txt.

chomik@zhp:~$ echo dobreprogramy.pl to moja ulubiona strona internetowa > plik.txt chomik@zhp:~$

Tym razem nasze zdanie nie zostało wyświetlone na ekranie, bo za pomocą operatora ">" przekierowaliśmy standardowy strumień wyjściowy do pliku plik.txt. Zatem sprawdźmy, czy nasz tekst rzeczywiście tam jest za pomocą instrukcji cat, której zadaniem jest wyświetlenie zawartości pliku na ekranie.

chomik@zhp:~$ cat plik.txt dobreprogramy.pl to moja ulubiona strona internetowa chomik@zhp:~$

Tekst oczywiście tam jest. Tą samą metodę możemy zastosować do każdego innego polecenie. Teraz już mogę Wam pokazać wynik polecenia ping, co próbowałem zrobić wcześniej, bo teraz mogę bez problemu te dane skopiować, ale również mogę je zapisać do pliku. Zatem:

chomik@zhp:~$ ping -c 2 dobreprogramy.pl > plik.txt chomik@zhp:~$ chomik@zhp:~$ cat plik.txt PING dobreprogramy.pl (194.0.171.150) 56(84) bytes of data. 64 bytes from nlb-web.xenium.pl (194.0.171.150): icmp_seq=1 ttl=122 time=28.0 ms 64 bytes from nlb-web.xenium.pl (194.0.171.150): icmp_seq=1 ttl=122 time=28.0 ms (DUP!) 64 bytes from nlb-web.xenium.pl (194.0.171.150): icmp_seq=1 ttl=122 time=28.0 ms (DUP!) 64 bytes from nlb-web.xenium.pl (194.0.171.150): icmp_seq=2 ttl=122 time=28.0 ms --- dobreprogramy.pl ping statistics --- 2 packets transmitted, 2 received, +2 duplicates, 0% packet loss, time 1004ms rtt min/avg/max/mdev = 28.000/28.000/28.000/0.000 ms chomik@zhp:~$

Teraz w pliku plik.txt mamy wynik polecenia ping. Uważni zauważą jednak, że z naszego pliku zniknęło zdanie, że DB to nasza ulubiona strona. Stało się tak, że operator ">" zawsze nadpisuje plik. Jeżeli go nie ma to go tworzy, jeżeli jest to usuwa i tworzy z nową treścią. Żeby tego uniknąć to należy skorzystać z operatora dopisania ">>", którego zdaniem jest dopisywanie treści na koniec pliku. Zatem przykład:

chomik@zhp:~$ echo dobreprogramy.pl to moja ulubiona strona internetowa > plik.txt chomik@zhp:~$ ping -c 2 dobreprogramy.pl >> plik.txt chomik@zhp:~$ chomik@zhp:~$ cat plik.txt dobreprogramy.pl to moja ulubiona strona internetowa PING dobreprogramy.pl (194.0.171.150) 56(84) bytes of data. 64 bytes from nlb-web.xenium.pl (194.0.171.150): icmp_seq=1 ttl=122 time=36.0 ms 64 bytes from nlb-web.xenium.pl (194.0.171.150): icmp_seq=1 ttl=122 time=36.0 ms (DUP!) 64 bytes from nlb-web.xenium.pl (194.0.171.150): icmp_seq=1 ttl=122 time=36.0 ms (DUP!) 64 bytes from nlb-web.xenium.pl (194.0.171.150): icmp_seq=2 ttl=122 time=32.0 ms --- dobreprogramy.pl ping statistics --- 2 packets transmitted, 2 received, +2 duplicates, 0% packet loss, time 1004ms rtt min/avg/max/mdev = 32.000/35.000/36.000/1.732 ms chomik@zhp:~$

To chyba już nie wymaga komentarza.

Podsumowanie

W tym wpisie poznaliśmy prosty mechanizm, który pozwala nam na przekierowanie standardowego strumienia wyjściowego. Należy pamiętać, że w Linuksie poleceń w konsoli jest tysiące, każde z nich ma wiele parametrów, ale wynik ich wszystkich można zapisać dokładnie w ten sam sposób. Te same dane można wykorzystać w celu dalszej obróbki, ale o tym będzie w następnym wpisie.  

Komentarze

0 nowych
Kpc21   10 #1 19.06.2010 22:59

"Chciałbym Wam pokazać jakie, ale w konsoli tekstowej cmd nie działa metoda Copy'ego-Paste'a. "

Jak najbardziej działa. Klikasz PPM, wybierasz Oznacz, zaznaczasz, robisz Copy za pomocą klawisza Enter i potem wklejasz chociażby na blogu.

Smoczysko   1 #2 19.06.2010 23:01

"Chciałbym Wam pokazać jakie, ale w konsoli tekstowej cmd nie działa metoda Copy'ego-Paste'a. Właściwie nawet nie wiem, czy w jakikolwiek sposób wynik polecenia da się jakoś zapisać. Więc zamykam okno i stwierdzam, że ta konsola mi się do niczego nie przyda."
Absolutnie nie zgadzam się z tym stwierdzeniem! Nie mam zamiaru bronić powłoki systemu Windows, ale aż tak zacofana nie jest. Gdy chcemy coś przekopiować: klikamy PPM na oknie cmd -> Edytuj -> Oznacz i wybieramy tekst do przekopiowania. Kiedy zaznaczymy już interesujący nas tekst naciskamy Enter i w schowku znajdują się dane z powłoki. Oto przykład dla polecenia, które podano w poście:

C:\Users\Smok>ping dobreprogramy.pl

Badanie dobreprogramy.pl [194.0.171.150] z 32 bajtami danych:
Odpowiedź z 194.0.171.150: bajtów=32 czas=20ms TTL=119
Odpowiedź z 194.0.171.150: bajtów=32 czas=17ms TTL=119
Odpowiedź z 194.0.171.150: bajtów=32 czas=17ms TTL=119
Odpowiedź z 194.0.171.150: bajtów=32 czas=17ms TTL=119

Statystyka badania ping dla 194.0.171.150:
Pakiety: Wysłane = 4, Odebrane = 4, Utracone = 0
(0% straty),
Szacunkowy czas błądzenia pakietów w millisekundach:
Minimum = 17 ms, Maksimum = 20 ms, Czas średni = 17 ms

Pozdrawiam, Smoczysko!

Kpc21   10 #3 19.06.2010 23:04

A przykłady które podałeś działają akurat równie dobrze w powłoce cmd.exe. W której - o dziwo - też się da pisać skrypty. I za czasów DOS-a i powłoki command.com (o bardzo podobnej składni jak cmd.exe) było to dość powszechne, a takie skrypty nazywano plikami wsadowymi.

Kpc21   10 #4 19.06.2010 23:04

Zapomniałem dodać - zamiast polecenia cat, należy zastosować type. A reszta jest zupełnie taka sama.

parasite85   8 #5 19.06.2010 23:22

Po pierwsze tak jak już wcześniej napisali działa kopiowanie.
Poza tym można jeszcze zastosować inną metodę:
ping dobreprogramy.pl >> ping.txt
ta prosta komenda zapisze wynik pinga w pliku tekstowym o nazwie ping w katalogu w którym się znajdowałeś w chwili pingowania:)

Chomik   4 #6 20.06.2010 09:28

Przyznaje się bez bicia, że nie wiedziałem, że się da kopiować. Stąd pewna doza niepewności w artykule. Okazuje się, że to jest całkiem proste, choć mało intuicyjne. Dzięki za wyprowadzenie z błędu - od czego są koledzy :) Obiecuję, że się poprawię.
Co do skryptów w cmd to oczywiście się da. Jak ktoś chce to może sobie napisać tzw. plik wsadowy .bat. Zresztą MS do tej pory z nich korzysta jeżeli chcesz np. przenieść prezentację PowerPoint na płytkę CD to na niej tworzy plik play.bat, który najpierw uruchamia PPViewer, a potem prezentację.

Kpc21   10 #7 20.06.2010 16:19

Jeśli chodzi o cmd.exe, to tutaj pliki wsadowe mają rozszerzenie .cmd. Natomiast rozszerzenie .bat zostało zachowane ze względu na kompatybilność wsteczną - i przez to jest od niego prawdopodobnie popularniejsze.

Dimatheus   22 #8 20.06.2010 21:17

Hej,

@ Chomik - "Okazuje się, że to jest całkiem proste, choć mało intuicyjne."

Czy takie mało intuicyjne - praktycznie dokładnie takie same jak w Unix'ie, tyle że nieco zmienione niektóre komendy; praktycznie rodem z DOS'a, w którym odpowiadały one angielskim czasownikom określającym dokładnie to, co chcemy zrobić. :)

Pozdrawiam,
Dimatheus

Chomik   4 #9 20.06.2010 22:37

Dimatheus - ale ja pisałem o kopiowaniu, a nie kierowaniu strumienia. Zresztą nieważne, bo ja tu chcę dyskutować o bash'u, a nie o cmd :)

  #10 21.06.2010 14:43

@Kpc21
Zgadza się,ale czysta powłoka dosowa ma bardzo mało poleceń,linuksowa ma tysiące,polecenia te są osobnymi programami z katalogu bin

  #11 21.06.2010 18:17

Powłoka CMD jest o wiele mniej intuicyjna, jednak wszystkie z pokazanych przykładów da się w niej osiągnąć. Pominę, że w powłoce Windows też mamy STDOUT, STDIN.

Jednak bardziej zaawansowane rzeczy trudno będzie uzyskać w cmd.

roobal   15 #12 21.06.2010 18:51

Co do kopiowania zawartości terminala do schowka, czyli wspomniana metoda kopiuj/wklej zależy nie tyle od powłoki co od samego terminala.

Nie wiem jak jest w Windows ale o ile w terminalach linuksowych, tj. Gnome Terminal czy Konsole można kopiować i wklejać ale już terminale typowo minimalistyczne, tj. Xterm itp. takiej opcji nie posiadają.

Pozdrawiam!

trux   11 #13 22.06.2010 01:36

roobal@
"Nie wiem jak jest w Windows ale o ile w terminalach linuksowych, tj. Gnome Terminal czy Konsole można kopiować i wklejać ale już terminale typowo minimalistyczne, tj. Xterm itp. takiej opcji nie posiadają.."

Nie do końca tak jest, bo działa kopiowanie i wklejanie przy pomocy 3-go przycisku myszy.

Kot-ek   10 #14 23.06.2010 15:14

"Chciałbym Wam pokazać jakie, ale w konsoli tekstowej cmd nie działa metoda Copy'ego-Paste'a. Właściwie nawet nie wiem, czy w jakikolwiek sposób wynik polecenia da się jakoś zapisać."

Da się, jak już zostało powiedziane.

"Jednak tutaj, w przeciwieństwie do powłoki cmd, domyślny STDUOT można zmienić za pomocą odpowiednich operatorów"

Nie ma żadnych przeciwieństw: operator przekierowania to >, a operatora dopisania to >>.

"Przyznaje się bez bicia, że nie wiedziałem, że się da kopiować. Stąd pewna doza niepewności w artykule. Okazuje się, że to jest całkiem proste, choć mało intuicyjne."

Intuicyjność można zwiększyć we właściwościach konsoli cmd uruchamiając w zakładce "Opcje" "Tryb szybkiej edycji". Wtedy zaznacza się LPM (Lewym Przyciskiem Myszki), ENTER'em kopiuje, a wkleja PPM.

roobal   15 #15 25.06.2010 21:54

@Trux Na pewno w Xterm? Bo już tego sposobu próbowałem i nie działał u mnie.

Pozdrawiam!