[ -f /*.txt ]
จะกลับมาจริงเฉพาะถ้ามีหนึ่ง (และมีเพียงหนึ่ง) ไฟล์ที่ไม่ใช่ที่ซ่อนอยู่ใน/ที่มีชื่อในปลาย.txtและหากไฟล์ที่เป็นไฟล์ปกติหรือ symlink ไปเป็นไฟล์ปกติ
นั่นเป็นเพราะเชลล์จะถูกขยายโดยเชลล์ก่อนที่จะถูกส่งไปยังคำสั่ง (ที่นี่[)
ดังนั้นถ้ามี/a.txtและ/b.txt, [จะถูกส่งผ่าน 5 ข้อโต้แย้ง: [, -f, /a.txt, และ/b.txt จะบ่นว่าได้รับข้อโต้แย้งมากเกินไป][-f
หากคุณต้องการตรวจสอบว่า*.txtรูปแบบขยายเป็นไฟล์ที่ไม่ซ่อนอย่างน้อยหนึ่งไฟล์ (ปกติหรือไม่):
shopt -s nullglob
set -- *.txt
if [ "$#" -gt 0 ]; then
./script "$@" # call script with that list of files.
fi
# Or with bash arrays so you can keep the arguments:
files=( *.txt )
# apply C-style boolean on member count
(( ${#files[@]} )) && ./script "${files[@]}"
shopt -s nullglobเป็นbashเฉพาะ แต่เปลือกหอยชอบksh93, zsh, yash, tcshมีงบเทียบเท่า
โปรดทราบว่ามันค้นหาไฟล์เหล่านั้นโดยการอ่านเนื้อหาของไดเรกทอรีมันไม่ลองและเข้าถึงไฟล์เหล่านั้นเลยซึ่งทำให้มีประสิทธิภาพมากกว่าโซลูชันที่เรียกคำสั่งเช่นlsหรือstatในรายการของไฟล์ที่คำนวณโดยเชลล์
มาตรฐานที่shเทียบเท่าจะเป็น:
set -- [*].txt *.txt
case "$1$2" in
('[*].txt*.txt') ;;
(*) shift; script "$@"
esac
ปัญหาคือว่าด้วย Bourne หรือ POSIX shells ถ้ารูปแบบไม่ตรงกันมันจะขยายออกไปเอง ดังนั้นถ้า*.txtขยายไปยัง*.txtคุณไม่ทราบว่ามันเป็นเพราะไม่มีแฟ้มในไดเรกทอรีหรือเพราะมีไฟล์เดียวที่เรียกว่า.txt *.txtการใช้[*].txt *.txtช่วยให้สามารถแยกแยะระหว่างสอง
/?fiนอกจากนี้คุณกำลังขาดหายไปอัฒภาคก่อน