Làm thế nào để tăng một biến trong bash?

Tôi đã cố gắng để tăng một số biến sử dụng cả var=$var+1var=($var+1) không thành công. Biến là một con số, mặc dù bash dường như được đọc nó như một chuỗi.

Bash phiên bản 4.2.45(1)-phát hành (x86_64-máy tính microsoft office hành) trên ổ 13.10.

Có nhiều hơn một cách để tăng một biến trong bash, nhưng những gì bạn đã cố gắng là không đúng.

Bạn có thể sử dụng ví dụ mở rộng số học:

var=$((var+1))((var=var+1))((var+=1))((var++))

Hoặc anh có thể sử dụng let:

let "var=var+1"let "var+=1"let "var++"

Cũng nhìn thấy: http://tldp.org/LDP/abs/html/dblparens.html.

var=$((var + 1))

Số học ở bash sử dụng $((...)) cú pháp.

Lựa chọn khác nhau để tăng bởi 1, và phân tích

Nhờ Nhà hàng Rădeanu là câu trả lời đó cung cấp tiếp theo cách để tăng một biến trong bash:

var=$((var+1))((var=var+1))((var+=1))((var++))let "var=var+1"let "var+=1" let "var++"

Có những cách khác quá. Ví dụ, nhìn trong các câu trả lời câu hỏi này.

let var++var=$((var++))((++var)){    declare -i var    var=var+1    var+=1}{    i=0    i=$(expr $i + 1)}

Có rất nhiều lựa chọn dẫn đến hai câu hỏi:

  1. Là có một buổi biểu diễn sự khác biệt giữa chúng?
  2. Nếu vậy mà, đó thực hiện tốt nhất?

Gia tăng hiệu mã kiểm tra:

#!/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=100000while ((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)'donefor 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

Kết quả:

i=$((i+1))              user    0m0.992si=$((i++))              user    0m0.964s((i=i+1))               user    0m0.760s((i+=1))                user    0m0.700s((i++))                 user    0m0.644s((++i))                 user    0m0.556slet "i=i+1"             user    0m1.116slet "i+=1"              user    0m1.100slet "i++"               user    0m1.008slet i=i+1               user    0m0.952slet i+=1                user    0m1.040slet i++                 user    0m0.820sdeclare -i i; i=i+1     user    0m0.528sdeclare -i i; i+=1      user    0m0.492si=0; i=$(expr $i + 1)   user    0m5.464s

Kết luận:

Nó có vẻ bash là nhanh nhất lúc thực hiện i+=1 khi $i được tuyên bố là một số nguyên. let báo cáo có vẻ đặc biệt chậm, và expr đến nay là chậm nhất bởi vì nó không được xây dựng vào bash.

Đó cũng đây:

var=`expr $var + 1`

Hãy cẩn thận, chú ý của các không gian và cũng có thể ` là không '

Trong khi nhà hàng của câu trả lời, và các ý kiến, có đầy đủ và rất hữu ích, họ đang bash-cụ thể. Tôi biết anh đã yêu cầu cụ thể về bash, nhưng tôi nghĩ rằng tôi muốn ống trong kể từ khi tôi tìm thấy câu này khi tôi đã tìm cách để làm điều tương tự sử dụng sh trong bận dưới uCLinux. Di động này ngoài bash.

Nếu bạn tuyên bố $var như là một số nguyên, sau đó, những gì bạn đã cố lần đầu tiên thực sự sẽ làm việc:

$ declare -i var=5$ echo $var5$ var=$var+1$ echo $var6

Tài liệu tham khảo: Loại biến, Bash hướng Dẫn cho người Mới bắt đầu

Có một phương pháp mất tích trong tất cả các câu trả lời - bc

$ VAR=7    $ bc <<< "$VAR+2"9$ echo $VAR7$ VAR=$( bc <<< "$VAR+1" )$ echo $VAR8

bc được chỉ định bởi DOS chuẩn, vì vậy nên có mặt trên tất cả các phiên bản của cài DOS hệ thống tuân thủ. Những <<< chuyển hướng có thể được thay đổi echo "$VAR" | bc di động, nhưng kể từ khi các câu hỏi, câu hỏi về bash - được rồi, để chỉ sử dụng <<<.

Sự trở lại mã 1 vấn đề là món quà cho tất cả định biến thể (let, (()) etc.). Điều này thường gây ra rắc rối, ví dụ như, trong kịch bản, sử dụng set -o errexit. Đây là những gì tôi đang sử dụng để ngăn chặn lỗi mã 1 từ toán biểu mà đánh giá 0;

math() { (( "$@" )) || true; }math a = 10, b = 10math a++, b+=2math c = a + bmath mod = c % 20echo $a $b $c $mod#11 12 23 3

Đây có phải là điều tồi tệ nhất cách để thực hiện một nhiệm vụ đơn giản nhưng tôi chỉ muốn tài liệu cho nó thú vị, tôi đoán (hoàn toàn trái ngược của mã golf).

$ var=0$ echo $var0$ var="$(python -c 'print('$var'+1)')"$ echo $var1

hay

$ var="$(printf '%s\n' $var'+1' | bc)"$ echo $var1

Nghiêm túc sử dụng một trong những khác tốt hơn nhiều sự lựa chọn ở đây.

Đây là việc cá cược an toàn

(( var = var + 1 ))

Nếu các giá trị kết quả là, không không, sau đó lập lối ra trên lỗi sẽ dừng lại Của kịch bản

set -evar=0(( var++ ))echo You will never get here