Potrafię odczytać liczby i operacje za pomocą:
echo "First number please"
read num1
echo "Second number please"
read num2
echo "Operation?"
read op
ale potem wszystkie moje próby dodania liczb kończą się niepowodzeniem:
case "$op" in
"+")
echo num1+num2;;
"-")
echo `num1-num2`;;
esac
Biegać:
First number please
1
Second mumber please
2
Operation?
+
Wynik:
num1+num2
...lub...
echo $num1+$num2;;
# results in: 1+2
...lub...
echo `$num1`+`$num2`;;
# results in: ...line 9: 1: command not found
Wygląda na to, że wciąż otrzymuję ciągi znaków, gdy próbuję dodać add („2 + 2” zamiast „4”).
case
ani nic poza jedną linią:echo $num+$num
ponieważ to dokładnie odtworzy problem . Pomysł zminimalizowania kontekstu w pytaniach programowych wyjaśniono tutaj: sscce.orgOdpowiedzi:
Arytmetyka w powłokach POSIX odbywa się za pomocą
$
podwójnych nawiasów(( ))
:Możesz przypisać z tego (sans
echo
):Istnieje również
expr
:W skryptowaniu
$(())
preferowane jest unikanie rozwidlenia / wykonaniaexpr
polecenia.źródło
echo $(($num1$op$num2))
bez angażowaniacase
.case
tu mowy o zaangażowaniu.+
, więc będziesz potrzebowałcase
zewnętrznej strony do oddzielnego odejmowania.case
z kodu PO za pomocąecho $(($num1$op$num2))
- to zadziała, ale użyciecase
jest bardziej niezawodne, ponieważ domyślnie możesz obsługiwać błędy*
.Istniejąca odpowiedź to czysty bash, więc będzie szybszy niż ten, ale może obsłużyć tylko liczby całkowite. Jeśli potrzebujesz obsługi pływaków, musisz użyć zewnętrznego programu
bc
.scale=4
Mówibc
użyć czterech miejsc po przecinku. Zobaczman bc
więcej informacji.źródło
bash
nie obsługuje pływających arytmetyki punkt o$((...))
, wiele muszli (ksh93
,zsh
,yash
przynajmniej) zrobić. Zaletąbc
jest to, że obsługuje dowolną precyzję, podczas gdy arytmetyka powłoki jest ograniczona do typu procesoradouble
. Pamiętaj, że nie musiszscale
tutaj ustawiać . W przypadku dodatkówscale
parametr nie jest używany. Skala3.1415+9.99
będzie pochodzić od skali operandów (tutaj 4).450
a druga dziesiętna jest przechowywana w zmiennej$mynumber
? Na przykład450-$mynumber
.echo "450-$mynumber" | bc
powinien to zrobić. Jeśli chcesz, aby zmienna się rozwijała, musisz użyć podwójnych cudzysłowów zamiast pojedynczych cudzysłowów.computedval=$(echo 'scale=10;var1-var2' | bc)
nie działa, ani nie działacomputedval=$(echo 'scale=10;$var1-$var2' | bc)
Zauważ, że
\
przed*
(dla mnożenia) całe wyrażenie musi znajdować się w cudzysłowach `.źródło
expr
nie jest konieczne i nigdy nie jest konieczne przechwytywanie standardowego wyjścia polecenia tylko po to, aby zapisać go z powrotem na standardowe wyjście.minimalistyczny
źródło
Możesz także użyć
$[ ... ]
struktury. W tym przypadku korzystamy z wbudowanego mechanizmu w Bash, który jest szybszy i nieco wygodniejszy w użyciu. Ponieważ wiemy, że wszystko pomiędzy $ [, a] jest traktowane jako wyrażenie, nie musimy poprzedzać zmiennych$
. Podobnie nie musimy zabezpieczyć się*
przed traktowaniem go jak wzoru.źródło
W oparciu o sekwencję danych wejściowych, których żądasz od użytkownika, wydaje się, że używasz odwrotnej notacji polskiej.
Lepiej jest użyć bezpośrednio
dc
(kalkulatora biurkowego), ponieważ po to jest.Przykładowa sesja z wykorzystaniem
dc
:Lub nieinteraktywnie:
źródło