Di
[ -f "$file" ]
yang [
perintah melakukan stat()
(tidak lstat()
) system call pada jalur yang disimpan dalam $file
dan mengembalikan benar jika sistem panggilan berhasil dan jenis file sebagai dikembalikan oleh stat()
adalah " biasa ".
Jadi, jika [ -f "$file" ]
mengembalikan true, Anda dapat mengetahui bahwa file tersebut memang ada dan merupakan file biasa atau symlink yang akhirnya diputuskan menjadi file biasa (atau setidaknya itu pada saat filestat()
).
Namun jika itu mengembalikan false (atau jika [ ! -f "$file" ]
atau ! [ -f "$file" ]
mengembalikan true), ada banyak kemungkinan berbeda:
- file tidak ada
- file ada tetapi tidak biasa file (bisa berupa perangkat, fifo, direktori, socket ...)
- file ada tetapi Anda tidak memiliki izin pencarian ke direktori induk
- file ada tetapi jalur untuk mengaksesnya terlalu panjang
- file tersebut adalah symlink ke file biasa, tetapi Anda tidak memiliki izin pencarian untuk beberapa direktori yang terlibat dalam resolusi symlink.
- ... alasan lain mengapa
stat()
panggilan sistem mungkin gagal.
Singkatnya, seharusnya:
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
Untuk mengetahui dengan pasti bahwa file tersebut tidak ada, kita perlu stat()
panggilan sistem untuk kembali dengan kode kesalahan ENOENT
( ENOTDIR
memberitahu kita salah satu komponen jalur bukan direktori adalah kasus lain di mana kita dapat memberi tahu file tidak ada di jalur itu). Sayangnya [
perintah itu tidak memberi tahu kami. Ini akan mengembalikan false apakah kode kesalahan ENOENT, EACCESS (izin ditolak), ENAMETOOLONG atau yang lainnya.
The [ -e "$file" ]
tes juga dapat dilakukan dengan ls -Ld -- "$file" > /dev/null
. Dalam hal ini, ls
akan memberi tahu Anda mengapa stat()
gagal, meskipun informasi tidak dapat dengan mudah digunakan secara terprogram:
$ 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
Setidaknya ls
memberitahu saya itu bukan karena file itu tidak ada yang gagal. Itu karena tidak tahu apakah file itu ada atau tidak. The [
perintah hanya mengabaikan masalah.
Dengan zsh
shell, Anda dapat meminta kode kesalahan dengan $ERRNO
variabel khusus setelah [
perintah gagal , dan mendekode angka itu menggunakan $errnos
array khusus dalam zsh/system
modul:
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
(berhati-hatilah $errnos
dukungannya rusak dengan beberapa versi zsh
ketika dibangun dengan versi terbarugcc
).