ถ้าเงื่อนไขในหลายบรรทัดในเปลือกทุบตี


19

ฉันมีฟังก์ชั่นเปลือกทุบตีที่จะโต้แย้งและทำอะไรกับมันถ้าจำเป็น

do_somthing() {
  if [need to do something on $1]
  then
    do it
    return 0
  else
    return 1
  fi
}

ฉันต้องการเรียกวิธีนี้โดยมีข้อโต้แย้งหลายอย่างและตรวจสอบว่าอย่างน้อยหนึ่งข้อประสบความสำเร็จหรือไม่

ฉันลองทำสิ่งที่ชอบ:

if [ do_something "arg1" ||
     do_something "arg2" ||
     do_something "arg3" ]
then
  echo "OK"
else
  echo "NOT OK"
fi

สิ่งที่จะเป็นไวยากรณ์ที่ถูกต้องสำหรับที่?
แก้ไข
ด้วย - ฉันต้องการแน่ใจว่าแม้ว่าเงื่อนไขแรกจะเป็นจริงเงื่อนไขอื่น ๆ ทั้งหมดจะยังคงได้รับการประเมิน

ขอบคุณ


ฉันอัพเดตคำตอบแล้ว
tectux

ขอบคุณคุณช่วยยกตัวอย่างได้ไหม
Itay

1
ฉันได้เพิ่มตัวอย่างรหัสลงในคำตอบของฉัน
tectux

คำตอบ:


7

รันคำสั่งก่อนจากนั้นตรวจสอบว่าอย่างน้อยหนึ่งคำสั่งสำเร็จ

#!/bin/bash

success=0
do_something arg1 && success=1
do_something arg2 && success=1
do_something arg3 && success=1

if ((success)); then
    printf 'Success! At least one of the three commands succeeded\n'
fi

3
นี้จะทำให้เกิดความสับสนผมจะดีใจถ้าคุณสามารถให้คำอธิบายเกี่ยวกับวิธีงบเงื่อนไขการทำงานในทุบตี ... , do_something ผลตอบแทน 0 ความสำเร็จ แต่แล้วเราอัปเดตความสำเร็จ 1 ... , ประเมินสิ่งที่แตกต่างif ((success)) if successฉันกำลังสับสน :)
Itay

2
@Itay ((...))เป็นคำสั่งทางคณิตศาสตร์ ถ้าผลลัพธ์ด้านในเป็นศูนย์ไม่ใช่มันจะส่งกลับค่าจริง (0) หากผลลัพธ์ภายในเป็น 0 จะส่งคืนค่าเท็จ (1) "สำเร็จ" ถือเป็นตัวแปรซึ่งคาดว่าจะมีตัวเลข ดูmywiki.wooledge.org/ArithmeticExpression
geirha

ขอบคุณฉันเดาว่าส่วนที่ทำให้ฉันสับสนคือ 0 นั้นเป็นจริงและ 1 เป็นเท็จโดยปกติมันจะตรงกันข้าม :)
Itay

2
@ มันอาจจะสับสนในตอนแรก Bash นั้นแตกต่างจากภาษาที่ใช้โดยทั่วไปซึ่งมันคือ "command based"; ไม่เรียกใช้ฟังก์ชันไม่มีคลาสและเมธอดเรียกใช้คำสั่งและทดสอบสถานะการออกคำสั่ง และมันง่ายกว่ามากในการรันคำสั่งใน bash มากกว่าภาษาเช่น C, python, java, perl และอื่น ๆ คำสั่งออกด้วย 0 เพื่อส่งสัญญาณความสำเร็จและ 1-255 สำหรับความล้มเหลวประเภทต่างๆ (คำสั่งที่สามารถทั่วไปเท่านั้นประสบความสำเร็จในทางหนึ่ง แต่ล้มเหลวด้วยเหตุผลที่แตกต่างกัน)
geirha

