Как увеличить значение переменной в bash?
Я попытался увеличить числовую переменную, используя как var = $ var + 1
, так и var = ($ var + 1)
без успеха. Переменная - это число, хотя bash, похоже, читает его как строку.
Версия Bash 4.2.45 (1) -release (x86_64-pc-linux-gnu) на Ubuntu 13.10.
7 ответов
Существует несколько способов увеличения переменной в bash, но то, что вы пробовали, неверно.
Вы можете использовать, например, арифметическое расширение :
вар = $ ((вар + 1))
((Переменная = переменная + 1))
((VAR + = 1))
((Вар ++))
Или вы можете использовать let
:
let "var = var + 1"
пусть "var + = 1"
пусть "var ++"
См. также: http://tldp.org/LDP/abs/html/dblparens .html .
var = $ ((var + 1))
Арифметика в bash использует синтаксис $ ((...))
.
Анализ производительности различных опций
Благодаря ответу Radu Rădeanu , который предоставляет следующие способы увеличения переменной в bash:
вар = $ ((вар + 1))
((Переменная = переменная + 1))
((VAR + = 1))
((Вар ++))
пусть "var = var + 1"
пусть "var + = 1"
пусть "var ++"
Есть и другие способы. Например, посмотрите другие ответы на этот вопрос.
let var ++
вар = $ ((вар ++))
((Вар ++))
{
declare -i var
переменная = переменная + 1
вар + 1 =
}
{
= 0
i = $ (expr $ i + 1)
}
Имея так много вариантов, вы можете ответить на эти два вопроса:
- Есть ли разница в производительности между ними?
- Если так, что лучше всего работает?
Инкрементальный код проверки производительности:
#! /Bin /Баш
# Чтобы сосредоточиться исключительно на производительности каждого типа приращения
#, мы должны исключить выполнение bash, когда циклы из
# эффективность измерение. Итак, приступим к индивидуальным сценариям, которые
# increment $ i по-своему.
# Объявите i как целое число для тестов 12 и 13.
эхо> t12 'declare -i i; I = I + 1'
эхо> t13 'declare -i i; I + = 1'
# Установите i для теста 14.
эхо> t14 'i = 0; i = $ (expr $ i + 1) '
х = 100000
while ((x--)); делать
эхо> t0 'i = $ ((i + 1))'
эхо> t1 'i = $ ((i ++))'
эхо> t2 '((i = i + 1))'
эхо> t3 '((i + = 1))'
эхо> t4 '((i ++))'
эхо> t5 '((++ i))'
эхо> t6 'let "i = i + 1"'
эхо> t7 'let "i + = 1"'
эхо> t8 'let "i ++"'
эхо> t9 'пусть i = i + 1'
эхо> t10 'пусть i + = 1'
эхо> t11 'let i ++'
эхо> t12 'i = i + 1'
эхо> t13 'i + = 1'
эхо> t14 'i = $ (expr $ i + 1)'
сделанный
для сценария в t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14; делать
line1 = "$ (head -1" $ script ")"
printf "% -24s" "$ line1"
{time bash "$ script"; } | & Пользователь grep
# Поскольку stderr отправляется в grep выше, это подтвердит
# нет ошибок при запуске команды:
eval "$ line1"
rm "$ script"
сделанный
Результаты:
i = $ ((i + 1)) пользователь 0m0.992s
i = $ ((i ++)) пользователь 0m0.964s
((i = i + 1)) пользователь 0m0.760s
((i + = 1)) пользователь 0m0.700s
((i ++)) пользователь 0m0.644s
((++ i)) пользователь 0m0.556s
пусть «i = i + 1» пользователь 0m1.116s
пусть пользователь «i + = 1» 0m1.100s
пусть пользователь «i ++» 0m1.008s
пусть i = i + 1 пользователь 0m0.952s
пусть i + = 1 пользователь 0m1.040s
пусть i ++ пользователь 0m0.820s
declare -i i; i = i + 1 пользователь 0m0.528s
declare -i i; i + = 1 пользователь 0m0.492s
I = 0; i = $ (expr $ i + 1) пользователь 0m5.464s
Вывод:
Кажется, bash работает быстрее при выполнении i + = 1
, когда $ i
объявляется как целое число. Операторы let
кажутся особенно медленными, а expr
на сегодняшний день является самым медленным, поскольку он не является встроенным.
Есть и это:
var = `expr $ var + 1`
Обратите внимание на пробелы, а также ` не
Хотя ответы Radu и комментарии являются исчерпывающими и очень полезными, они являются специфичными для bash. Я знаю, что вы специально задавали вопрос о bash, но я думал, что буду подключаться, поскольку нашел этот вопрос, когда искал сделать то же самое, используя sh в busybox под uCLinux. Этот переносной компьютер за пределами bash.
Если вы объявите $ var
как целое число, то то, что вы пробовали в первый раз, действительно будет работать:
$ declare -i var = 5
$ echo $ var
5
$ var = $ var + 1
$ echo $ var
6
Во всех ответах отсутствует один метод - bc
$ VAR = 7
$ bc <"$ VAR + 2"
9
$ echo $ VAR
7
$ VAR = $ (bc <<"$ VAR + 1")
$ echo $ VAR
8
bc
указан POSIX , поэтому он должен присутствовать во всех версиях Ubuntu и POSIX-совместимых систем. Переадресация <<
может быть изменена на echo "$ VAR" | bc
для переносимости, но поскольку вопрос спрашивает о bash
- это нормально, просто используйте <<lt;
.
Код возврата 1
присутствует для всех вариантов по умолчанию (let
, (())
и т. д.). Это часто вызывает проблемы, например, в сценариях, которые используют set -o errexit
. Вот что я использую для предотвращения кода ошибки 1
из математических выражений, которые вычисляются до 0
;
math () {(("$ @")) || правда; }
math a = 10, b = 10
math a ++, b + = 2
math c = a + b
math mod = c% 20
echo $ a $ b $ c $ mod
# 11 12 23 3