Score:0

คำเตือนเกี่ยวกับชื่อตัวเลือกที่ไม่ถูกต้องซึ่งเกิดขึ้นระหว่างชื่อตัวเลือกที่ถูกต้อง

ธง jp

ฉันได้เขียน bash ชิ้นต่อไปนี้ แต่ต้องใช้บางสิ่งที่ซับซ้อนกว่านี้เล็กน้อย

ภารกิจคือตรวจหาตัวเลือกที่ไม่ถูกต้องเฉพาะในกรณีที่เกิดขึ้นระหว่างตัวเลือกที่รู้จัก

ตัวอย่างเช่นต่อไปนี้ myfunc -v -w --vlt "อูบุนตู" จะพิมพ์

ตัวเลือกที่ไม่รู้จัก -w

แต่ myfunc -v --vlt -w "อูบุนตู" จะไม่พิมพ์ข้อความเตือนใด ๆ เนื่องจาก -ว เกิดขึ้นหลังจากอาร์กิวเมนต์ที่ไม่ใช่ตัวเลือกที่ทราบ

รหัสจะตรวจสอบเฉพาะชื่อตัวเลือกที่ขึ้นต้นด้วย -. ด้วยประการฉะนี้ myfunc -v -w 5 --vlt "อูบุนตู" จะรายงานเฉพาะใน -วโดยไม่คำนึงถึงค่าตัวเลือกใดๆ สำหรับข้อความเตือน

 สำหรับฉันใน "$@"; ทำ
  กรณี $i ใน
   ("-v"|"--คำฟุ่มเฟื่อย"|"-u"|"--การใช้งาน"|"-h"|"--วิธีใช้")
     printf '%s\n' "ตัวเลือก: $i"
     ;;
   ("--vlt"|"--blu"|"--grn"|"--ylw")
     printf '%s\n' "ตัวเลือก: $i"
     ;;
   ("--orn"|"--pur"|"--red"|"--wht")
     printf '%s\n' "ตัวเลือก: $i"
     ;;
   (*)
     printf '%s\n' "ตัวเลือกไม่ถูกต้อง | Argm: $i"
     ;;
  เอสแซค
 เสร็จแล้ว
bac0n avatar
cn flag
วงเล็บด้านซ้ายไม่ควรมี คุณไม่จำเป็นต้องอ้างอิงรูปแบบเช่นกัน หากคุณไม่มีความตั้งใจที่จะจัดการ `$@` (พารามิเตอร์ตำแหน่ง) ก็ไม่จำเป็นต้องกำหนดให้กับอาร์เรย์อื่นอีกครั้ง (ควรใส่ case `"$i"` ใน...)
bac0n avatar
cn flag
`printf 'ตัวเลือกไม่ถูกต้อง: %s\n' "$i"`
jp flag
คำถามเกี่ยวกับการตรวจจับตัวเลือกที่ไม่ถูกต้องซึ่งเกิดขึ้นระหว่างอาร์กิวเมนต์ตัวเลือกที่ถูกต้อง
bac0n avatar
cn flag
คุณจะยังคงต้องแก้ไขสิ่งที่ฉันชี้ให้เห็น
jp flag
ไม่จำเป็นต้องใช้ "$i" กับ `case` ใช่ ฉันสามารถทำ `for i ใน "$@"; ทำ' ใช่ไหม?
Score:1
ธง cn

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

#!/bin/bash

check_value(){
    ! [[ $1 = @(|-[!-]*|--[!-]*) ]]
}
expand_option(){
    ท้องถิ่น -n __a__=$2; ท้องถิ่น b=${1:1}
    [[ ! $b =~ [\ -] ]] && {
      [[ $b =~ ${b//?/(.)} ]] && { __a__=("${BASH_RMATCH[@]:1}"); __a__=("${__a__[@]/#/-}"); }
    } || กลับ 1
}

ประกาศ -a a=() b=()
ประกาศ -A O=()

ในขณะที่ (($# > 0)); ทำ
    กรณี "$1" ใน
    -[!-][!-]*)
        expand_option "$1" ก || { \
        printf 'การขยายไม่ถูกต้อง: %s\n' "$1"; ทางออก; }; ชุด -- "${a[@]}" "${@:2}"
        ดำเนินต่อ
        ;;
     -[วู้])
        O[${1//-}]=1
        printf 'ตัวเลือก 1: %s\n' "$1"
        ;;
    -[!-]*)
        printf 'ตัวเลือกสั้นไม่ถูกต้อง: %s\n' "$1"
        ทางออก
        ;;
     --ช่วย)  ;&
     --การใช้งาน) ;&
     --คำฟุ่มเฟือย)
        O[${1//-}]=1
        printf 'ตัวเลือก 2: %s\n' "$1"
        ;;
     --vlt)
        check_value "$2" || { \
        printf "ค่าไม่ถูกต้อง: '%s'\n" "$2"; ทางออก; }
        O[${1//-}]=$2
        printf 'ค่าสำหรับ %s: %s\n' "$1" "$2"
        กะ
        ;;
    --[!-]*)
        printf 'ตัวเลือกแบบยาวไม่ถูกต้อง: %s\n' "$1"
        ทางออก
        ;;
    --)
        b+=("${@:2}")
        หยุดพัก
        ;;
     *)
        b+=("$1")
        ;;
    เอสแซค
    กะ
เสร็จแล้ว

echo ตัวเลือกสุดท้าย '${O[@]}':
สำหรับ k ใน "${!O[@]}"; ทำ
    printf 'คีย์: %s, ค่า: %s\n' "$k" "${O[$k]}"
เสร็จแล้ว

ถ้า ((${#b[@]} > 0)); แล้ว
    printf 'ไม่ทราบค่า: %s\n' "${b[*]}"
ไฟ

jp flag
การใช้ `;;` แทน `;&` จะยังทำสิ่งเดียวกันอยู่หรือไม่?
bac0n avatar
cn flag
ฉันจะหาทางออกอื่นด้วย getopt ... `;&` ทำหน้าที่เป็นทางผ่าน ผมว่ามันทำให้น่าอ่านขึ้น
jp flag
ไม่ได้ตั้งใจจะทำให้แผนของคุณเสีย แต่ฉันหลีกเลี่ยงการใช้ `getopt` หรือ `getopts` ฉันเคยใช้มันมาก่อน แต่ฉันทำสิ่งต่าง ๆ มากกว่าที่พวกเขามีให้ในปัจจุบัน
bac0n avatar
cn flag
ซับซ้อนเกินไป

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา