İçinde
[ -f "$file" ]
[komutu bir does stat()(değil lstat()saklanan yolda) sistem çağrısını $fileve döndüren gerçek sistem çağrısı başarılı olursa ve dosya türü tarafından döndürülen olarakstat() "dir düzenli ".
Yani eğer [ -f "$file" ] true döndürürse, dosyanın var olduğunu ve normal bir dosya veya sonunda normal bir dosyaya çözümlenen bir symlink olduğunu söyleyebilirsiniz (veya en azından o sıradaydı stat()).
Ancak yanlış döndürürse (veya[ ! -f "$file" ] veya ! [ -f "$file" ]return true), birçok farklı olasılık vardır:
- dosya mevcut değil
- dosya var ama bir normal bir dosya (bir cihaz, fifo, dizin, soket olabilir ...)
- dosya var ancak üst dizine arama izniniz yok
- dosya var, ancak dosyaya erişmek için gereken yol çok uzun
- dosya normal bir dosyaya bir simge bağlantısıdır, ancak simge bağlantısının çözümüne dahil olan bazı dizinler için arama izniniz yoktur.
- ...
stat()sistem çağrısının başarısız olmasının başka nedenleri .
Kısacası, şöyle olmalıdır:
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
Dosyanın bulunmadığından emin olmak için, stat()sistem çağrısının hata koduyla geri dönmesi gerekir ENOENT( ENOTDIRyol bileşenlerinden birinin dizin olmadığını söyler, dosyanın olmadığını söyleyebileceğimiz başka bir durumdur bu yol tarafından var). Ne yazık ki [komut bunu bize bildirmiyor. Hata kodu ENOENT, EACCESS (izin reddedildi), ENAMETOOLONG veya başka bir şey olsun, yanlış döndürür.
[ -e "$file" ]Test ayrıca ile yapılabilir ls -Ld -- "$file" > /dev/null. Bu durumda, bilgiler lsneden stat()başarısız olduğunu söyleyecektir , ancak bilgiler programlı olarak kolayca kullanılamaz:
$ 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
En azından lsbana bunun başarısız olduğu için dosya olmadığı için olmadığını söylüyor. Çünkü dosyanın var olup olmadığını söyleyemez. [Komut sadece sorunu görmezden geldi.
İle zshkabuk, sizinle hata kodunu sorgulayabilir $ERRNOözel başarısız sonra değişkenin [komuta ve sayı kullanarak o kod çözme $errnosözel dizi zsh/systemmodülü:
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
(en son sürümleriyle oluşturulduğunda $errnosdesteğin bazı sürümleriyle bozulduğunazshgcc dikkat edin ).