ทุบตีคำเตือนที่ไม่มีข้อโต้แย้งและการตัดสินคดี


110

ฉันกำลังเรียนรู้การทุบตี

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

ฉันต้องการทราบคำแนะนำสำหรับคู่มือออนไลน์ที่ดีที่สุดสำหรับผู้เริ่มต้นในการทุบตี

ขอบคุณ

คำตอบ:


176
if [[ $# -eq 0 ]] ; then
    echo 'some message'
    exit 0
fi

case "$1" in
    1) echo 'you gave 1' ;;
    *) echo 'you gave something else' ;;
esac

ขั้นสูงทุบตี Scripting คู่มือสวยดี แม้จะมีชื่อ แต่ก็ปฏิบัติตามพื้นฐาน


RE: "exit 0". ฉันไม่รู้ว่าการออกจากสคริปต์เป็นสิ่งที่เขาคิดหรือไม่ แต่ใช่นั่นเป็นแนวทางที่ยอดเยี่ยม
Trampas Kirk

ฉันตีความ "และ" เป็น "อย่างอื่น" โดยสมมติว่าข้อความนั้นน่าจะเป็นข้อความช่วยเหลือ แต่ฉันแน่ใจว่าเวอร์เนอร์สามารถรู้ได้ว่าเส้นนั้นทำอะไรและเขาต้องการหรือไม่ :)
โทมัส

ขอบคุณแน่นอน! และประการสุดท้ายฉันจะปิดข้อความแสดงข้อผิดพลาด ib สคริปต์ได้อย่างไรจึงจะไม่แสดงในเชลล์
เปิดทาง

คุณหมายถึงข้อผิดพลาดที่มาจากโปรแกรมใดโปรแกรมหนึ่งที่คุณกำลังโทรหาใช่หรือไม่? คุณสามารถใส่> /dev/nullและ / หรือ2> /dev/nullหลังจากนั้นเพื่อส่งเอาต์พุตมาตรฐานและ / หรือสตรีมข้อผิดพลาดมาตรฐานไปยังการให้อภัย
Thomas

4
หากคุณพิจารณาข้อโต้แย้งที่ขาดหายไปเป็นสิ่งที่ไม่ดี (เช่นสคริปต์แล้วไม่สามารถดำเนินการได้สำเร็จ) ให้ส่งคืนสิ่งที่แตกต่างจาก 0 ( exit 1) มีข้อกำหนดเพิ่มเติมเกี่ยวกับรหัสการส่งคืน / ออกซึ่งคุณสามารถค้นหาทางออนไลน์ได้อย่างรวดเร็ว แต่ประเด็นสำคัญคือไม่ควรเป็น 0 ซึ่งบ่งบอกถึงความสำเร็จ
เฟลิกซ์

25

หากสนใจเฉพาะการประกันตัวหากไม่มีข้อโต้แย้งใด ๆ การทดแทนพารามิเตอร์นั้นยอดเยี่ยม:

#!/bin/bash
# usage-message.sh

: ${1?"Usage: $0 ARGUMENT"}
#  Script exits here if command-line parameter absent,
#+ with following error message.
#    usage-message.sh: 1: Usage: usage-message.sh ARGUMENT

11

ตัวอย่าง

 if [ -z "$*" ]; then echo "No args"; fi

ผลลัพธ์

No args

รายละเอียด

-zเป็นตัวดำเนินการยูนารีสำหรับความยาวของสตริงเป็นศูนย์ $*คือข้อโต้แย้งทั้งหมด คำพูดมีไว้เพื่อความปลอดภัยและห่อหุ้มหลายอาร์กิวเมนต์หากมี

ใช้man bashและค้นหา ( / key) สำหรับ "unary" สำหรับตัวดำเนินการเพิ่มเติมเช่นนี้


