[ -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
นอกจากนี้คุณกำลังขาดหายไปอัฒภาคก่อน