นั่นเป็นครั้งแรกที่พฤติกรรมของตัวแทนที่น่าแปลกใจเนื่องจากคำอธิบายของ*
อักขระตัวแทนกล่าวว่า:
จับคู่สตริงใด ๆ รวมถึงสตริง null
... จนกว่าคุณจะรู้ว่าช่วงเวลานั้นค่อนข้างพิเศษเมื่อตัวละครตัวแรกของชื่อไฟล์ ข้อความเกริ่นนำในภาษา3.5.8 Filename Expansion
บอกว่า:
เมื่อใช้รูปแบบสำหรับการขยายชื่อไฟล์อักขระ '.' ที่จุดเริ่มต้นของชื่อไฟล์หรือทันทีหลังจากเครื่องหมายทับจะต้องจับคู่อย่างชัดเจนเว้นแต่ว่าตัวเลือกเปลือก dotglob ตั้งค่า
"รูปแบบการใช้งาน" ของสัญลักษณ์แทนคำนำหน้าด้วย./
จะมีประโยชน์สำหรับการจัดการชื่อด้วยเครื่องหมายนำหน้าในเปลือก bashดังที่ผู้ขับเหล็กแสดงความคิดเห็น จะไม่มีผลกับการขยาย wildcard / ชื่อไฟล์ แต่ทำให้ปลอดภัย / ง่ายกว่าในการจัดการชื่อไฟล์เมื่อคุณอ้างถึงหากพวกเขาเริ่มต้นด้วยตัวอักษรที่โปรแกรมเหล่านั้นอาจตีความผิดเป็นตัวเลือก ตัวอย่างเช่น:
# I want a file named `-n`
$ touch -n
touch: invalid option -- 'n'
Try 'touch --help' for more information.
$ touch -- -n
### ok
$ touch ./-n
### ok
... และตอนนี้ฉันมีไฟล์ชื่อ-n
แล้วถ้าฉันวนไปวนมาด้วย wildcard:
for file in *n
do
echo "$file"
done
... ฉันไม่ออกเลย!
แต่ถ้าผมคำนำหน้าสัญลักษณ์แทนด้วย./
,
for file in ./*n
do
echo "$file"
done
./-n
... ฉันเห็นชื่อไฟล์
นี่เป็นตัวอย่างง่ายๆสำหรับวัตถุประสงค์ในการสาธิต ดูเพิ่มเติมทำไม printf ถึงดีกว่า echo ด้วยเหตุผลนี้และอื่น ๆ ยูทิลิตี้อื่น ๆ จะได้รับการสะดุดโดยตัวเลือกอื่น ๆ ดังนั้นจึงเป็นการดีกว่าถ้าจะแสดงชื่อไฟล์ให้กับสาธารณูปโภคอย่างปลอดภัยที่สุด หากคุณไม่ได้ใส่ไวลด์การ์ดไว้ในชื่อ "หนี" คุณจะต้อง "ป้องกัน" ยูทิลิตี้ของคุณด้วยวิธีอื่น หนึ่งทั่วไปหนึ่งคือการส่งสัญญาณการสิ้นสุดของตัวเลือกด้วย--
เช่น
for file in *n
do
mv -- "$file" backup/"$file"
done
... ซึ่งจะปลอดภัยผ่าน-n
ชื่อไฟล์ไปยังmv
(เท่าที่เห็นภายใต้set -x
):
mv -- -n backup/-n
./*
คือเพื่อให้แน่ใจว่าชื่อที่ขึ้นต้นด้วย-
จะไม่ถือว่าเป็นตัวเลือก