ในสคริปต์ทุบตีใช้เงื่อนไข“ หรือ” ในคำสั่ง“ ถ้า”


128

คำถามนี้เป็นผลสืบเนื่องของแปลกไปของฉันคำถามก่อนหน้านี้ ผู้ใช้ในเว็บไซต์นี้ช่วยฉันในการกำหนดวิธีการเขียน bash forloop ที่วนซ้ำค่าสตริง ตัวอย่างเช่นสมมติว่าการควบคุมวงตัวแปรfnameiterates "a.txt" "b.txt" "c.txt"มากกว่าสตริง ฉันต้องการที่จะecho"ใช่!" เมื่อfnameมีค่า"a.txt"หรือ"c.txt"และecho"ไม่!" มิฉะนั้น. ฉันได้ลอง bash shell script แล้ว:

#!/bin/bash

for fname in "a.txt" "b.txt" "c.txt"
do
 echo $fname
 if [ "$fname" = "a.txt" ] | [ "$fname" = "c.txt" ]; then
 echo "yes!"
else
 echo "no!"
fi
done

ฉันได้รับผลลัพธ์:

a.txt

ไม่!

b.txt

ไม่!

c.txt

ใช่!

ทำไมifคำสั่งเห็นได้ชัดว่าผลผลิตจริงเมื่อfnameมีค่า"a.txt"? ฉันใช้|ไม่ถูกต้องหรือไม่


3
ในทุบตี 'หรือ' โอเปอเรเตอร์คือ '||' (สไตล์ C)
Marius Cotofana

3
คุณยังสามารถใช้-oภายในเดียวกัน[ ]ได้
Thor

6
@Thor ฉันชอบ||และแยก[ ]กว่า-oสำหรับการพกพาเพียงเพราะ[ไม่รับประกันว่าจะสนับสนุนมากกว่า 4 ข้อโต้แย้ง แน่นอนถ้าภาษาเป้าหมายคือbashไม่มีใครควรจะใช้[นะเพราะbash's [[จะดีกว่าในหลาย ๆ
jw013

2
@ jw013 ขอบคุณ นี่หมายความว่าฉันควรจะใช้if [[ "$fname" = "a.txt" ]] || [[ "$fname" = "c.txt" ]]มากกว่าif [ "$fname" = "a.txt" ] || [ "$fname" = "c.txt" ]หรือไม่
แอนดรู

5
@ แอนดรูว์นั้นถูกต้องถ้าคุณเป็นคนประกาศให้เป็นbashเช่นเดียวกับที่คุณทำอยู่แล้ว ข้อดีอย่างหนึ่ง[[ก็คือมันไม่ได้แยกคำ (กรณีพิเศษ) จึง[[ $unquoted_var = string ]]ปลอดภัย
jw013

คำตอบ:


226

หากคุณต้องการพูดให้ORใช้ double pipe ( ||)

if [ "$fname" = "a.txt" ] || [ "$fname" = "c.txt" ]

(การใช้รหัส OP ดั้งเดิม|นั้นเพียงแค่ส่งออกท่อทางด้านซ้ายไปทางด้านขวาในลักษณะเดียวกับการใช้งานท่อธรรมดาทั่วไป)


4
นอกจากนี้||ไม่ได้ทำตรรกะมาตรฐาน "หรือ" - มันลัดวงจรและคำสั่งที่สองจะทำงานเฉพาะในกรณีที่ครั้งแรกล้มเหลว
holdenweb

13
@ โฮลเดนเว็บฉันค่อนข้างมั่นใจว่าภาษาที่ทันสมัยที่สุดส่วนใหญ่ทำงานในลักษณะเดียวกัน ไม่จำเป็นต้องใช้รอบ CPU ในการประเมินเงื่อนไขที่สองORหากเงื่อนไขแรกประเมินเป็นจริง
bahamat

1
ฉันคิดว่าคนชอบทุบตี==แต่หลังจากได้เห็นคำตอบนี้ฉันตัดสินใจที่จะค้นหามัน เห็นได้ชัดว่า "สามารถใช้งานได้ แต่ไม่ได้มาตรฐาน" ฉันคิดว่าฉันจะให้สิ่งนี้กับคนอื่น ๆ ถ้าคุณอยากรู้: stackoverflow.com/a/2237103
harperville

นี่คือสิ่งที่testหน้าคนแนะนำด้วย
cdosborn

2
คุณยังสามารถใช้การทดสอบวงเล็บคู่ - if [[ "$fname" = "a.txt" ]] || [[ "$fname" = "c.txt" ]](ถ้าคุณต้องการหรือจำเป็นต้องมีฟังก์ชั่นพิเศษที่เกี่ยวข้อง[[ ]])
HankCa
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.