shell - जांचें कि शेल स्क्रिप्ट में कोई निर्देशिका मौजूद है या नहीं




unix posix (20)

find का उपयोग कर अधिक फीचर्स

  • उप-निर्देशिकाओं के भीतर फ़ोल्डर का अस्तित्व जांचें:

    found=`find -type d -name "myDirectory"`
    if [ -n "$found"]
    then
        # The variable 'found' contains the full path where "myDirectory" is.
        # It may contain several lines if there are several folders named "myDirectory".
    fi
    
  • वर्तमान निर्देशिका के भीतर एक पैटर्न के आधार पर एक या कई फ़ोल्डर्स के अस्तित्व की जांच करें:

    found=`find -maxdepth 1 -type d -name "my*"`
    if [ -n "$found"]
    then
        # The variable 'found' contains the full path where folders "my*" have been found.
    fi
    
  • दोनों संयोजन। निम्नलिखित उदाहरण में, यह वर्तमान निर्देशिका में फ़ोल्डर के अस्तित्व की जांच करता है:

    found=`find -maxdepth 1 -type d -name "myDirectory"`
    if [ -n "$found"]
    then
        # The variable 'found' is not empty => "myDirectory"` exists.
    fi
    

एक शेल स्क्रिप्ट के भीतर, निर्देशिका मौजूद है या नहीं, यह जांचने के लिए किस कमांड का उपयोग किया जा सकता है?


  1. परीक्षण करने के लिए एक सरल स्क्रिप्ट अगर डीआईआर या फाइल मौजूद है या नहीं:

    if [ -d /home/ram/dir ]   # for file "if [-f /home/rama/file]" 
    then 
        echo "dir present"
    else
        echo "dir not present"
    fi
    
  2. यह जांचने के लिए एक सरल स्क्रिप्ट है कि निर्देशिका मौजूद है या नहीं:

    mkdir tempdir   # if you want to check file use touch instead of mkdir
    ret=$?
    if [ "$ret" == "0" ]
    then
        echo "dir present"
    else
        echo "dir not present"
    fi
    

    उपर्युक्त स्क्रिप्ट जांचेंगे कि डीआईआर मौजूद है या नहीं

    $? अगर अंतिम कमांड sucess यह "0" और शून्य शून्य मान देता है। मान लीजिए tempdir पहले से मौजूद है तो mkdir tempdir नीचे की तरह त्रुटि देगा:

    mkdir: निर्देशिका 'tempdir' नहीं बना सकता: फ़ाइल मौजूद है


आप test -d उपयोग कर सकते हैं ( man test देखें)।

-d file सही है अगर फ़ाइल मौजूद है और एक निर्देशिका है।

उदाहरण के लिए:

test -d "/etc" && echo Exists || echo Does not exist

