Wykonywanie prostych obliczeń z poziomu powłoki
Transkrypt
Wykonywanie prostych obliczeń z poziomu powłoki
LINUX USER Wiersz poleceń bash i bc Wykonywanie prostych obliczeń z poziomu powłoki Nie zawsze do prostych obliczeń trzeba używać kalkulatora, takiego jak xcalc czy Kcalc – przecież bash może obsłużyć proste operacje arytmetyczne, a do bardziej zaawansowanych zastosowań zawsze możemy użyć bc. HEIKE JURZIK Poproszę o wiersz poleceń Najczęściej używaną powłoką użytkownika w Linuksie jest Bourne Again Shell, czyli Bash. Powłoka odbiera i interpretuje komendy, uruchamia programy i zarządza procesami. Dodatkowo bash przechowuje zmienne środowiskowe i zezwala na ich użycie innym programom. Poza różnorakimi możliwościami programowania, bash potrafi obsługiwać cztery podstawowe operacje matematyczne (dodawanie, odejmowanie, mnożenie i dzielenie) oraz operacje modulo, potrafi zatem wyznaczać wartości wyrażeń matematycznych. Jakkolwiek, obsługując tylko liczby całkowite (liczby całkowite bez pozycji po przecinku) do 32 bitów, bash nie jest matematycznym geniuszem. Jeżeli musimy popracować z liczbami zmiennoprzecinkowymi, spróbujmy użyć bc, „Basic Calculator”. Program może być używany zarówno interaktywnie jak i w formie skryptowej. Jak rachować Do wykonywania operacji matematycznych bash wymaga specjalnej składni. Starsze wersje muszą dodawać przedrostek dolara i zamykać wyrażenia matematyczne w nawiasach 92 Maj 2004 kwadratowych. Bash 2.0 i późniejsze wymagają zamykania wyrażeń w podwójnych nawiasach zwykłych. Mimo że późniejsze wersje powłoki bash obsługują starsze notacje, my pozostaniemy w naszych dalszych przykładach przy podwójnych nawiasach zwykłych. Bash wykonuje obliczenia na „zwyczajnych” liczbach oraz na zmiennych, na przykład: hj@asteroid:~$ echo $((1+1)) 2 Alternatywnie, możemy zdefiniować zmienne i przed użyciem w obliczeniach przyporządkować im wartości: hj@asteroid:~$ hj@asteroid:~$ hj@asteroid:~$ 20 hj@asteroid:~$ -1 a=4 b=5 echo $((a*b)) echo $((a-b)) Żeby zmieścić wyrażenia oraz obliczenia w pojedynczej linii, używamy średnika, który łączy poszczególne polecenie. Poprzedni www.linux-magazine.pl przykład może być również przedstawiony w pojedynczym wierszu, jak niżej a=4; b=5; echo $((a*b)) Inne operatory to znak minus (-) dla odejmowania, gwiazdka (*) dla mnożenia i ukośnik w prawo (/) dla dzielenia liczb całkowitych. Podwójna gwiazdka (**) jest używana jako operator wykładniczy, np. echo $((2**16)), znak procent jest operatorem modulo, który ustala resztę z dzielenia liczb całkowitych, np. ec $((5%3)) równa się 2, jako że 2 jest resztą z dzielenia 5 przez 3. Jak sobie radzić z liczbami zmiennoprzecinkowymi? Jeżeli napiszemy: echo $((1/3)), to zauważymy, że nie jest to tak naprawdę dzielenie liczb całkowitych, ale mimo to bash nie potrafi obsługiwać liczb zmiennoprzecinkowych. Wejdziemy do bc. W celu uruchomienia kalkulatora wpisujemy bc. Za pierwszym razem użytkownicy mogą być zakłopotani faktem, że po wykonaniu polecenia nie widać kursora. Bez paniki – bc czeka na wprowadzenie danych. Wyjść z kal- Wiersz poleceń kulatora możemy wpisując quit lub naciskając [Ctrl-d]. Jak można oczekiwać, wyrażenia arytmetyczne mogą być formułowane za pomocą zwykłych operatorów: +, -, *, i / oraz nawiasów. (1.1+2)*2 [Return] 6.2 Po wpisaniu wyrażenia naciskamy [Enter], bc natychmiast zwróci wynik. Średnik wpisujemy dla oddzielenia od siebie operacji: 1.1+2; 3.1-2 [Return] 3.1 1.1 bc przechowuje historie wszystkich poleceń, pozwalając za pomocą klawiszy strzałek na przewijanie do przodu i do tyłu pośród ostatnio użytych poleceń, tak samo jak to jest w powłoce. Cztery podstawowe operacje matematyczne w bc są identyczne z używanymi w bash, lecz operatory wykładnicze się różnią. Zamiast podwójnej gwiazdki, bc używa znaku daszka (^). Zmienne Jeżeli wielokrotnie będziemy używać tej samej liczby do obliczeń, sensownym wydaje się zdeklarowanie jej jako zmiennej. Znak równości jest używany do przyporządkowania wartości do zmiennej, na przykład: a=201; b=300 Niestety, bc nie pokazuje, czy zapisał zmienną. Aby wyświetlić wartości a i b musimy wpisać nazwę zmiennej i nacisnąć [Enter] – rzeczywiście bc jest wyjątkowo oschły. Każda zdefiniowana zmienna może być użyta w obliczeniach jako liczba: a*b 60300 a+b 501 Możemy się nieco zdziwić próbując podzielić te dwie zmienne: bc zwróci jako wynik 0. Aby obsługiwać operacje zmiennoprzecinkowe, musimy wyspecyfikować opcje -l podczas uruchamiania programu. Na szczęście jest także sposób, aby dodać wsparcie zmiennoprzecinkowe podczas pracy z programem. Wpisujemy scale=value (gdzie value to liczba całkowita pomiędzy 9 i 99), aby określić liczbę miejsc dziesiętnych wyświetlanych (i obliczanych) przez bc: scale=23 [Return] a/b [Return] .67000000000000000000000 Podczas wykonywania dzielenia możemy zauważyć, że bc cierpi na te same bolączki, co każdy inny program działający na liczbach zmiennoprzecinkowych: błędy w zaokrąglaniu. Na przykład, 1/3*3 zwraca wartość 0.999999999 (liczba dziewiątek wskazuje zdefiniowaną przez nas liczbę miejsc po przecinku), podczas gdy matematycznie równoważne wyrażenie 1/(3/3) jest obliczane poprawnie zwracając 1. Trzeba przyznać, że bc obsługuje liczby ujemne naprawdę dobrze. Wystarczy postawić znak minus przed liczbą: a + -b -99 -a -201 Inne światy Program bc ma w zanadrzu całkiem sporo sztuczek, na przykład funkcje matematyczne, takie jak potęgowanie: sqrt(144) 12 Domyślnie bc będzie używał systemu dziesiętnego, ale bardzo łatwo zmienić na inną podstawę: ibase=16 A 10 Wszystko co zostanie wpisane po poleceniu iba se będzie interpretowane przez bc jako dane w formacie szesnastkowym – włączając w to polecenie powrotu do systemu dziesiętnego, iba se=10. Oczywiście bc oczekuje danych szesnastkowych i poprawnie interpretuje 10 jako 16 w systemie dziesiętnym. Składnia w tym przypadku to iba se=A. Aby sprawdzić, jaką podstawę program aktualnie wykorzystuje, piszemy iba se bez żadnych parametrów. Podczas gdy iba se ustawia format wejścia, oba se określa podstawę dla wyjścia. Gdybyśmy byli zainteresowani tym, jaka jest wartość liczby 15 w systemie szesnastkowym, piszemy jak niżej: LINUX USER obase=16 [Return] 15 [Return] F Nie powinniśmy mieć żadnych trudności z przestawieniem z powrotem oba se na podstawę 10. Sztuczkę tą wykonamy za pomocą obase=10, zakładając że nie zmienialiśmy wcześniej formatu wejściowego iba se. Warto sprawdzić Program bc jest językiem programowania, pozwala to programowi na używanie struktur sterujących, podobnych do używanych przez C lub C++, co umożliwia bardziej złożone zastosowania. Żeby wyświetlić kwadraty numerów od 1 do 10, użyjemy prostej pętli f oszczędzając tym samym dużo pisania: for (i=1; i<=10; i++) U print i^2,'\n'; 1 4 9 16 25 36 49 64 81 100 Składnia użyta w pętli jest łatwa do zrozumienia – instrukcja, a następnie trzy wyrażenia w nawiasach. Pierwsze wyrażenie (i=1) jest wykonywane tylko raz przed przetwarzaniem pętli. Pętla jest wykonywana dopóki drugie wyrażenie nie będzie prawdziwe, czyli aż i<=10. Trzecie wyrażenie jest wykonywane przy każdym powtórzeniu, tzn. zwiększa się wartość i. Nie ma potrzeby uruchamiania bc za każdym razem, kiedy chcemy wykonać proste obliczenie, wpisujemy polecenie i zamykamy program. Możemy użyć potoków do przekazania obliczeń do bc, co jest w rzeczywistości potajemnym sposobem użycia powłoki bash do wykonywania zmiennoprzecinkowych obliczeń: hj@asteroid:~$ echo 1/3 | bc -l .33333333333333333333 Używając apostrofu (`) można nawet przechować obliczenia w zmiennych powłoki: x=`echo '$a*$b' | bc -l` pomnoży wartości zmiennych powłoki a i b i zapisze wynik w x. ■ www.linux-magazine.pl Maj 2004 93