як я можу додати (відняти тощо) два числа з bash?


90

Я можу прочитати номери та роботу з:

echo "First number please"
read num1
echo "Second number please"
read num2
echo "Operation?"
read op

але тоді всі мої спроби додати числа провалюються:

case "$op" in
  "+")
    echo num1+num2;;
  "-")
    echo `num1-num2`;;
esac

Виконати:

First number please
1
Second mumber please
2
Operation?
+

Вихід:

num1+num2

... або ...

echo $num1+$num2;;

# results in: 1+2    

... або ...

echo `$num1`+`$num2`;;

# results in: ...line 9: 1: command not found

Здається, я все ще отримую рядки, можливо, коли я намагаюся додати add ("2 + 2" замість "4").


5
Я відредагував ваш заголовок, тому що це хороше загальне запитання, і якби ви звузили контекст донизу, ви зрозуміли б, що це не має нічого спільного caseі нічого іншого, крім одного рядка:, echo $num+$numоскільки це точно відтворить проблему . Ідея з мінімізуючи контекст в питаннях програмування пояснюється тут: sscce.org
ленок

2
+1 Привіт золотоногі, так, мені це стало зрозуміло згодом, але так, я цілком згоден з вашою думкою і так, чим конкретніше і «поодинокіше» питання - тим краще. Вітаю Ваші редакції :) Дякую :)
Michael Durrant

Відповіді:


116

Арифметика в оболонках POSIX виконується з $подвійними дужками (( )):

echo "$(($num1+$num2))"

Ви можете призначити з цього (sans echo):

num1="$(($num1+$num2))"

Є також expr:

expr $num1 + $num2

У сценаріях $(())краще, оскільки це дозволяє уникнути вилки / виконання для exprкоманди.


Або навіть безпосередньо echo $(($num1$op$num2))без участі case.
манатура

Тут ніхто не caseбере участь.
goldilocks

1
Ні, але ви використовували буквальне +, тому caseдля обробки віднімання знадобиться зовнішня частина.
манатство

1
@manatwork: Ви маєте на увазі виключити caseз коду ОП за допомогою echo $(($num1$op$num2))- це буде працювати, але використання caseбільш надійного, оскільки ви можете обробляти помилки за замовчуванням *.
goldilocks

+1 для вас обох. Я використовував case (можливо, не показав цього на початку), але як ви обидва зрозуміли, що проблема була не в цьому.
Майкл Дюрант

13

Існуюча відповідь - чистий баш, тому він буде швидшим за це, але він може обробляти лише цілі числа. Якщо вам потрібно обробляти поплавці, вам доведеться скористатися зовнішньою програмою bc.

$ echo 'scale=4;3.1415+9.99' | bc
13.1315

scale=4Каже bcвикористовувати чотири знака після коми. Див. Для man bcотримання додаткової інформації.


Зверніть увагу , що в той час bashне підтримує з плаваючою точкою арифметика з $((...)), багато снарядів ( ksh93, zsh, yashпо крайней мере) робити. Перевага bcполягає в тому, що він підтримує довільну точність, тоді як арифметика оболонки обмежена doubleтипом процесора . Зауважте, що тут не потрібно встановлювати scale. Для доповнень scaleпараметр не використовується. Шкала 3.1415+9.99буде отримана з операндів (тут 4).
Стефан Шазелас

Як зробити математику, якщо одне значення є, 450а інше десятковим зберігається на змінній $mynumber? Наприклад, 450-$mynumber.
Сигур

@sigur echo "450-$mynumber" | bcповинен це зробити. Якщо ви хочете, щоб змінна розширювалася, ви повинні використовувати подвійні лапки, а не одиничні лапки.
злий

@evilsoup, зараз це працює як шарм. Дякую.
Сигур

computedval=$(echo 'scale=10;var1-var2' | bc)не працює, не працюєcomputedval=$(echo 'scale=10;$var1-$var2' | bc)
StatsSorceress

5
echo `expr $a + $b`   
echo `expr $a - $b`   
echo `expr $a \* $b`   
echo `expr $a / $b`   

Зауважте, що \перед *(для множення) весь вираз повинен бути в межах зворотних лапок `.


1
exprне є необхідним, і ніколи не потрібно зафіксувати стандартний висновок команди, просто щоб повернути його до стандартного виводу.
чепнер


1

Ви також можете використовувати $[ ... ]структуру. У цьому випадку ми використовуємо вбудований механізм у Bash, який швидше та трохи зручніше у використанні. Оскільки ми знаємо, що все між $ [і] трактується як вираз, нам не потрібно передувати змінні $. Аналогічно, нам не потрібно захищатись *від цього, як до візерунка.

num1=2
num2=3
echo $[num1 + num2]
5

0

Виходячи з послідовності входів, які ви вимагаєте від користувача, здається, ви використовуєте зворотну польську нотацію.

echo "First number please"
read num1
echo "Second number please"
read num2
echo "Operation?"
read op

Ви можете краще просто скористатися dc(настільний калькулятор) безпосередньо, оскільки саме це і є.

DESCRIPTION
       Dc is a reverse-polish desk calculator which supports unlimited pre-
       cision arithmetic.

Приклад сеансу з використанням dc:

$ dc
1 2 + p    # This part is typed; the result comes next.
3
q  # This is also typed.
$

Або неінтерактивно:

$ dc -e '1 2 + p'
3
$
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.