Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> การเขียนโปรแกรม BASH

วิธีรวมตัวเลือกในสคริปต์เชลล์ Bash ของคุณ

คำสั่ง Terminal มักมีตัวเลือกหรือสวิตช์ ซึ่งคุณสามารถใช้เพื่อปรับเปลี่ยนวิธีที่คำสั่งทำงาน ตัวเลือกรวมอยู่ในข้อกำหนด POSIX สำหรับอินเทอร์เฟซบรรทัดคำสั่ง นอกจากนี้ยังเป็นข้อตกลงที่ให้เกียรติกับเวลาซึ่งสร้างขึ้นด้วยแอปพลิเคชัน UNIX ที่เก่าที่สุด ดังนั้นจึงควรทราบวิธีรวมไว้ในสคริปต์ Bash เมื่อคุณสร้างคำสั่งของคุณเอง

เช่นเดียวกับภาษาส่วนใหญ่ มีหลายวิธีในการแก้ปัญหาตัวเลือกการแยกวิเคราะห์ใน Bash จนถึงทุกวันนี้ วิธีโปรดของฉันยังคงเป็นวิธีที่ฉันเรียนรู้จากสคริปต์บิลด์ Slackware ของ Patrick Volkerding ซึ่งทำหน้าที่เป็นคำแนะนำเบื้องต้นเกี่ยวกับเชลล์สคริปต์ในตอนที่ฉันค้นพบ Linux ครั้งแรกและกล้าที่จะเสี่ยงกับไฟล์ข้อความธรรมดาที่มาพร้อมกับระบบปฏิบัติการ








P>

ตัวเลือกการแยกวิเคราะห์ใน Bash

กลยุทธ์ในการแยกวิเคราะห์ตัวเลือกใน Bash คือการวนรอบอาร์กิวเมนต์ทั้งหมดที่ส่งผ่านไปยังเชลล์สคริปต์ของคุณ พิจารณาว่าเป็นตัวเลือกหรือไม่ จากนั้นเลื่อนไปที่อาร์กิวเมนต์ถัดไป ทำขั้นตอนนี้ซ้ำจนกว่าจะไม่มีตัวเลือกเหลืออยู่

เริ่มต้นด้วยตัวเลือกบูลีน (บางครั้งเรียกว่า สวิตช์ หรือ ธง ):

#!/bin/bash

while [ True ]; do
if [ "$1" = "--alpha" -o "$1" = "-a" ]; then
    ALPHA=1
    shift 1
else
    break
fi
done

echo $ALPHA

ในรหัสนี้ ฉันสร้าง while วนซ้ำซึ่งทำหน้าที่เป็นวงวนไม่สิ้นสุดจนกว่าจะไม่มีการโต้แย้งเพิ่มเติมในการประมวลผล if คำสั่งพยายามจับคู่อาร์กิวเมนต์ใดๆ ก็ตามที่พบในตำแหน่งแรก ($1 ) เป็น --alpha หรือ -a . (นี่คือชื่อตัวเลือกตามอำเภอใจที่ไม่มีนัยสำคัญเป็นพิเศษ ในสคริปต์จริง คุณอาจใช้ --verbose และ -v เพื่อทริกเกอร์เอาต์พุตแบบละเอียด)

shift คีย์เวิร์ดทำให้อาร์กิวเมนต์ทั้งหมดเปลี่ยนไป 1 ดังนั้นอาร์กิวเมนต์ในตำแหน่ง 2 ($2 ) ถูกย้ายไปตำแหน่ง 1 ($1 ). else คำสั่งจะถูกเรียกใช้เมื่อไม่มีอาร์กิวเมนต์เพิ่มเติมในการประมวลผล ซึ่งทำลาย while วนซ้ำ

ที่ส่วนท้ายของสคริปต์ ค่าของ $ALPHA ถูกพิมพ์ไปยังเครื่องปลายทาง

ทดสอบสคริปต์:

$ bash ./test.sh --alpha
1
$ bash ./test.sh

