ฉันจะตรวจสอบได้อย่างไรว่า-h
แอตทริบิวต์ถูกส่งไปยังเชลล์สคริปต์หรือไม่ ฉันต้องการแสดงข้อความช่วยเหลือเมื่อผู้ใช้โทรmyscript.sh -h
มา
ฉันจะตรวจสอบได้อย่างไรว่า-h
แอตทริบิวต์ถูกส่งไปยังเชลล์สคริปต์หรือไม่ ฉันต้องการแสดงข้อความช่วยเหลือเมื่อผู้ใช้โทรmyscript.sh -h
มา
คำตอบ:
นี่คือตัวอย่างสำหรับ bash:
usage="$(basename "$0") [-h] [-s n] -- program to calculate the answer to life, the universe and everything
where:
-h show this help text
-s set the seed value (default: 42)"
seed=42
while getopts ':hs:' option; do
case "$option" in
h) echo "$usage"
exit
;;
s) seed=$OPTARG
;;
:) printf "missing argument for -%s\n" "$OPTARG" >&2
echo "$usage" >&2
exit 1
;;
\?) printf "illegal option: -%s\n" "$OPTARG" >&2
echo "$usage" >&2
exit 1
;;
esac
done
shift $((OPTIND - 1))
ในการใช้สิ่งนี้ภายในฟังก์ชัน:
"$FUNCNAME"
แทน$(basename "$0")
local OPTIND OPTARG
ก่อนโทรgetopts
basename
ด้วยเครื่องหมายขีดนำ
"$FUNCNAME"
"$0"
นอกจากนี้ยังเพิ่มlocal OPTIND OPTARG
FUNCNAME
โรงงาน ฉันมีฟังก์ชั่นทั้งหมดของฉันอยู่ในไฟล์เดียวดังนั้นนี่จึงเหมาะอย่างยิ่งสำหรับการขยายให้เป็นสิ่งที่มีประโยชน์สำหรับผู้อื่น
"$usage"
ทุกที่ที่คุณใช้
shift $((OPTIND - 1))
เพื่ออะไร?
อาร์กิวเมนต์แรกของเชลล์สคริปต์พร้อมใช้งานเป็นตัวแปร$1
ดังนั้นการนำไปใช้งานที่ง่ายที่สุดคือ
if [ "$1" == "-h" ]; then
echo "Usage: `basename $0` [somestuff]"
exit 0
fi
แต่สิ่งที่ anubhava พูด
[
เป็นเวอร์ชันที่รองรับ POSIX
function
:คุณควรแทนที่exit 0
ด้วยreturn
ถ้าคุณไม่ต้องการยุติเชลล์ของคุณหลังจากเรียกใช้ฟังก์ชันของคุณ (เคยทำมาแล้ว😂)
นี่คือส่วนหนึ่งที่ฉันใช้เพื่อเริ่มเซิร์ฟเวอร์ VNC
#!/bin/bash
start() {
echo "Starting vnc server with $resolution on Display $display"
#your execute command here mine is below
#vncserver :$display -geometry $resolution
}
stop() {
echo "Killing vncserver on display $display"
#vncserver -kill :$display
}
#########################
# The command line help #
#########################
display_help() {
echo "Usage: $0 [option...] {start|stop|restart}" >&2
echo
echo " -r, --resolution run with the given resolution WxH"
echo " -d, --display Set on which display to host on "
echo
# echo some stuff here for the -a or --add-options
exit 1
}
################################
# Check if parameters options #
# are given on the commandline #
################################
while :
do
case "$1" in
-r | --resolution)
if [ $# -ne 0 ]; then
resolution="$2" # You may want to check validity of $2
fi
shift 2
;;
-h | --help)
display_help # Call your function
exit 0
;;
-d | --display)
display="$2"
shift 2
;;
-a | --add-options)
# do something here call function
# and write it in your help function display_help()
shift 2
;;
--) # End of all options
shift
break
;;
-*)
echo "Error: Unknown option: $1" >&2
## or call function display_help
exit 1
;;
*) # No more options
break
;;
esac
done
######################
# Check if parameter #
# is set too execute #
######################
case "$1" in
start)
start # calling function start()
;;
stop)
stop # calling function stop()
;;
restart)
stop # calling function stop()
start # calling function start()
;;
*)
# echo "Usage: $0 {start|stop|restart}" >&2
display_help
exit 1
;;
esac
มันแปลกนิดหน่อยที่ฉันวาง start stop start ไว้แยกกัน แต่มันควรจะใช้งานได้
if
หากคุณมีเพียงตัวเลือกเดียวในการตรวจสอบและจะเป็นตัวเลือกแรกเสมอ ( $1
) วิธีแก้ปัญหาที่ง่ายที่สุดคือการif
ทดสอบ ( [
) ตัวอย่างเช่น:
if [ "$1" == "-h" ] ; then
echo "Usage: `basename $0` [-h]"
exit 0
fi
โปรดทราบว่าสำหรับความเข้ากันได้ของ posix =
จะใช้งานได้เช่นเดียวกับ==
.
$1
?เหตุผลที่$1
จำเป็นต้องใส่เครื่องหมายคำพูดก็คือถ้าไม่มี$1
เชลล์จะพยายามรันif [ == "-h" ]
และล้มเหลวเนื่องจาก==
ได้รับอาร์กิวเมนต์เดียวเมื่อคาดหวังสองข้อเท่านั้น:
$ [ == "-h" ]
bash: [: ==: unary operator expected
getopt
หรือgetopts
ในฐานะที่เป็นปัญหา จาก คนอื่น ๆgetopts
ถ้าคุณมีมากกว่าเป็นตัวเลือกที่ง่ายเดียวหรือต้องการตัวเลือกของคุณเพื่อยอมรับข้อโต้แย้งแล้วคุณแน่นอนควรไปสำหรับความซับซ้อนเป็นพิเศษในการใช้
การอ้างอิงอย่างรวดเร็วผมชอบ60 getopts สองกวดวิชา †
คุณอาจต้องการพิจารณาgetopt
โปรแกรมแทนเชลล์ในgetopts
ตัว อนุญาตให้ใช้ตัวเลือกแบบยาวและตัวเลือกหลังอาร์กิวเมนต์ที่ไม่ใช่ตัวเลือก (เช่นfoo a b c --verbose
แทนที่จะเป็นเพียงfoo -v a b c
) คำตอบนี้ Stackoverflowอธิบายวิธีการใช้ getopt
GNU
† jeffbyrnesกล่าวว่าลิงก์เดิมเสียชีวิตไปแล้ว แต่โชคดีที่ทางเครื่องกลับได้เก็บถาวรไว้
ดีกว่าที่จะใช้ getopt สิ่งอำนวยความสะดวกของ bash โปรดดูคำถามและคำตอบนี้สำหรับความช่วยเหลือเพิ่มเติม: การใช้ getopts ใน bash shell script เพื่อรับตัวเลือกบรรทัดคำสั่งที่ยาวและสั้น
ฉันคิดว่าคุณสามารถใช้กรณีนี้ ...
case $1 in
-h) echo $usage ;;
h) echo $usage ;;
help) echo $usage ;;
esac