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




file-io scripting (12)

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

#!/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

https://code.i-harness.com


आप "!" के साथ एक अभिव्यक्ति को अस्वीकार कर सकते हैं:

#!/bin/bash
FILE=$1

if [ ! -f "$FILE" ]
then
    echo "File $FILE does not exist"
fi

प्रासंगिक मैन पेज man test या समकक्ष, man [ - या बिल्ट-इन बैश कमांड के लिए help [ या help [


आपको एक निर्विवाद चर के लिए test चलाने के बारे में सावधान रहना चाहिए, क्योंकि यह अप्रत्याशित परिणाम उत्पन्न कर सकता है:

$ [ -f ]
$ echo $?
0
$ [ -f "" ]
$ echo $?
1

सिफारिश आमतौर पर डबल उद्धरण चिह्नों से घिरा परीक्षण चर है:

#!/bin/sh
FILE=$1

if [ ! -f "$FILE" ]
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!

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

-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

में

[ -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 के कुछ संस्करणों के साथ टूटा हुआ है ) से सावधान रहें।


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

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 "The File '$FILE' Does Not Exist"
fi

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

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

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

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

बैश फ़ाइल परीक्षण

-b filename - विशेष फ़ाइल ब्लॉक करें
-c filename - विशेष चरित्र फ़ाइल
-d directoryname - निर्देशिका अस्तित्व के लिए जाँच करें
-e filename - फ़ाइल अस्तित्व के लिए जांचें, भले ही प्रकार (नोड, निर्देशिका, सॉकेट, आदि)
-f filename - नियमित फ़ाइल अस्तित्व के लिए जांच करें निर्देशिका नहीं
-G filename - जांचें कि फ़ाइल मौजूद है और प्रभावी समूह आईडी के स्वामित्व में है
-G filename set-group-id - सही है अगर फ़ाइल मौजूद है और सेट-समूह-आईडी है
-k filename - चिपचिपा बिट
-L filename - प्रतीकात्मक लिंक
-O filename - सही है अगर फ़ाइल मौजूद है और प्रभावी उपयोगकर्ता आईडी के स्वामित्व में है
-r filename - जांचें कि फ़ाइल एक पठनीय है या नहीं
-S filename - जांचें कि फ़ाइल सॉकेट है या नहीं
-s filename - जांचें कि फ़ाइल nonzero आकार है या नहीं
-u filename - जांचें कि फ़ाइल सेट-उपयोगकर्ता-आईडी बिट सेट है या नहीं
-w filename - जांचें कि फ़ाइल लिखने योग्य है या नहीं
-x filename - जांचें कि फ़ाइल निष्पादन योग्य है या नहीं

कैसे इस्तेमाल करे:

#!/bin/bash
file=./file
if [ -e "$file" ]; then
    echo "File exists"
else 
    echo "File does not exist"
fi 

एक परीक्षण अभिव्यक्ति का उपयोग करके अस्वीकार किया जा सकता है ! ऑपरेटर

#!/bin/bash
file=./file
if [ ! -e "$file" ]; then
    echo "File does not exist"
else 
    echo "File exists"
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




scripting