7
ปัญหา (เล็กน้อย) เกี่ยวกับสิ่งนี้คือมันไม่ได้แยกความแตกต่างระหว่างการไม่มีอาร์กิวเมนต์และการส่งสตริงว่างเป็นอาร์กิวเมนต์ นั่นอาจมีความสำคัญในบางบริบท การใช้ [$ # -eq 0] จะสามารถจัดการทั้งสองกรณีได้อย่างเหมาะสม
Idelic

1
อ่ารายละเอียดปลีกย่อยของการเขียนโปรแกรม (ba) sh ... นี่คือเหตุผลที่ฉันเกลียดมัน
Thomas

1
คิดว่า-zเป็นmizzing
Ray Foss

4

เก่า แต่ฉันมีเหตุผลที่จะแก้ไขคำตอบใหม่ตอนนี้เนื่องจากความสับสนก่อนหน้านี้:

if [[ $1 == "" ]] #Where "$1" is the positional argument you want to validate 

 then
 echo "something"
 exit 0

fi

สิ่งนี้จะสะท้อน "Something" หากไม่มีอาร์กิวเมนต์ตำแหน่ง $ 1 อย่างไรก็ตามไม่สามารถตรวจสอบได้ว่า $ 1 มีข้อมูลเฉพาะ


$#คือจำนวนเต็มของจำนวนอาร์กิวเมนต์อย่างชัดเจน มันจะเป็น "0" และคุณจะสะท้อน "บางสิ่ง" แม้ว่าจะไม่มีข้อโต้แย้งหรือจะเป็นจำนวนบวกและคุณจะสะท้อน "บางสิ่ง" อย่างถูกต้อง แต่การตรวจสอบตัวเองจะไม่เคยทำอะไรโดยไม่คำนึงถึงการป้อนข้อมูลหรือขาดของการป้อนข้อมูลที่คุณใช้ - มันจะเสมอรายงานว่า$#มีค่า ดังนั้นนี่จึงผิดอย่างสิ้นเชิงและจะไม่ได้ผลตามที่กล่าวอ้าง
eschwartz

คุณคิดบวกอย่างสมบูรณ์หรือไม่? ฉันมีสคริปต์หลายตัวที่ทำงานได้ตามที่ตั้งใจไว้โดยใช้รูปแบบนี้ เมื่ออ่านคำตอบของคุณฉันได้ทำการทดสอบซ้ำทั้งสำหรับการแข่งขันและการขาด $ # จะไม่มีค่าหากไม่ได้ระบุไว้หากไม่มีอาร์กิวเมนต์ตำแหน่งที่ตรงกับสิ่งที่เคย # ในสถานการณ์ของคุณ มันไม่มีเหตุผลว่าทำไม bash จึงถือว่าค่าในอาร์กิวเมนต์ตำแหน่งที่ไม่มีอยู่
Ryan Smith

ลองecho $#เป็นเนื้อหาของสคริปต์ /tmp/test.sh จากนั้นเรียกใช้ภายใต้ / bin / bash เช่นเดียวกับ / bin / sh (หรือ / bin / dash และการใช้งานเชลล์อื่น ๆ ที่คุณมีอยู่/tmp/test.shจะสะท้อน "0" ถึง คอนโซลตามประสงค์/bin/dash /tmp/test.shในทางกลับกัน/tmp/test.sh fooจะสะท้อน "1" และ/tmp/test.sh first secondจะสะท้อน "2"
eschwartz

ตามman bashในส่วน "พารามิเตอร์พิเศษ" "เชลล์ปฏิบัติต่อพารามิเตอร์หลายตัวเป็นพิเศษพารามิเตอร์เหล่านี้สามารถอ้างอิงได้เท่านั้นไม่อนุญาตให้กำหนดให้กับพารามิเตอร์เหล่านี้" และ "# ขยายเป็นจำนวนพารามิเตอร์ตำแหน่งเป็นทศนิยม" POSIX ได้รับคำสั่งเช่นเดียวกันตามที่อธิบายไว้ในpubs.opengroup.org/onlinepubs/9699919799/utilities/…
eschwartz

ขออภัยดูเหมือนว่าจะมีการสื่อสารผิดพลาด! ฉันหมายถึง # เป็นตัวยึดตำแหน่งสำหรับอาร์กิวเมนต์ตำแหน่งเฉพาะ (เช่น $ 2 ถ้าคุณหมายถึงอาร์กิวเมนต์ที่สอง) ไม่ใช่ $ # ตามตัวอักษร หลังจากตรวจสอบข้างต้นของคุณแล้วคุณว่าถูกต้องแล้ว $ # ตามตัวอักษรจะแก้ไขจำนวนอาร์กิวเมนต์เสมอ ขออภัยในความสับสน
Ryan Smith
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.