$ bash ./test.sh -a
1

ตรวจพบตัวเลือกอย่างถูกต้อง

การตรวจจับอาร์กิวเมนต์ใน Bash

มีปัญหาแม้ว่า:อาร์กิวเมนต์พิเศษจะถูกละเว้น

$ bash ./test.sh --alpha foo
1
$

ในการดักจับอาร์กิวเมนต์ที่ไม่ได้มีไว้สำหรับตัวเลือก คุณสามารถดัมพ์อาร์กิวเมนต์ที่เหลือลงในอาร์เรย์ Bash

#!/bin/bash

while [ True ]; do
if [ "$1" = "--alpha" -o "$1" = "-a" ]; then
    ALPHA=1
    shift 1
else
    break
fi
done

echo $ALPHA

ARG=( "${@}" )
for i in ${ARG[@]}; do
    echo $i
done

ทดสอบเวอร์ชันใหม่ของสคริปต์:

$ bash ./test.sh --alpha foo
1
foo
$ bash ./test.sh foo

foo
$ bash ./test.sh --alpha foo bar
1
foo
bar

ตัวเลือกที่มีอาร์กิวเมนต์

บางตัวเลือกต้องการอาร์กิวเมนต์ทั้งหมดของตัวเอง ตัวอย่างเช่น คุณอาจต้องการอนุญาตให้ผู้ใช้ตั้งค่าแอตทริบิวต์ เช่น สีหรือความละเอียดของกราฟิก หรือกำหนดให้แอปพลิเคชันของคุณไปที่ไฟล์การกำหนดค่าที่กำหนดเอง

ในการใช้งาน Bash คุณสามารถใช้ shift คีย์เวิร์ดเหมือนกับที่คุณทำกับสวิตช์บูลีน แต่เปลี่ยนอาร์กิวเมนต์เป็น 2 แทนที่จะเป็น 1

#!/bin/bash

while [ True ]; do
if [ "$1" = "--alpha" -o "$1" = "-a" ]; then
    ALPHA=1
    shift 1
elif [ "$1" = "--config" -o "$1" = "-c" ]; then
    CONFIG=$2
    shift 2
else
    break
fi
done

echo $ALPHA
echo $CONFIG

ARG=( "${@}" )

for i in ${ARG[@]}; do
    echo $i
done

ในรหัสนี้ ฉันเพิ่ม elif ประโยคเพื่อเปรียบเทียบแต่ละอาร์กิวเมนต์กับทั้ง --config และ -c . ในกรณีที่มีการจับคู่ ค่าของตัวแปรที่เรียกว่า CONFIG ถูกกำหนดเป็นค่าของอาร์กิวเมนต์ที่สอง (ซึ่งหมายความว่า --config ตัวเลือกต้องมีอาร์กิวเมนต์) อาร์กิวเมนต์ทั้งหมดเลื่อนตำแหน่ง 2:1 เพื่อเลื่อน --config หรือ -c และ 1 เพื่อย้ายอาร์กิวเมนต์ ตามปกติ การวนซ้ำจะวนซ้ำจนกว่าจะไม่มีอาร์กิวเมนต์ที่ตรงกันเหลืออยู่

นี่คือการทดสอบสคริปต์เวอร์ชันใหม่:

$ bash ./test.sh --config my.conf foo bar
my.conf
foo
bar
$ bash ./test.sh -a --config my.conf baz
1
my.conf
baz

การแยกวิเคราะห์ตัวเลือกทำได้ง่าย

มีวิธีอื่นในการแยกวิเคราะห์ตัวเลือกใน Bash คุณสามารถใช้ case . แทนได้ คำสั่งหรือ getopt สั่งการ. ไม่ว่าคุณจะเลือกใช้ตัวเลือกใด ตัวเลือกสำหรับผู้ใช้ของคุณก็เป็นคุณสมบัติที่สำคัญสำหรับแอปพลิเคชันใดๆ และ Bash ก็ทำให้เป็นเรื่องง่าย