नोट: test कमांड सशर्त अभिव्यक्ति के समान है [ (देखें: man [ ), इसलिए यह शेल स्क्रिप्ट में पोर्टेबल है।

[ - यह test लिए एक पर्याय है, लेकिन आखिरी तर्क होना चाहिए, एक शाब्दिक होना चाहिए ] , उद्घाटन से मेल खाने के लिए [

संभावित विकल्पों या आगे की सहायता के लिए, जांचें:

  • help [
  • help test
  • man test या man [

इस कोड को बैश प्रोम पर टाइप करें

if [ -d "$DIRECTORY" ]; then
  # if true this block of code will execute
fi

क्या आपने लीप से पहले देखने के बजाए बस जो भी करना चाहते हैं, उसे करने पर विचार किया है?

आईई, यदि आप इसे दर्ज करने से पहले किसी निर्देशिका के अस्तित्व की जांच करना चाहते हैं, तो बस इसे करने का प्रयास करें:

if pushd /path/you/want/to/enter; then
    # commands you want to run in this directory
    popd
fi

यदि आपके द्वारा pushd को दिया गया पथ मौजूद है, तो आप इसे दर्ज करेंगे और यह 0 बाहर निकल जाएगा, जिसका अर्थ है कि कथन का अगला भाग निष्पादित होगा। यदि यह अस्तित्व में नहीं है, तो कुछ भी नहीं होगा (कुछ आउटपुट के अलावा यह कहता है कि निर्देशिका मौजूद नहीं है, जो शायद डीबगिंग के लिए उपयोगी सहायक प्रभाव है)।

इससे बेहतर लगता है, जिसके लिए खुद को दोहराने की आवश्यकता है:

if [ -d /path/you/want/to/enter ]; then
    pushd /path/you/want/to/enter
    # commands you want to run in this directory
    popd
fi

cd , mv , rm , इत्यादि के साथ वही काम करता है ... यदि आप उन फ़ाइलों पर आज़माते हैं जो मौजूद नहीं हैं, तो वे एक त्रुटि से बाहर निकलेंगे और एक संदेश प्रिंट करेंगे कि यह अस्तित्व में नहीं है, और आपका then ब्लॉक होगा को छोड़ दिया। यदि आप उन फ़ाइलों पर आज़माते हैं जो मौजूद हैं, तो आदेश निष्पादित करेगा और 0 स्थिति से बाहर निकल जाएगा, जिससे आपके ब्लॉक को निष्पादित करने की अनुमति मिल जाएगी।


छोटा रूप:

[ -d "$DIR" ] && echo "Yes"

टिप्पणी के अनुसार:

यदि आप निर्देशिका बनाना चाहते हैं और यह अभी तक अस्तित्व में नहीं है, तो सबसे सरल तकनीक mkdir -p का उपयोग करना है जो निर्देशिका बनाता है - और किसी भी गायब निर्देशिका को पथ बनाता है - और यदि निर्देशिका पहले से मौजूद है तो विफल नहीं होती है, तो आप कर सकते हैं इसे सब एक साथ करें:

mkdir -p /some/directory/you/want/to/exist || exit 1

दरअसल, बुलेटप्रूफ दृष्टिकोण प्राप्त करने के लिए आपको कई टूल का उपयोग करना चाहिए:

DIR_PATH=`readlink -f "${the_stuff_you_test}"` # Get rid of symlinks and get abs path
if [[ -d "${DIR_PATH}" ]] ; Then # now you're testing
    echo "It's a dir";
fi

जब तक आप "${}" उपयोग करते हैं, तब तक रिक्त स्थान और विशेष वर्णों के बारे में चिंता करने की आवश्यकता नहीं है।

ध्यान दें कि [[]] रूप में पोर्टेबल नहीं है, लेकिन चूंकि अधिकांश लोग बैश के आधुनिक संस्करणों के साथ काम करते हैं (क्योंकि आखिरकार, अधिकांश लोग कमांड लाइन के साथ भी काम नहीं करते हैं: -पी), लाभ से अधिक है मुसीबत।


नीचे का उपयोग किया जा सकता है,

find . -type d -name dirname -prune -print

बैश स्क्रिप्ट में संदर्भित करते समय हमेशा डबल कोट्स में चर को लपेटना याद रखें। बच्चे इन दिनों इस विचार के साथ बड़े हो जाते हैं कि उनके पास उनके निर्देशिका नामों में रिक्त स्थान और अन्य मज़ेदार पात्र हो सकते हैं। (रिक्त स्थान! मेरे दिनों में, हमारे पास कोई फैंसी रिक्त स्थान नहीं था!))

एक दिन, उनमें से एक बच्चा आपकी लिपि $DIRECTORY सेट के साथ "My M0viez" और आपकी स्क्रिप्ट उड़ जाएगी। आप वह नहीं चाहते हैं। तो इसका इस्तेमाल करें।

if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists, even if it contains spaces
fi

यदि आप यह जांचना चाहते हैं कि कोई निर्देशिका मौजूद है, भले ही यह वास्तविक निर्देशिका या सिमलिंक है, तो इसका उपयोग करें:

ls $DIR
if [ $? != 0 ]; then
        echo "Directory $DIR already exists!"
        exit 1;
fi
echo "Directory $DIR does not exist..."

स्पष्टीकरण: "ls" कमांड त्रुटि देता है "ls: / x: ऐसी कोई फ़ाइल या निर्देशिका नहीं" यदि निर्देशिका या सिम्लिंक मौजूद नहीं है, और रिटर्न कोड भी सेट करता है, जिसे आप "$?" के माध्यम से पुनर्प्राप्त कर सकते हैं, गैर- -नुल (आमतौर पर "1")। सुनिश्चित करें कि आप "एलएस" कॉल करने के बाद सीधे रिटर्न कोड की जांच करें।


यह जांचने के लिए कि कोई निर्देशिका मौजूद है या नहीं, यदि आप इस तरह की संरचना को सरल बना सकते हैं:

if [ -d directory/path to a directory ] ; then
#Things to do

else #if needed #also: elif [new condition] 
# things to do
fi

आप इसे नकारात्मक में भी कर सकते हैं

if [ ! -d directory/path to a directory ] ; then
# things to do when not an existing directory

नोट : सावधान रहें, दोनों खुले और बंद ब्रेसिज़ के दोनों तरफ खाली रिक्त स्थान छोड़ दें।

उसी वाक्यविन्यास के साथ आप इसका उपयोग कर सकते हैं:

-e: any kind of archive 

-f: file 

-h: symbolic link 

-r: readable file 

-w: writable file 

-x: executable file 

-s: file size greater than zero 

यहां एक बहुत व्यावहारिक मुहावरे है:

(cd $dir) || return # is this a directory,
                    # and do we have access?

मैं आमतौर पर इसे एक समारोह में लपेटता हूं:

can_use_as_dir() { 
    (cd ${1:?pathname expected}) || return
}

या:

assert_dir_access() { 
    (cd ${1:?pathname expected}) || exit
}

इस दृष्टिकोण के बारे में अच्छी बात यह है कि मुझे एक अच्छा त्रुटि संदेश नहीं सोचना है।

cd मुझे पहले से ही stderr के लिए एक मानक एक लाइन संदेश दे देंगे। इससे अधिक जानकारी भी मिल जाएगी जो मैं प्रदान करने में सक्षम हूं। एक सबहेल ( ... ) अंदर cd प्रदर्शन करके, कमांड कॉलर की वर्तमान निर्देशिका को प्रभावित नहीं करता है। यदि निर्देशिका मौजूद है, तो यह सबहेल और फ़ंक्शन केवल एक नो-ऑप है।

अगला तर्क है कि हम cd पास करते हैं: ${1:?pathname expected} । यह पैरामीटर प्रतिस्थापन का एक और विस्तृत रूप है जिसे नीचे अधिक विस्तार से समझाया गया है।

टीएल; डॉ: यदि इस फ़ंक्शन में पारित स्ट्रिंग खाली है, तो हम फिर से सबहेल ( ... ) से बाहर निकलें और दिए गए त्रुटि संदेश के साथ फ़ंक्शन से वापस आएं।

ksh93 मैन पेज से उद्धरण:

${parameter:?word}

यदि parameter सेट किया गया है और गैर-शून्य है तो इसके मूल्य को प्रतिस्थापित करें; अन्यथा, शैल से word और बाहर निकलें (अगर इंटरैक्टिव नहीं है)। यदि word छोड़ा जाता है तो एक मानक संदेश मुद्रित होता है।

तथा

यदि कोलन : उपरोक्त अभिव्यक्तियों से छोड़ा गया है, तो खोल केवल जांचता है कि पैरामीटर सेट है या नहीं।

यहाँ वाक्यांश वाक्यांश प्रलेखन के लिए अनोखा है, क्योंकि word किसी भी उचित स्ट्रिंग को संदर्भित कर सकता है, जिसमें व्हाइटस्पेस शामिल है।

इस विशेष मामले में, मुझे पता है कि मानक त्रुटि संदेश 1: parameter not set नहीं है, इसलिए मैं उस मान के प्रकार पर ज़ूम इन करता हूं जिसे हम यहां उम्मीद करते हैं - निर्देशिका का pathname

एक दार्शनिक नोट: खोल एक वस्तु उन्मुख भाषा नहीं है, इसलिए संदेश pathname कहता है, directory नहीं। इस स्तर पर, मैं इसे सरल रखना चाहूंगा - फ़ंक्शन के लिए तर्क केवल तार हैं।


या कुछ पूरी तरह से बेकार के लिए:

[ -d . ] || echo "No"

-e चेक का उपयोग फाइलों की जांच करेगा और इसमें निर्देशिकाएं शामिल हैं।

if [ -e ${FILE_PATH_AND_NAME} ]
then
    echo "The file or directory exists."
fi

-l (कम लिस्टिंग) विकल्प के साथ संयोजन में ls कमांड फाइलों और निर्देशिकाओं के बारे में विशेषताएँ गुण देता है।
विशेष रूप से ls -l आउटपुट का पहला अक्षर यह आमतौर पर d या ए - (डैश) होता है। सूचीबद्ध एक d के मामले में निश्चित रूप से एक निर्देशिका है।

केवल एक पंक्ति में निम्न आदेश आपको बताएगा कि दिए गए ISDIR चर में निर्देशिका का पथ है या नहीं:

[[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] &&
    echo "YES, $ISDIR is a directory." || 
    echo "Sorry, $ISDIR is not a directory"

व्यावहारिक उपयोग:

    [[email protected] ~]$ ISDIR="$HOME/Music" 
    [[email protected] ~]$ ls -ld "$ISDIR"
    drwxr-xr-x. 2 claudio claudio 4096 Aug 23 00:02 /home/claudio/Music
    [[email protected] ~]$ [[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] && 
        echo "YES, $ISDIR is a directory." ||
        echo "Sorry, $ISDIR is not a directory"
    YES, /home/claudio/Music is a directory.

    [[email protected] ~]$ touch "empty file.txt"
    [[email protected] ~]$ ISDIR="$HOME/empty file.txt" 
    [[email protected] ~]$ [[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] && 
        echo "YES, $ISDIR is a directory." || 
        echo "Sorry, $ISDIR is not a directoy"
    Sorry, /home/claudio/empty file.txt is not a directory

[ -d ~/Desktop/TEMPORAL/ ] && echo "DIRECTORY EXISTS" || echo "DIRECTORY DOES NOT EXIST"

[[ -d "$DIR" && ! -L "$DIR" ]] && echo "It's a directory and not a symbolic link"

एनबी: क्वोटिंग चर एक अच्छा अभ्यास है।


if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists
fi

यह पूरी तरह से सच नहीं है ... यदि आप उस निर्देशिका में जाना चाहते हैं, तो आपको निर्देशिका पर निष्पादन अधिकार भी होना चाहिए। शायद आपको लिखने के अधिकार भी होना चाहिए।

therfore:

if [ -d "$DIRECTORY" ] && [ -x "$DIRECTORY" ] ; then
    # ... to go to that directory (even if DIRECTORY is a link)
    cd $DIRECTORY
    pwd
fi
if [ -d "$DIRECTORY" ] && [ -w "$DIRECTORY" ] ; then
    # ... to go to that directory and write something there (even if DIRECTORY is a link)
    cd $DIRECTORY
    touch foobar
fi

if [ -d "$DIRECTORY" ]; then  
    # Here if $DIRECTORY exists  
fi




posix