Як я можу зробити поділ зі змінними в оболонці Linux?


136

Коли я запускаю команди в своїй оболонці, як показано нижче, вона повертає expr: non-integer argumentпомилку. Може хтось, будь ласка, пояснить це мені?

$ x=20
$ y=5
$ expr x / y 
expr: non-integer argument

4
@ShivanRaptor Хоча можна стверджувати, що питання є питанням RTFM, це, безумовно, дійсне питання програмування оболонки. Це також розумне питання для когось із мов, які не потребують перенаправлення (наприклад, Ruby або JavaScript). Його слід залишити відкритим.
— Тодд А. Джейкобс

6
@ShivanRaptor Ні, це тут на тему. Йдеться про програмування в Bash. Unix / Linux - це насамперед для використання системи, а не для програмування. Тепер сценарій оболонки охоплює межу між програмуванням та використанням системи, тому це може бути обговорене на будь-якому сайті. Якби виникло питання про те, "як мені встановити мережу", це однозначно належало б на Unix / Linux. Якби мова йшла про інтерактивні палітурки клавіш на Bash, це теж би там належало. Але питання щодо сценаріїв оболонок, безумовно, є на темі як тут, так і там.
— Брайан Кемпбелл

Дивіться мою відповідь тут, що ілюструє віднімання та поділ змінних $ BASH, використовуючи виклик Python з оболонки (для перетворення int в плавати ...): stackoverflow.com/questions/8385627/…
— Victoria Stuart

Відповіді:


195

Ці змінні є змінними оболонок. Щоб розширити їх як параметри до іншої програми ( тобто expr ), вам потрібно використовувати $префікс:

expr $x / $y

Причина, на яку він скаржився, полягає в тому, що він вважав, що ви намагаєтесь працювати з алфавітними символами ( тобто не цілими числами)

Якщо ви використовуєте оболонку Bash, ви можете досягти такого ж результату, використовуючи синтаксис виразів:

echo $((x / y))

Або:

z=$((x / y))
echo $z

1
Ви можете дізнатися багато, прочитавши man-сторінку для bash. Введіть man bashпідказку ( qдля виходу)
— неділю

62
Десь на цій сторінці слід зазначити, що більшість (якщо не всі) оболонок GNU / Linux виконують лише цілі операції .
— Skippy le Grand Gourou

35

Я вважаю, що це вже згадувалося в інших темах:

calc(){ awk "BEGIN { print "$*" }"; }

тоді ви можете просто ввести:

calc 7.5/3.2
  2.34375

У вашому випадку це буде:

x=20; y=3;
calc $x/$y

або якщо ви хочете, додайте це як окремий сценарій і зробіть його доступним у $ PATH, щоб ви завжди мали його у вашій локальній оболонці:

#!/bin/bash
calc(){ awk "BEGIN { print $* }"; }

4
Ви також можете використовуватиecho '1 / 3' | bc -l
— Євген

19

Чому б не використовувати let; Мені це набагато легше. Ось приклад, який вам може бути корисним:

start=`date +%s`
# ... do something that takes a while ...
sleep 71

end=`date +%s`
let deltatime=end-start
let hours=deltatime/3600
let minutes=(deltatime/60)%60
let seconds=deltatime%60
printf "Time spent: %d:%02d:%02d\n" $hours $minutes $seconds

Ще один простий приклад - обчислити кількість днів з 1970 року:

let days=$(date +%s)/86400

15

Посилання на змінну діаграми вимагає розширення параметрів

Оболонка за замовчуванням у більшості дистрибутивів Linux - Bash. У Bash змінні повинні використовувати префікс знака долара для розширення параметра . Наприклад:

x=20
y=5
expr $x / $y

Звичайно, Bash також має арифметичні оператори та спеціальний синтаксис арифметичного розширення , тому немає необхідності викликати бінарний файл expr як окремий процес. Ви можете дозволити оболонці виконувати всю роботу так:

x=20; y=5
echo $((x / y))

Див. Арифметичне розширення та арифметику оболонки в Довідковому посібнику Баша для всіх деталей горі.
— Тодд А. Джейкобс

1
Це не має нічого спільного з перенаправленням, а інтерполяцією, і exprце перешкоджає 2013 р.
— Жилль Кінот

@sputnick Ви явно розгублені. Будь ласка, зверніться до словника. Дивіться повагу та інтерполяцію .
— Тодд А. Джейкобс

1
Краще слово - це розширення , але не перенаправлення . dereferencing використовується при використанні покажчиків , це не так, це просто прості змінні.
— Жиль Кінот

1
@Prashant: tldp, як відомо, не є хорошим орієнтиром у світі баш.
— Жиль Кінот

1

припустимо

x=50
y=5

тоді

z=$((x/y))

це буде працювати належним чином. Але якщо ви хочете використовувати / оператора в операторах випадків, він не може його вирішити. введіть тут код У цьому випадку використовуйте прості рядки, такі як div або devide або щось інше. Дивіться код


Це неправильно. /прекрасно працює як оболонка корпусу. Те, що не працює, - це використовувати *для множення, не цитуючи це, що може бути тим, що ви насправді зробили; це призводить до того, що він ефективно перекриває всі наступні пункти у справі, які у вашому прикладі - "розділити" та "модуль"
— dave_thompson_085,

0

Щоб отримати цифри після десяткових знаків, ви можете зробити це:

read num1 num2
div=`echo $num1 / $num2 |bc -l`
echo $div
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.