Pokusil jsem se bez úspěchu zvýšit číselnou proměnnou pomocí var=$var+1
A var=($var+1)
. Proměnná je číslo, ale zdá se, že bash jej čte jako řetězec.
Bash verze 4.2.45 (1) -vydání (x86_64-pc-linux-gnu) na Ubuntu 13.10.
Existuje více než jeden způsob, jak zvýšit proměnnou v bash, ale to, co jste vyzkoušeli, není správné.
Můžete použít například aritmetické rozšíření :
var=$((var+1))
((var=var+1))
((var+=1))
((var++))
Nebo můžete použít let
:
let "var=var+1"
let "var+=1"
let "var++"
Viz také: http://tldp.org/LDP/abs/html/dblparens.html .
var=$((var + 1))
Aritmetika v bashu používá syntaxi $((...))
.
Díky odpověď Radu Rădean , která poskytuje následující způsoby, jak zvýšit proměnnou v bash:
var=$((var+1))
((var=var+1))
((var+=1))
((var++))
let "var=var+1"
let "var+=1"
let "var++"
Existují i jiné způsoby. Podívejte se například na další odpovědi na tuto otázku.
let var++
var=$((var++))
((++var))
{
declare -i var
var=var+1
var+=1
}
{
i=0
i=$(expr $i + 1)
}
S tolika možností vede k těmto dvěma otázkám:
#!/bin/bash
# To focus exclusively on the performance of each type of increment
# statement, we should exclude bash performing while loops from the
# performance measure. So, let's time individual scripts that
# increment $i in their own unique way.
# Declare i as an integer for tests 12 and 13.
echo > t12 'declare -i i; i=i+1'
echo > t13 'declare -i i; i+=1'
# Set i for test 14.
echo > t14 'i=0; i=$(expr $i + 1)'
x=100000
while ((x--)); do
echo >> t0 'i=$((i+1))'
echo >> t1 'i=$((i++))'
echo >> t2 '((i=i+1))'
echo >> t3 '((i+=1))'
echo >> t4 '((i++))'
echo >> t5 '((++i))'
echo >> t6 'let "i=i+1"'
echo >> t7 'let "i+=1"'
echo >> t8 'let "i++"'
echo >> t9 'let i=i+1'
echo >> t10 'let i+=1'
echo >> t11 'let i++'
echo >> t12 'i=i+1'
echo >> t13 'i+=1'
echo >> t14 'i=$(expr $i + 1)'
done
for script in t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14; do
line1="$(head -1 "$script")"
printf "%-24s" "$line1"
{ time bash "$script"; } |& grep user
# Since stderr is being piped to grep above, this will confirm
# there are no errors from running the command:
eval "$line1"
rm "$script"
done
i=$((i+1)) user 0m0.992s
i=$((i++)) user 0m0.964s
((i=i+1)) user 0m0.760s
((i+=1)) user 0m0.700s
((i++)) user 0m0.644s
((++i)) user 0m0.556s
let "i=i+1" user 0m1.116s
let "i+=1" user 0m1.100s
let "i++" user 0m1.008s
let i=i+1 user 0m0.952s
let i+=1 user 0m1.040s
let i++ user 0m0.820s
declare -i i; i=i+1 user 0m0.528s
declare -i i; i+=1 user 0m0.492s
i=0; i=$(expr $i + 1) user 0m5.464s
Zdá se, že bash je nejrychlejší při provádění i+=1
když $i
je deklarováno jako celé číslo. Příkazy let
se zdají být zvláště pomalé a expr
je zdaleka nejpomalejší, protože není zabudován do bash.
Je tu také toto:
var=`expr $var + 1`
Pečlivě si všimněte mezer a také ` není '
Zatímco odpovědi Radu a komentáře jsou vyčerpávající a velmi užitečné, jsou specifické pro bash. Vím, že jste se konkrétně zeptali na bash, ale myslel jsem, že budu doufat, protože jsem našel tuto otázku, když jsem chtěl dělat to samé pomocí sh v busyboxu pod uCLinux. Tento přenosný za bash.
Pokud prohlásíte $var
jako celé číslo, pak to, co jste vyzkoušeli poprvé, bude ve skutečnosti fungovat:
$ declare -i var=5
$ echo $var
5
$ var=$var+1
$ echo $var
6
Reference: Typy proměnných, Bash Guide pro začátečníky
Ve všech odpovědích chybí jedna metoda - bc
$ VAR=7
$ bc <<< "$VAR+2"
9
$ echo $VAR
7
$ VAR=$( bc <<< "$VAR+1" )
$ echo $VAR
8
bc
je specifikováno standardem POSIX , takže by měl být přítomen ve všech verzích systémů kompatibilních s Ubuntu a POSIX. The <<<
přesměrování lze změnit na echo "$VAR" | bc
pro přenositelnost, ale protože se otázka ptá na bash
- je v pořádku použít <<<
.
Pro všechny výchozí varianty (let
, 1
Atd.) Je k dispozici problém s návratovým kódem (())
. To často způsobuje potíže, např. Ve skriptech, které používají set -o errexit
. Zde používám to, abych zabránil chybovému kódu 1
Z matematických výrazů, které vyhodnocují na 0
;
math() { (( "[email protected]" )) || true; }
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
Kecy, to bylo určeno pro jiné diskusní vlákno - nevím, jak smazat můj příspěvek
#!/bin/bash
myname=$(basename "$0")
# parse sub options
get_opts () {
rs='' && rc=0 # return string and return code
while [[ $# -gt 0 ]]; do
shift
[[ "$1" =~ -.* ]] && break || rs="$rs $1" && rc=$((rc + 1))
done
echo "$rs"
}
# help function
help () { cat <<EOP
$myname: -c cluster [...] -a action [...] -i instance [...]
EOP
}
while [[ $# -gt 0 ]]; do
case $1 in
"-a") ACTS="$(get_opts [email protected])"
;;
"-i") INSTS=$(get_opts [email protected])
;;
"-c") CLUSTERS=$(get_opts [email protected])
;;
"-h") help
;;
?) echo "sorry, I dont do $1"
exit
;;
esac
shift
done
exit
To musí být nejhorší způsob, jak splnit tak jednoduchý úkol, ale chtěl jsem to jen zdokumentovat pro zábavu, myslím (úplný opak oproti kódu golfu).
$ var=0
$ echo $var
0
$ var="$(python -c 'print('$var'+1)')"
$ echo $var
1
nebo
$ var="$(printf '%s\n' $var'+1' | bc)"
$ echo $var
1
Zde můžete použít jednu z dalších mnohem lepších možností.