bash मैं कैसे बता सकता हूं कि बैश में नियमित फ़ाइल मौजूद नहीं है?




file-io scripting (14)

यह उल्लेखनीय है कि यदि आपको एक कमांड निष्पादित करने की आवश्यकता है तो आप संक्षेप में संक्षिप्त कर सकते हैं

if [ ! -f "$file" ]; then
    echo "$file"
fi

सेवा मेरे

test -f "$file" || echo "$file"

या

[ -f "$file" ] || echo "$file"

मैंने यह देखने के लिए निम्न स्क्रिप्ट का उपयोग किया है कि कोई फ़ाइल मौजूद है या नहीं:

#!/bin/bash

FILE=$1     
if [ -f $FILE ]; then
   echo "File $FILE exists."
else
   echo "File $FILE does not exist."
fi

उपयोग करने के लिए सही वाक्यविन्यास क्या है यदि मैं केवल यह जांचना चाहता हूं कि फ़ाइल मौजूद नहीं है या नहीं ?

#!/bin/bash

FILE=$1     
if [ $FILE does not exist ]; then
   echo "File $FILE does not exist."
fi

ऐसा करने के तीन अलग-अलग तरीके हैं:

  1. बैश के साथ बाहर निकलने की स्थिति को नकारात्मक करें (कोई अन्य जवाब यह नहीं कहता है):

    if ! [ -e "$file" ]; then
        echo "file does not exist"
    fi
    

    या:

    ! [ -e "$file" ] && echo "file does not exist"
    
  2. टेस्ट कमांड के अंदर परीक्षण को नकारात्मक करें [ (प्रस्तुत करने से पहले सबसे अधिक जवाब देने का तरीका है):

    if [ ! -e "$file" ]; then
        echo "file does not exist"
    fi
    

    या:

    [ ! -e "$file" ] && echo "file does not exist"
    
  3. परीक्षण के नतीजे पर नकारात्मक अधिनियम ( && ) के बजाय ||

    केवल:

    [ -e "$file" ] || echo "file does not exist"
    

    यह मूर्खतापूर्ण दिखता है (आईएमओ), इसका उपयोग तब तक न करें जब तक कि आपके कोड को बोर्न शैल (जैसे सोलारिस 10 या उससे पहले के /bin/sh ) में पोर्टेबल होना पड़े, जिसमें पाइपलाइन अस्वीकरण ऑपरेटर ( ! ) की कमी थी:

    if [ -e "$file" ]; then
        :
    else
        echo "file does not exist"
    fi
    

कभी-कभी यह उपयोग करने के लिए आसान हो सकता है && और || ऑपरेटरों।

की तरह (यदि आपके पास "test" कमांड है):

test -b $FILE && echo File not there!

या

test -b $FILE || echo File there!

सबसे आसान तरीका

FILE=$1
[ ! -e "${FILE}" ] && echo "does not exist" || echo "exists"

मैं निम्नलिखित एक-लाइनर को POSIX खोल संगत प्रारूप में करना पसंद करता हूं:

$ [ -f "/$DIR/$FILE" ] || echo "$FILE NOT FOUND"

$ [ -f "/$DIR/$FILE" ] && echo "$FILE FOUND"

कुछ आदेशों के लिए, जैसे कि मैं एक स्क्रिप्ट में करता हूं:

$  [ -f "/$DIR/$FILE" ] || { echo "$FILE NOT FOUND" ; exit 1 ;}

एक बार जब मैंने ऐसा करना शुरू किया, तो मैं शायद ही कभी पूरी तरह से टाइप किए गए वाक्यविन्यास का उपयोग करता हूं !!


में

[ -f "$file" ]

[ आदेश एक 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 त्रुटि कोड के साथ वापस करने की आवश्यकता 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 विशेष चर के साथ त्रुटि कोड से पूछ सकते हैं [ आदेश, और zsh/system मॉड्यूल में $errnos विशेष सरणी का उपयोग करके उस संख्या को डीकोड करें:

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;;
    (*) echo "can't tell"; syserror "$err"
  esac
fi

( gcc हाल के संस्करणों के साथ बनाया गया जब $errnos समर्थन $errnos के कुछ संस्करणों के साथ टूटा हुआ है ) से सावधान रहें।


test कमांड ( [ यहां) में "नहीं" लॉजिकल ऑपरेटर है जो विस्मयादिबोधक बिंदु (कई अन्य भाषाओं के समान) है। इसे इस्तेमाल करे:

if [ ! -f /tmp/foo.txt ]; then
    echo "File not found!"
fi

[[ -f $FILE ]] || printf '%s does not exist!\n' "$FILE"

साथ ही, यह संभव है कि फ़ाइल एक टूटा प्रतीकात्मक लिंक है, या गैर-नियमित फ़ाइल, जैसे कि सॉकेट, डिवाइस या फीफो। उदाहरण के लिए, टूटे सिमलिंक के लिए चेक जोड़ने के लिए:

if [[ ! -f $FILE ]]; then
    if [[ -L $FILE ]]; then
        printf '%s is a broken symlink!\n' "$FILE"
    else
        printf '%s does not exist!\n' "$FILE"
    fi
fi

तुम यह केर सकते हो:

[[ ! -f "$FILE" ]] && echo "File doesn't exist"

या

if [[ ! -f "$FILE" ]]; then
    echo "File doesn't exist"
fi

यदि आप फ़ाइल और फ़ोल्डर दोनों की जांच करना चाहते हैं, तो -f बजाय -e विकल्प का उपयोग करें। -e नियमित फाइलों, निर्देशिकाओं, सॉकेट, चरित्र विशेष फाइलों, ब्लॉक विशेष फाइलों आदि के लिए सच है।


फ़ाइल अस्तित्व का परीक्षण करने के लिए, पैरामीटर निम्न में से कोई एक हो सकता है:

-e: Returns true if file exists (regular file, directory, or symlink)
-f: Returns true if file exists and is a regular file
-d: Returns true if file exists and is a directory
-h: Returns true if file exists and is a symlink

नीचे दिए गए सभी परीक्षण नियमित फाइलों, निर्देशिकाओं और सिम्लिंक पर लागू होते हैं:

-r: Returns true if file exists and is readable
-w: Returns true if file exists and is writable
-x: Returns true if file exists and is executable
-s: Returns true if file exists and has a size > 0

उदाहरण स्क्रिप्ट:

#!/bin/bash
FILE=$1

if [ -f "$FILE" ]; then
   echo "File $FILE exists"
else
   echo "File $FILE does not exist"
fi


एक परीक्षण को उलट करने के लिए, "!" का प्रयोग करें। यह अन्य भाषाओं में "नहीं" लॉजिकल ऑपरेटर के बराबर है। इसे इस्तेमाल करे:

if [ ! -f /tmp/foo.txt ];
then
    echo "File not found!"
fi

या थोड़ा अलग तरीके से लिखा है:

if [ ! -f /tmp/foo.txt ]
    then echo "File not found!"
fi

या आप इसका उपयोग कर सकते हैं:

if ! [ -f /tmp/foo.txt ]
    then echo "File not found!"
fi

या, सभी को एक साथ पेश करना:

if ! [ -f /tmp/foo.txt ]; then echo "File not found!"; fi

जो लिखा जा सकता है (तब "और" ऑपरेटर: &&) का उपयोग करके:

[ ! -f /tmp/foo.txt ] && echo "File not found!"

जो इस तरह कम दिखता है:

[ -f /tmp/foo.txt ] || echo "File not found!"

यह शेल स्क्रिप्ट निर्देशिका में फ़ाइल ढूंढने के लिए भी काम करती है:

echo "enter file"

read -r a

if [ -s /home/trainee02/"$a" ]
then
    echo "yes. file is there."
else
    echo "sorry. file is not there."
fi

यह कोड भी काम कर रहा है।

#!/bin/bash
FILE=$1
if [ -f $FILE ]; then
 echo "File '$FILE' Exists"
else
 echo "The File '$FILE' Does Not Exist"
fi






scripting