Как я могу сделать деление с переменными в оболочке Linux?
136
Когда я запускаю команды в своей оболочке, как показано ниже, она возвращает expr: non-integer argumentошибку. Может кто-нибудь, пожалуйста, объясните мне это?
$ x=20
$ y=5
$ expr x / y
expr: non-integer argument
@ShivanRaptor Хотя можно утверждать, что этот вопрос является вопросом RTFM, он, безусловно, является актуальным вопросом программирования оболочки. Это также разумный вопрос для тех, кто пришел из языков, которые не требуют разыменования (например, Ruby или JavaScript). Это должно быть оставлено открытым.
Тодд А. Джейкобс
6
@ShivanRaptor Нет, это по теме здесь. Это о программировании на Bash. Unix / Linux в первую очередь для использования системы, а не программирования. Теперь сценарии оболочки охватывают границу между программированием и использованием системы, так что это может быть тема на любом сайте. Если бы возник вопрос о том, «как настроить сеть», это определенно относится к Unix / Linux. Если бы это был вопрос об интерактивных сочетаниях клавиш в Bash, он бы тоже был там. Но вопрос о сценариях оболочки определенно стоит здесь и там.
Брайан Кэмпбелл
Смотрите мой ответ здесь, который иллюстрирует вычитание и деление переменных $ BASH, используя вызов Python из оболочки (для преобразования int в float ...): stackoverflow.com/questions/8385627/…
Виктория Стюарт
Ответы:
195
Эти переменные являются переменными оболочки. Чтобы расширить их как параметры для другой программы ( т.е.expr ), вам нужно использовать $префикс:
expr $x / $y
Причина, по которой он жаловался, заключается в том, что он думал, что вы пытаетесь оперировать буквенными символами ( т.е. не целыми числами)
Если вы используете оболочку Bash, вы можете достичь того же результата, используя синтаксис выражения:
Почему бы не использовать 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 года:
Ссылка на переменные Bash требует расширения параметров
Оболочкой по умолчанию в большинстве дистрибутивов Linux является Bash. В Bash переменные должны использовать префикс знака доллара для расширения параметров . Например:
x=20
y=5
expr $x / $y
Конечно, Bash также имеет арифметические операторы и специальный синтаксис арифметического расширения , поэтому нет необходимости вызывать двоичный файл expr как отдельный процесс. Вы можете позволить оболочке выполнять всю работу следующим образом:
Это не имеет ничего общего с разыменованием, но интерполяцией и exprне приветствуется в 2013 году.
Gilles Quenot
@sputnick Вы явно запутались. Пожалуйста, не стесняйтесь обращаться к словарю. Смотрите разыменование и интерполируйте .
Тодд А. Джейкобс
1
Лучшее слово расширяется , но не разыменование . Разыменование используется, когда мы используем указатели , здесь это не так, это просто простые переменные.
Жиль Квено
1
@Prashant: tldp, как известно, не является хорошей ссылкой в мире bash.
Жиль Квено
1
давайте предположим
x=50
y=5
затем
z=$((x/y))
это будет работать правильно. Но если вы хотите использовать / оператор в операторах case, то он не может решить это.
В этом случае используйте простые строки, такие как div или devide или что-то еще. См код
Это не верно. /отлично работает как метка оболочки Что не работает - это использовать *для умножения без цитирования, что может быть тем, что вы на самом деле сделали; это приводит к тому, что он эффективно переопределяет все последующие элементы в кейсе, который в вашем примере является «devide» и «modulo»
dave_thompson_085
0
Чтобы получить числа после десятичной точки, вы можете сделать это: -
Ответы:
Эти переменные являются переменными оболочки. Чтобы расширить их как параметры для другой программы ( т.е.
expr
), вам нужно использовать$
префикс:Причина, по которой он жаловался, заключается в том, что он думал, что вы пытаетесь оперировать буквенными символами ( т.е. не целыми числами)
Если вы используете оболочку Bash, вы можете достичь того же результата, используя синтаксис выражения:
Или:
источник
man bash
в командной строке (q
для выхода)Я считаю, что это уже упоминалось в других темах:
тогда вы можете просто набрать:
В вашем случае это будет:
или, если хотите, добавьте его как отдельный скрипт и сделайте его доступным в $ PATH, чтобы он всегда был в локальной оболочке:
источник
echo '1 / 3' | bc -l
Почему бы не использовать let; Я нахожу это намного проще. Вот пример, который вы можете найти полезным:
Еще один простой пример - подсчитать количество дней с 1970 года:
источник
Ссылка на переменные Bash требует расширения параметров
Оболочкой по умолчанию в большинстве дистрибутивов Linux является Bash. В Bash переменные должны использовать префикс знака доллара для расширения параметров . Например:
Конечно, Bash также имеет арифметические операторы и специальный синтаксис арифметического расширения , поэтому нет необходимости вызывать двоичный файл expr как отдельный процесс. Вы можете позволить оболочке выполнять всю работу следующим образом:
источник
expr
не приветствуется в 2013 году.давайте предположим
затем
это будет работать правильно. Но если вы хотите использовать / оператор в операторах case, то он не может решить это. В этом случае используйте простые строки, такие как div или devide или что-то еще. См код
источник
/
отлично работает как метка оболочки Что не работает - это использовать*
для умножения без цитирования, что может быть тем, что вы на самом деле сделали; это приводит к тому, что он эффективно переопределяет все последующие элементы в кейсе, который в вашем примере является «devide» и «modulo»Чтобы получить числа после десятичной точки, вы можете сделать это: -
источник