में
[ -f "$file" ]
यदि सिस्टम कॉल सफल होता है और फाइल के प्रकार " नियमित " है , तो [
कमांड एक stat()
(नहीं lstat()
) सिस्टम कॉल को स्टोर करता है $file
और वापस लौटाता है ।stat()
इसलिए अगर यह [ -f "$file" ]
सच है, तो आप बता सकते हैं कि फाइल मौजूद है और एक नियमित फाइल है या एक सिमलिंक अंततः एक नियमित फाइल में हल हो रही है (या कम से कम यह उस समय थी stat()
)।
हालाँकि अगर यह गलत है (या यदि सही है [ ! -f "$file" ]
या नहीं ! [ -f "$file" ]
), तो कई अलग संभावनाएं हैं:
- फ़ाइल मौजूद नहीं है
- फ़ाइल मौजूद है, लेकिन एक नियमित फ़ाइल नहीं है (एक उपकरण, फिफो, निर्देशिका, सॉकेट हो सकता है ...)
- फ़ाइल मौजूद है, लेकिन आपके पास मूल निर्देशिका के लिए खोज अनुमति नहीं है
- फ़ाइल मौजूद है, लेकिन इसे एक्सेस करने का रास्ता बहुत लंबा है
- फ़ाइल एक नियमित फ़ाइल के लिए एक सिम्लिंक है, लेकिन आपके पास सिम्लिंक के रिज़ॉल्यूशन में शामिल कुछ निर्देशिकाओं की खोज अनुमति नहीं है।
- ... किसी अन्य कारण से
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
)।