ใน
[ -f "$file" ]
[
คำสั่งไม่ได้stat()
(ไม่ได้lstat()
) สายระบบบนเส้นทางที่เก็บไว้ใน$file
และผลตอบแทนที่แท้จริงว่าระบบโทรประสบความสำเร็จและประเภทของไฟล์ที่ส่งกลับโดยstat()
เป็น " ปกติ "
ดังนั้นหาก[ -f "$file" ]
คืนค่าเป็นจริงคุณสามารถบอกได้ว่าไฟล์นั้นมีอยู่จริงและเป็นไฟล์ปกติหรือ symlink จะแก้ไขเป็นไฟล์ปกติในที่สุด (หรืออย่างน้อยก็เป็นตอนนั้นstat()
)
อย่างไรก็ตามถ้ามันกลับมา เท็จ (หรือถ้า[ ! -f "$file" ]
หรือ! [ -f "$file" ]
กลับจริง) มีความเป็นไปได้ที่แตกต่างกัน:
- ไฟล์ไม่มีอยู่
- มีไฟล์อยู่ แต่ไม่ใช่ไฟล์ปกติ (อาจเป็นอุปกรณ์, Fifo, ไดเรกทอรี, ซ็อกเก็ต ... )
- มีไฟล์อยู่ แต่คุณไม่มีสิทธิ์ในการค้นหาในไดเรกทอรีหลัก
- ไฟล์มีอยู่ แต่เส้นทางที่จะเข้าถึงนั้นยาวเกินไป
- ไฟล์นี้เป็น symlink ไปยังไฟล์ปกติ แต่คุณไม่ได้รับอนุญาตให้ค้นหาในบางไดเรกทอรีที่เกี่ยวข้องกับการแก้ปัญหาของ symlink
- ... เหตุผลอื่นใดสาเหตุที่การ
stat()
เรียกระบบอาจล้มเหลว
กล่าวโดยย่อคือ:
if [ -f "$file" ]; then
printf '"%s" is a path to a regular file or symlink to regular file\n' "$file"
elif [ -e "$file" ]; then
printf '"%s" exists but is not a regular file\n' "$file"
elif [ -L "$file" ]; then
printf '"%s" exists, is a symlink but I cannot tell if it eventually resolves to an actual file, regular or not\n' "$file"
else
printf 'I cannot tell if "%s" exists, let alone whether it is a regular file or not\n' "$file"
fi
หากต้องการทราบว่าไฟล์นั้นไม่มีอยู่จริงเราจะต้องstat()
เรียกใช้ระบบเพื่อส่งคืนพร้อมรหัสข้อผิดพลาดของENOENT
( ENOTDIR
บอกเราว่าหนึ่งในองค์ประกอบของพา ธ ไม่ใช่ไดเรกทอรีคือกรณีอื่นที่เราสามารถบอกได้ว่าไฟล์ไม่ได้ มีอยู่โดยเส้นทางนั้น) น่าเสียดายที่[
คำสั่งไม่แจ้งให้เราทราบ มันจะกลับเท็จว่ารหัสข้อผิดพลาดคือ ENOENT, EACCESS (สิทธิ์ปฏิเสธ), ENAMETOOLONG หรือสิ่งอื่นใด
ทดสอบยังสามารถทำได้ด้วย[ -e "$file" ]
ls -Ld -- "$file" > /dev/null
ในกรณีนั้นls
จะบอกคุณว่าทำไมความstat()
ล้มเหลวถึงแม้ว่าข้อมูลจะไม่สามารถใช้โปรแกรมได้อย่างง่ายดาย:
$ file=/var/spool/cron/crontabs/root
$ if [ ! -e "$file" ]; then echo does not exist; fi
does not exist
$ if ! ls -Ld -- "$file" > /dev/null; then echo stat failed; fi
ls: cannot access '/var/spool/cron/crontabs/root': Permission denied
stat failed
อย่างน้อยก็ls
บอกฉันไม่ได้เพราะไฟล์ไม่มีอยู่ว่ามันล้มเหลว เป็นเพราะไม่สามารถบอกได้ว่ามีไฟล์อยู่หรือไม่ [
คำสั่งเพียงละเลยปัญหา
ด้วยzsh
เชลล์คุณสามารถค้นหารหัสข้อผิดพลาดด้วย$ERRNO
ตัวแปรพิเศษหลังจาก[
คำสั่งที่ล้มเหลวและถอดรหัสหมายเลขนั้นโดยใช้$errnos
อาร์เรย์พิเศษในzsh/system
โมดูล:
zmodload zsh/system
ERRNO=0
if [ ! -f "$file" ]; then
err=$ERRNO
case $errnos[err] in
("") echo exists, not a regular file;;
(ENOENT|ENOTDIR)
if [ -L "$file" ]; then
echo broken link
else
echo does not exist
fi;;
(*) syserror -p "can't tell: " "$err"
esac
fi
(ระวังการ$errnos
สนับสนุนถูกทำลายด้วยบางรุ่นzsh
เมื่อสร้างขึ้นด้วยรุ่นล่าสุดของgcc
)