2
วิธีนี้มีประโยชน์ที่คุณสามารถแสดงความคิดเห็นในบรรทัดที่คุณไม่ต้องการปิดการใช้งานชั่วคราว
Josiah Yoder

31

ใช้แบ็กสแลช

if [ $(do_something "arg1") ] || \
   [ $(do_something "arg2") ] || \
   [ $(do_something "arg3") ]
then
  echo "OK"
else
  echo "NOT OK"
fi

แก้ไข

นอกจากนี้ - ฉันต้องการตรวจสอบให้แน่ใจว่าแม้ว่าเงื่อนไขแรกจะเป็นจริงเงื่อนไขอื่น ๆ ทั้งหมดจะยังคงได้รับการประเมิน

นั่นเป็นไปไม่ได้ในหนึ่งคำสั่งถ้า แต่คุณสามารถใช้ for for loop ที่วนซ้ำอาร์กิวเมนต์และประเมินแยกต่างหาก สิ่งที่ต้องการ:

do_something() {
  for x in "$@"
  do
    if [need to do something on $x]
    then
      do it
    else
      echo "no action required on $x"
    fi
  done
}

ขอบคุณลองมัน - ฉันได้รับข้อผิดพลาด[: do_something: unary operator expected
Itay

คุณทำการประเมินแต่ละครั้งระหว่างวงเล็บของตัวเองหรือไม่? ดังนั้นแทนที่จะ[ expr1 ] || [ expr2 ] [ expr1 || expr2 ]
tectux

ใช่ฉันได้: ( ...
Itay

ฉันเดาว่าdo_something "arg1"มันถูกตีความว่าเป็นสองข้อโต้แย้งในขณะที่การแสดงออกควรเป็นเอกภาพ มีวิธีใดในการdo_something "arg1"ประเมินเป็นอาร์กิวเมนต์เดียว?
Itay

1
คุณถูก. วิธีนี้ใช้ได้เช่นกัน: if [ $(do_something "arg1") ].
tectux

5

ไวยากรณ์ที่ถูกต้องคือ:

if  do_something "arg1" || \
    do_something "arg2" || \
    do_something "arg3"
then
  echo "OK"
else
  echo "NOT OK"
fi

\ ถูกใช้เพื่อบอกเชลล์คำสั่งดำเนินการต่อในบรรทัดถัดไป

แก้ไข : ฉันคิดว่านี่ควรทำสิ่งที่คุณต้องการ:

#!/bin/bash

do_something() {
  if [need to do something on $1]
  then
    do it
    echo "OK"
  else
    echo "NOT OK"
  fi
}

do_something "arg1"
do_something "arg2"
do_something "arg3"

ขอขอบคุณผลลัพธ์ที่มีข้อผิดพลาด:[: too many arguments
Itay

@ คำตอบอัพเดทแล้ว
Eric Carvalho

การอัปเดตคำถาม - นี่ยังไม่เป็นคำตอบสุดท้าย :(
11'13

-1

ฉันชอบ:

if {
    do_something "arg1" ||
    do_something "arg2" ||
    do_something "arg3"
}; then
    echo "OK"
else
    echo "NOT OK"
fi

สคริปต์ของคุณจะไม่ทำงานเลย: หลังจากพารามิเตอร์ทดสอบครั้งที่ 1 มันจะสร้าง\nตัวละครดังนั้นifคำสั่งของคุณจะสร้างข้อผิดพลาดบางอย่างและdo_somethingไม่ใช่ชื่อคำสั่งข้อผิดพลาดเพิ่มเติม
damadam

สำหรับฉันมันทำงานใน zsh และทุบตีถ้าdo_somethingเป็นหน้าที่แน่นอน do_somethingจะต้องมีฟังก์ชั่นหรือคำสั่งมันควรจะเป็นอะไร? นอกจากนี้ฉันไม่เห็นว่ามันจะสร้าง\nตัวละครยกเว้นหลังจากสะท้อนผลและสิ่งนี้คาดว่า ...
Toxiro
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.