ฉันต้องการรู้ว่าอะไรคือความแตกต่างระหว่าง
a=$[1+1]
a=$((1+1))
let a=1+1
a=$(expr 1 + 1 )
4 ทั้งหมดกำหนดตัวแปร a ด้วย 2 แต่ความแตกต่างคืออะไร
จากสิ่งที่ฉันค้นพบจนถึงตอนนี้ก็คือ expr นั้นช้ากว่าเพราะมันไม่ใช่กระสุนจริงในตัว แต่ไม่มากกว่านั้น
ฉันต้องการรู้ว่าอะไรคือความแตกต่างระหว่าง
a=$[1+1]
a=$((1+1))
let a=1+1
a=$(expr 1 + 1 )
4 ทั้งหมดกำหนดตัวแปร a ด้วย 2 แต่ความแตกต่างคืออะไร
จากสิ่งที่ฉันค้นพบจนถึงตอนนี้ก็คือ expr นั้นช้ากว่าเพราะมันไม่ใช่กระสุนจริงในตัว แต่ไม่มากกว่านั้น
คำตอบ:
ข้อตกลงเหล่านี้ทั้งหมดเกี่ยวกับคณิตศาสตร์ แต่มีหลายวิธีและตัวแปรถูกสร้างขึ้นด้วยวิธีการที่ต่างกัน สิ่งเหล่านี้บางอย่างเป็นของbash
เชลล์โดยเฉพาะ
$((...))
เรียกว่าการขยายตัวทางคณิตศาสตร์ซึ่งเป็นเรื่องปกติของbash
และksh
เปลือกหอย สิ่งนี้ยอมให้ทำเลขคณิตเลขจำนวนเต็มอย่างง่ายโดยไม่มีจุดลอยตัว ผลลัพธ์ของนิพจน์จะแทนที่นิพจน์ดังที่echo $((1+1))
จะเป็นecho 2
((...))
เรียกว่าการประเมินผลทางคณิตศาสตร์และสามารถใช้เป็นส่วนหนึ่งของif ((...)); then
หรือwhile ((...)) ; do
งบ การขยายตัวทางเลขคณิต$((..))
แทนการส่งออกของการดำเนินการและสามารถใช้ในการกำหนดตัวแปรในi=$((i+1))
แต่ไม่สามารถใช้ในงบเงื่อนไข$[...]
เป็นไวยากรณ์เก่าสำหรับการขยายเลขคณิตซึ่งเลิกใช้แล้ว ดูเพิ่มเติม สิ่งนี้อาจถูกเก็บไว้เพื่อไม่ให้bash
สคริปต์เก่าแตก สิ่งนี้ใช้งานไม่ได้ksh93
ดังนั้นฉันจึงคาดเดาว่าไวยากรณ์นี้เฉพาะสำหรับการทุบตี หมายเหตุ : ช่องว่างสำคัญมากที่นี่ อย่าสับสนกับสิ่งที่ชอบ$[1+1]
[ $a -eq $b ]
การ[
เว้นวรรคเรียกว่าtest
คำสั่งและโดยทั่วไปคุณจะเห็นมันในส่วนการตัดสินใจ มันแตกต่างกันมากในพฤติกรรมและวัตถุประสงค์let
เป็น a bash
และksh
คำสำคัญที่ช่วยให้การสร้างตัวแปรที่มีการประเมินทางคณิตศาสตร์อย่างง่าย หากคุณพยายามที่จะกำหนดสตริงที่นั่นเหมือนlet a="hello world"
คุณจะได้รับข้อผิดพลาดทางไวยากรณ์ ทำงานในและbash
ksh93
$(...)
คือการทดแทนคำสั่งโดยที่คุณรับเอาต์พุตของคำสั่งและกำหนดให้กับตัวแปรอย่างแท้จริง คำสั่งของคุณที่นี่คือexpr
ซึ่งใช้อาร์กิวเมนต์ตำแหน่งเช่นexpr arg1 arg2 arg3
ดังนั้นช่องว่างมีความสำคัญ มันเป็นเหมือนเครื่องคิดเลขบรรทัดคำสั่งขนาดเล็กสำหรับเลขจำนวนเต็มบวกกับบางสิ่งที่เป็นจริง / เท็จและ regex นี่คือคำสั่ง shell-neutralนอกจากนี้ยังเป็นที่น่าสังเกตว่าส่วนขยายทางคณิตศาสตร์และการแทนที่คำสั่งถูกระบุโดยมาตรฐาน POSIXในขณะที่let
และ$[...]
ไม่ใช่
let
คำสั่งดำเนินการประเมินผลทางคณิตศาสตร์และเป็นเปลือกในตัว
เรียกใช้คำสั่งนี้และคุณจะไม่ได้รับอะไรเลย (ประเมินผลเท่านั้น):
let 1+2
$(( ))
ใช้เพื่อขยายเลขคณิต: อ่านที่นี่
เรียกใช้สิ่งนี้และคุณจะได้รับข้อผิดพลาด (เนื่องจากการขยาย):
$((1+2))
$[ ]
เป็นไวยากรณ์เก่าสำหรับการขยายเลขคณิต:
รูปแบบเก่า $ [expression] เลิกใช้แล้วและจะถูกลบออกเมื่อมีการทุบตี Bash Man Page
expr
เป็นคำสั่งไบนารีหากคุณต้องการขยายเลขคณิตภายในสถานการณ์ย่อยคำสั่งคุณสามารถใช้มันได้:
echo $(expr 1 + 2)
echo `expr 1 + 2`
เนื่องจากคำตอบบางข้อข้างต้นกล่าวถึงเป็นพิเศษksh93
มันก็คุ้มค่าที่จะสังเกตว่ามันสามารถทำเลขทศนิยมได้เช่น:
$ print $((1.0/3))
0.333333333333333333
คุณสามารถควบคุมความแม่นยำของเอาต์พุตด้วย printf เช่น:
$ printf "%.4f\n" $((1.0/3))
0.3333
ต้องระบุอย่างน้อยหนึ่งอาร์กิวเมนต์เป็นตัวเลขทศนิยมดังกล่าวข้างต้น หากทั้งคู่ระบุว่าเป็นจำนวนเต็มจะมีการคำนวณทางคณิตศาสตร์เฉพาะจำนวนเต็มเช่น:
$ print $((1/3))
0
สิ่งนี้มีประโยชน์เมื่อคุณต้องการเลขทศนิยมในเชลล์สคริปต์เนื่องจากคุณสามารถหลีกเลี่ยงการเรียกคำสั่งภายนอก
zsh
ksh
bash
zsh
kh93
let
ไม่ทำงานใน cron ฉันคิดว่าเป็นเพราะlet
มีสภาพแวดล้อมเป็นของตัวเอง ใช้$((...))
เนื่องจากเป็น POSIX ตัวอย่างเช่น,
let x=1+2
echo x=$x
ใน cron ให้ผลลัพธ์เป็น "x =" แต่ "x = 3" เมื่อเรียกใช้จากเชลล์
x=$((1+2))
echo x=$x
ผลลัพธ์เป็น "x = 3" ในทุกกรณี
((...))
จริงสามารถนำมาใช้สำหรับการมอบหมายงานในbash
,ksh
และzsh
:n=10; ((n+=10)); echo $n
พิมพ์ 20 และ((x=1)); echo $x
พิมพ์ 1.