İçinde
[ -f "$file" ]
[
komutu bir does stat()
(değil lstat()
saklanan yolda) sistem çağrısını $file
ve 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
( ENOTDIR
yol 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 ls
neden 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 ls
bana 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 zsh
kabuk, 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/system
modü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 $errnos
desteğin bazı sürümleriyle bozulduğunazsh
gcc
dikkat edin ).