พวกเขาดูเหมือนจะส่งสัญญาณทั้งสองเพื่อทุบตีเพื่อเริ่มต้นด้วยคำสั่งอื่นตามสัญลักษณ์ แต่มีความแตกต่างอย่างชัดเจนหรือไม่?
พวกเขาดูเหมือนจะส่งสัญญาณทั้งสองเพื่อทุบตีเพื่อเริ่มต้นด้วยคำสั่งอื่นตามสัญลักษณ์ แต่มีความแตกต่างอย่างชัดเจนหรือไม่?
คำตอบ:
ด้วยสายนี้:
command1 && command2
command2 จะถูกดำเนินการหาก (และเฉพาะในกรณีที่) command1 ส่งคืนสถานะทางออกเป็นศูนย์ในขณะที่อยู่ในบรรทัดนี้:
command1 ; command2
ทั้ง command1 และ command2 จะถูกดำเนินการโดยไม่คำนึงถึง อัฒภาคอนุญาตให้คุณพิมพ์คำสั่งมากมายในหนึ่งบรรทัด
คุณสามารถลองใช้ความแตกต่างด้วยตัวคุณเอง:
ls /invalid/path && echo "hello!"
เนื่องจาก / ไม่ถูกต้อง / เส้นทางไม่มีอยู่ ls ไม่สามารถแสดงรายชื่อไดเรกทอรีให้คุณ มันจะล้มเหลวพร้อมกับข้อความแสดงข้อผิดพลาด: "ls: / invalid / path: ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว" ครึ่งหลังของคำสั่ง (echo "Hello!") คือไม่เคยดำเนินการแม้เพราะครึ่งปีแรกล้มเหลว
ls /invalid/path ; echo "hello!"
ข้อความแสดงข้อผิดพลาดเหมือนเดิมปรากฏขึ้น แต่คราวนี้ส่วนที่สองจะถูกดำเนินการ !
ls: / ไม่ถูกต้อง / พา ธ : ไม่มีไฟล์หรือไดเรกทอรีดังกล่าว
สวัสดี!
ทำไมถึงมีประโยชน์
สมมติว่าคุณต้องการแตกไฟล์ชื่อ archive.tar.gz
คุณสามารถใช้คำสั่งtar zxvf archive.tar.gz && rm archive.tar.gz
ได้
หากการดึงข้อมูลที่เก็บถาวรล้มเหลวไม่ว่าด้วยเหตุผลใดส่วนที่สองจะไม่ถูกดำเนินการ! คุณสามารถลองอีกครั้ง
ถ้าคุณใช้; ในสถานการณ์เดียวกันการเก็บถาวรจะถูกลบและคุณไม่สามารถลองอีกครั้งได้
&&
คือAND
หมายความว่าคำสั่งที่สองจะดำเนินการหากคำสั่งแรกส่งคืนจริง (ไม่มีข้อผิดพลาด)
AND
พารามิเตอร์ที่ 2 จะไม่เกี่ยวข้องหากหนึ่งแรกเท่ากับfalse
และดังนั้นรหัสพื้นฐานได้รับการปรับให้เหมาะสมเพื่อเลื่อนการประเมินของพารามิเตอร์ที่ 2 จนกว่ามันจะรู้ว่าสิ่งแรกคือ
&&
เป็นเพียงตัวดำเนินการไบนารีฟังก์ชัน สิ่งที่ "พิเศษ" เท่านั้นคือมันเป็นสัญกรณ์มัด (ซึ่งเป็นมาตรฐานสำหรับส่วนใหญ่ของผู้ประกอบการประเภทนี้ต่อไป) และการดำเนินการล่าช้าของตัวถูกดำเนินการที่สอง การดำเนินการล่าช้านั้นทำให้สามารถใช้เป็นสิ่งที่สามารถมองเห็นแนวคิดในฐานะif
คำสั่งในบริบทนี้แต่ไม่ได้นำออกไปจากความจริงที่ว่าการใช้งานที่ตั้งใจไว้เดิมนั้นอยู่ภายใต้เงื่อนไขของif
คำสั่งจริง การใช้ที่นี่จริงๆเป็น "แฮ็ค" มากกว่า
a && b || c = (a && b) || c
มันก็คือการสืบทอดของทั้งสองการดำเนินงาน ลำดับของการประเมินผลง่าย ๆ ที่นั่นไม่มีเรื่องลึกลับเลย or(and(a, b), c)
ถ้าคุณจะเขียนพวกเขาเช่นฟังก์ชั่นปกติของคุณมันก็จะมีลักษณะ ตรรกะนี้เหมือนกันภายในif
เงื่อนไขเช่นเดียวกับเมื่อป้อนมันโดยตรงในบรรทัดคำสั่งเพราะ&&
และ||
เป็นตัวดำเนินการพวกมันจะถูกดำเนินการสองตัวและพวกมันจะคืนค่าอีก
อัปเดต : ฉันได้เพิ่มเป็นสคริปต์เพื่อดักจับกับดักที่เป็นไปได้บางส่วน:
เพราะไม่มีใครพูดถึง "||" ฉันจะ
อัปเดต 2 : การใช้ถ้อยคำที่สำคัญอีกครั้งที่นี่
&& เหมือนกับคำว่า "จากนั้น" ของคำสั่ง "ถ้า" ซึ่งตอบสนองต่อ "จริง"
|| จะไม่ชอบ "อื่น" ของ "ถ้า" งบ ..
|| เป็นเหมือนคำสั่ง "แล้ว" ของคำสั่ง "ถ้า" ซึ่งตอบสนองต่อ "เท็จ"
specificaly เพิ่มเติม && ทดสอบ $? ส่งคืนค่าของคำสั่งที่ถูกเรียกใช้ล่าสุดก่อนหน้า นี้และผ่านการควบคุมไปยังคำสั่งหรือ sub-shell ทันทีหลังจาก && ... มันจะผ่านการควบคุมถ้า $ เท่านั้น? เป็นความจริง.
|| คล้ายกันและมักจะเห็นตามคำสั่ง && แต่จะทดสอบค่าส่งคืนที่ผิดพลาด ($?) จากคำสั่งที่ดำเนินการล่าสุดก่อนหน้า นี้ ... NB! , Nota Bene! โปรดทราบ! .... หากคำสั่ง predecing เป็นคำสั่ง && ซึ่งมีการเรียกคืนเป็นเท็จเมื่อคุณคาดหวังว่าคำสั่งนั้นเป็นจริงดังนั้น || จะตอบกลับไปเป็นเท็จดังนั้นการผสมทั้งสองในบรรทัดเดียวกันอาจมีความเสี่ยง
ประเด็นหลักที่ฉันพยายามทำคือเกี่ยวข้องกับความผิดพลาดที่ฉันทำ เช่น:
## [[เงื่อนไข]] && A || B
จะได้ไม่ประพฤติเช่น C / C ++ ternary สไตล์ เช่น:
// (เงื่อนไข)? A: B
ดูสคริปต์ด้านล่างเพื่อดูตัวอย่างผลลัพธ์ "ไม่คาดคิด" จาก "A"
การทดสอบพื้นฐานและ && และ | | คำสั่งทั้งหมดจะต้องอยู่ในบรรทัดเดียวกัน ...
เรียกใช้สคริปต์นี้เพื่อดูว่ามีสิ่งใดที่ผิดพลาดเมื่อใช้ && และ || ส่วนใหญ่ดำเนินการเมื่อเร็ว ๆ นี้คำสั่งอาจจะไม่เป็นอย่างใดอย่างหนึ่งที่คุณคาดหวัง ..
[[เงื่อนไข]] && echo Hello || echo Goodbye .... โดยทั่วไปแล้วจะปลอดภัยเนื่องจาก
echo ที่มีรูปแบบถูกต้องจะกลับมาเป็นจริง
แต่สิ่งที่เกี่ยวกับการเข้าถึงไฟล์ที่ไม่ออก?
#!/bin/bash
#
# "as expected" return codes" means: expected to behave like a normal AND / OR contition test
#
if [[ "$1" != "" ]] ; then exit $1; fi # recursive call to return an arbitary $? value (decimal)
echo
echo 'test 1: All return codes are "as expected"'
echo ======
((1==1)) && echo " ((1==1)) rc=$? ..&&.. condition is true" || echo " ((1==1)) rc=$? ..||.. condition is false"
$0 0 && echo " \$0 0 rc=$? ..&&.. condition is true" || echo " \$0 0 rc=$? ..||.. condition is false"
((1!=1)) && echo " ((1!=1)) rc=$? ..&&.. condition is true" || echo " ((1!=1)) rc=$? ..||.. condition is false"
$0 1 && echo " \$0 1 rc=$? ..&&.. condition is true" || echo " \$0 1 rc=$? ..||.. condition is false"
echo
echo 'test 2: Now throw in some "unexpected" errors into the first of the &&/|| pair'
echo ======
((1==1)) && (echo " ((1==1)) rc=$? ..&&.. condition is true"; $0 1) || echo " ((1==1)) rc=$? ..||.. condition is false"
$0 0 && (echo " \$0 0 rc=$? ..&&.. condition is true"; $0 2) || echo " \$0 0 rc=$? ..||.. condition is false"
((1!=1)) && (echo " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3) || echo " ((1!=1)) rc=$? ..||.. condition is false"
$0 1 && (echo " \$0 1 rc=$? ..&&.. condition is true"; $0 4) || echo " \$0 1 rc=$? ..||.. condition is false"
echo
echo 'test 3: Now swap the order of && and || statements, using "as expected" return codes'
echo ======
((1==1)) || echo " ((1==1)) rc=$? ..||.. condition is true" && echo " ((1==1)) rc=$? ..&&.. condition is false"
$0 0 || echo " \$0 0 rc=$? ..||.. condition is true" && echo " \$0 0 rc=$? ..&&.. condition is false"
((1!=1)) || echo " ((1!=1)) rc=$? ..||.. condition is true" && echo " ((1!=1)) rc=$? ..&&.. condition is false"
$0 1 || echo " \$0 1 rc=$? ..||.. condition is true" && echo " \$0 1 rc=$? ..&&.. condition is false"
echo
echo 'test 4: With the order of && and || statements still swapped, introduce "unexpected" errors into the first of the &&/|| pair'
echo ======
((1==1)) && (echo " ((1==1)) rc=$? ..&&.. condition is true"; $0 1) || echo " ((1==1)) rc=$? ..||.. condition is false"
$0 0 && (echo " \$0 0 rc=$? ..&&.. condition is true"; $0 2) || echo " \$0 0 rc=$? ..||.. condition is false"
((1!=1)) && (echo " ((1!=1)) rc=$? ..&&.. condition is true"; $0 3) || echo " ((1!=1)) rc=$? ..||.. condition is false"
$0 1 && (echo " \$0 1 rc=$? ..&&.. condition is true"; $0 4) || echo " \$0 1 rc=$? ..||.. condition is false"
exit
ลอง
false && echo "hello"
และ
เท็จ echo "hello"
ดูความแตกต่าง
คำสั่ง (ฟังก์ชั่นในกรณีของสคริปต์) หลังจาก&&
ถูกดำเนินการขึ้นอยู่กับ RETVAL ของคำสั่งแรก (ฟังก์ชั่นในกรณีของสคริปต์) มันบังคับให้คำสั่งแรกคืนค่า 0 ถ้าสำเร็จ เราสามารถตรวจสอบค่าที่ส่งคืนเพื่อดำเนินการคำสั่งเพิ่มเติม