ฉันจะทำอะไรแบบนี้ในทุบตีได้อย่างไร
if "`command` returns any error";
then
echo "Returned an error"
else
echo "Proceed..."
fi
ฉันจะทำอะไรแบบนี้ในทุบตีได้อย่างไร
if "`command` returns any error";
then
echo "Returned an error"
else
echo "Proceed..."
fi
คำตอบ:
วิธีทำบางอย่างตามเงื่อนไขหากคำสั่งสำเร็จหรือล้มเหลว
นั่นคือสิ่งที่if
แถลงการณ์ของ bash ทำ:
if command ; then
echo "Command succeeded"
else
echo "Command failed"
fi
การเพิ่มข้อมูลจากความคิดเห็น: คุณไม่จำเป็นต้องใช้ไวยากรณ์[
... ]
ในกรณีนี้ ตัวเองเป็นคำสั่งมากเกือบเทียบเท่ากับ[
test
มันอาจเป็นคำสั่งที่ใช้บ่อยที่สุดในการใช้if
ซึ่งสามารถนำไปสู่การสันนิษฐานว่ามันเป็นส่วนหนึ่งของไวยากรณ์ของเชลล์ แต่ถ้าคุณต้องการทดสอบว่าคำสั่งสำเร็จหรือไม่ให้ใช้คำสั่งโดยตรงด้วยif
ดังที่แสดงด้านบน
แก้ไข: ยกคำถามที่ด้านบนเพื่อความชัดเจน (คำตอบนี้ไม่ปรากฏใกล้ด้านบนของหน้า)
then
สายแยก
if ! command ; then ... ; fi
ผมคิดว่าคุณหมายถึง [
เป็นคำสั่งและมันไม่จำเป็นในกรณีนี้
if [ ! command ]
ไม่ได้ดำเนินการcommand
; มันจะถือว่าcommand
เป็นสตริงและถือว่าเป็นจริงเพราะมันมีความยาวไม่เป็นศูนย์ [
เป็นคำพ้องความหมายสำหรับtest
คำสั่ง
สำหรับสิ่งเล็ก ๆ ที่คุณต้องการให้เกิดขึ้นหากคำสั่ง shell ใช้งานได้คุณสามารถใช้&&
โครงสร้างได้:
rm -rf somedir && trace_output "Removed the directory"
ในทำนองเดียวกันสำหรับสิ่งเล็ก ๆ ที่คุณต้องการให้เกิดขึ้นเมื่อคำสั่งเชลล์ล้มเหลวคุณสามารถใช้||
:
rm -rf somedir || exit_on_error "Failed to remove the directory"
หรือทั้งคู่
rm -rf somedir && trace_output "Removed the directory" || exit_on_error "Failed to remove the directory"
อาจไม่ฉลาดนักที่จะทำสิ่งเหล่านี้มาก แต่บางครั้งพวกเขาก็สามารถทำให้การควบคุมมีความชัดเจนมากขึ้น
ตรวจสอบค่า$?
ซึ่งประกอบด้วยผลลัพธ์ของการดำเนินการคำสั่ง / ฟังก์ชันล่าสุด:
#!/bin/bash
echo "this will work"
RESULT=$?
if [ $RESULT -eq 0 ]; then
echo success
else
echo failed
fi
if [ $RESULT == 0 ]; then
echo success 2
else
echo failed 2
fi
if
สำนวนของ Bash ฉันชอบคำตอบของ Keith Thompson
if
การทำ เงื่อนไขการควบคุมการไหลใน Bash ทั้งหมดตรวจสอบ$?
เบื้องหลัง นั่นคือสิ่งที่พวกเขาทำ การตรวจสอบค่าของมันอย่างชัดเจนนั้นไม่จำเป็นในกรณีส่วนใหญ่และมักจะเป็นปฏิปักษ์มือใหม่
if ! cmd
ก็โอเค มิฉะนั้นข้อตกลงร่วมกันคือการใช้else
ข้อ คุณไม่สามารถว่างเปล่าได้then
แต่บางครั้งคุณก็เห็นthen : nothing; else
ว่า:
ไม่มีตัวละครสำคัญ true
จะทำงานที่นั่นเช่นกัน
สิ่งนี้ใช้ได้กับฉัน:
command && echo "OK" || echo "NOK"
หากcommand
ประสบความสำเร็จก็echo "OK"
จะถูกดำเนินการและเนื่องจากมันประสบความสำเร็จการดำเนินการหยุดที่นั่น มิฉะนั้น&&
จะถูกข้ามและecho "NOK"
ถูกดำเนินการ
command && echo "OK" || c=$?; echo "NOK"; $(exit $c)
command && echo "OK" || (c=$?; echo "NOK"; (exit $c))
เหรอ?
echo "OK"
ส่วนใดส่วนหนึ่งอาจล้มเหลวตัวเองก็จะดีขึ้น:command && (echo "OK"; exit 0) || (c=$?; echo "NOK"; (exit $c))
ควรสังเกตว่าif...then...fi
และ&&
/ ||
ประเภทของวิธีการจัดการกับสถานะทางออกที่ส่งคืนโดยคำสั่งที่เราต้องการทดสอบ (0 เมื่อสำเร็จ); อย่างไรก็ตามคำสั่งบางคำสั่งจะไม่ส่งคืนสถานะการออกที่ไม่ใช่ศูนย์หากคำสั่งล้มเหลวหรือไม่สามารถจัดการกับอินพุตได้ ซึ่งหมายความว่าปกติif
และ&&
/ ||
แนวทางจะไม่ทำงานสำหรับคำสั่งเฉพาะเหล่านั้น
ตัวอย่างเช่นบน Linux GNU file
ยังคงออกด้วย 0 หากได้รับไฟล์ที่ไม่มีอยู่เป็นอาร์กิวเมนต์และfind
ไม่สามารถระบุตำแหน่งผู้ใช้ไฟล์ที่ระบุ
$ find . -name "not_existing_file"
$ echo $?
0
$ file ./not_existing_file
./not_existing_file: cannot open `./not_existing_file' (No such file or directory)
$ echo $?
0
ในกรณีเช่นนี้วิธีที่เป็นไปได้วิธีหนึ่งที่เราสามารถจัดการกับสถานการณ์ได้คือการอ่านstderr
/ stdin
ข้อความเช่นที่ส่งคืนโดยfile
คำสั่งหรือแยกวิเคราะห์เอาต์พุตของคำสั่งเช่นfind
นี้ สำหรับวัตถุประสงค์นั้นcase
สามารถใช้ข้อความสั่งได้
$ file ./doesntexist | while IFS= read -r output; do
> case "$output" in
> *"No such file or directory"*) printf "%s\n" "This will show up if failed";;
> *) printf "%s\n" "This will show up if succeeded" ;;
> esac
> done
This will show up if failed
$ find . -name "doesn'texist" | if ! read IFS= out; then echo "File not found"; fi
File not found
ข้อผิดพลาดมากที่สุดที่ฉันสามารถทำได้คือ:
RR=$?
ตอนนี้ไม่เพียง แต่สถานการณ์นี้ แต่คนอื่น ๆ ที่คุณอาจเผชิญให้พิจารณา:
$ AA=1 ; if (( "10#0${AA}" == 1 )) ; then echo yes ; else echo no ; fi
ตอบ: ใช่
$ AA=1 ; if (( "10#0${AA}" != 1 )) ; then echo yes ; else echo no ; fi
คำตอบ: ไม่
$ AA=1 ; if (( "10#0${BB}" == 1 )) ; then echo yes ; else echo no ; fi
คำตอบ: ไม่
$ AA=1 ; if (( "10#0${BB}" != 1 )) ; then echo yes ; else echo no ; fi
ตอบ: ใช่
$ AA=1 ; if (( "10#0${BB}" == 0 )) ; then echo yes ; else echo no ; fi
ตอบ: ใช่
เพื่อป้องกันข้อผิดพลาดทุกชนิด
คุณอาจรับรู้ถึงไวยากรณ์ทั้งหมด แต่นี่เป็นเคล็ดลับ:
"blank"
nothing
${variable}
สัญกรณ์ใหม่ที่ทันสมัยสำหรับตัวแปรคือbase-8
แต่รอการเพิ่มศูนย์ทำให้จำนวนกลายเป็น คุณจะได้รับข้อผิดพลาดเช่น:
value too great for base (error token is "08")
7
สำหรับตัวเลขดังกล่าวข้างต้น นั่นคือเมื่อ10#
เข้ามาเล่น:10#
base-10
กองกำลังจำนวนที่จะคุณสามารถทำได้:
if ($( ping 4.4.4.4 -c1 > /dev/null )) ; then
echo "ping response succsess!!!"
fi
ping
ถูกจับในมุมมองของการเรียกใช้เป็นคำสั่ง แต่เนื่องจากผลลัพธ์ถูกเปลี่ยนเส้นทางไปยัง / dev / null ที่จะเป็นสตริงว่างเสมอ ดังนั้นคุณจะไม่ทำงานอะไรใน subshell ซึ่งหมายความว่าสถานะการออกก่อนหน้า (ของ subshell การแทนที่คำสั่งที่เป็น ping) จะถูกเก็บไว้ เห็นได้ชัดว่าวิธีที่ถูกต้องอยู่if ping ...; then
ที่นี่
ตามที่ระบุไว้ที่อื่นในหัวข้อนี้คำถามเดิมโดยทั่วไปตอบตัวเอง นี่คือภาพประกอบที่แสดงว่าif
เงื่อนไขอาจซ้อนกัน
ตัวอย่างนี้ใช้if
เพื่อตรวจสอบว่ามีไฟล์อยู่หรือไม่และเป็นไฟล์ปกติหรือไม่ หากเงื่อนไขเหล่านั้นเป็นจริงให้ตรวจสอบว่ามีขนาดใหญ่กว่า 0 หรือไม่
#!/bin/bash
echo "Which error log are you checking today? "
read answer
if [ -f /opt/logs/$answer*.errors ]
then
if [ -s /opt/logs/$answer*.errors ]
then
echo "Content is present in the $answer error log file."
else
echo "No errors are present in the $answer error log file."
fi
else
echo "$answer does not have an error log at this time."
fi
#!/bin/bash
if command-1 ; then
echo "command-1 succeeded and now running from this block command-2"
command-2
else
echo "command-1 failed and now running from this block command-3"
command-3
fi
สิ่งนี้สามารถทำได้ง่ายๆด้วยวิธีนี้เนื่องจาก$?
ให้สถานะของคำสั่งสุดท้ายที่ถูกเรียกใช้งาน
ดังนั้นมันอาจจะเป็น
#!/bin/sh
... some command ...
if [ $? == 0 ] ; then
echo '<the output message you want to display>'
else
echo '<failure message>'
fi