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




unix posix (24)

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


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

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

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

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

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

छोटा रूप:

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

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

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 

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

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

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

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

if [ -d "$DIRECTORY" ]; then
  # Control will enter here if $DIRECTORY exists.
fi

या यह जांचने के लिए कि कोई निर्देशिका मौजूद नहीं है या नहीं:

if [ ! -d "$DIRECTORY" ]; then
  # Control will enter here if $DIRECTORY doesn't exist.
fi

हालांकि, जैसा कि जॉन एरिक्सन बताते हैं, बाद के आदेश इरादे से काम नहीं कर सकते हैं यदि आप इस बात पर ध्यान नहीं देते हैं कि निर्देशिका के लिए एक प्रतीकात्मक लिंक भी इस चेक को पास करेगा। जैसे यह चल रहा है:

ln -s "$ACTUAL_DIR" "$SYMLINK"
if [ -d "$SYMLINK" ]; then 
  rmdir "$SYMLINK" 
fi

त्रुटि संदेश उत्पन्न करेगा:

rmdir: failed to remove `symlink': Not a directory

इसलिए प्रतीकात्मक लिंक अलग-अलग इलाज किए जा सकते हैं, यदि बाद के आदेश निर्देशिकाओं की अपेक्षा करते हैं:

if [ -d "$LINK_OR_DIR" ]; then 
  if [ -L "$LINK_OR_DIR" ]; then
    # It is a symlink!
    # Symbolic link specific commands go here.
    rm "$LINK_OR_DIR"
  else
    # It's a directory!
    # Directory command goes here.
    rmdir "$LINK_OR_DIR"
  fi
fi

चर को लपेटने के लिए इस्तेमाल किए गए डबल-कोट्स का विशेष नोट लें, इसका कारण 8jean द्वारा किसी अन्य उत्तर में समझाया गया है।

यदि चरों में रिक्त स्थान या अन्य असामान्य वर्ण होते हैं तो यह शायद स्क्रिप्ट को विफल कर देगा।


यह उत्तर एक शेल स्क्रिप्ट के रूप में लपेटा गया है

उदाहरण

$ is_dir ~                           
YES

$ is_dir /tmp                        
YES

$ is_dir ~/bin                       
YES

$ mkdir '/tmp/test me'

$ is_dir '/tmp/test me'
YES

$ is_dir /asdf/asdf                  
NO

# Example of calling it in another script
DIR=~/mydata
if [ $(is_dir $DIR) == "NO" ]
then
  echo "Folder doesnt exist: $DIR";
  exit;
fi

is_dir

function show_help()
{
  IT=$(CAT <<EOF

  usage: DIR
  output: YES or NO, depending on whether or not the directory exists.

  )
  echo "$IT"
  exit
}

if [ "$1" == "help" ]
then
  show_help
fi
if [ -z "$1" ]
then
  show_help
fi

DIR=$1
if [ -d $DIR ]; then 
   echo "YES";
   exit;
fi
echo "NO";

जांचें कि निर्देशिका मौजूद है या नहीं, और एक बनाओ

[ -d "$DIRECTORY" ] || mkdir $DIRECTORY

(1)

[ -d Piyush_Drv1 ] && echo ""Exists"" || echo "Not Exists"

(2)

[ `find . -type d -name Piyush_Drv1 -print | wc -l` -eq 1 ] && echo Exists || echo "Not Exists"

(3)

[[ -d run_dir  && ! -L run_dir ]] && echo Exists || echo "Not Exists"

अगर ऊपर दिए गए दृष्टिकोण में से एक के साथ कोई समस्या मिली है।

ls कमांड के साथ; वे मामले जब निर्देशिका मौजूद नहीं है - एक त्रुटि संदेश दिखाया गया है

$ [[ ls -ld SAMPLE_DIR| grep ^d | wc -l ls -ld SAMPLE_DIR| grep ^d | wc -l ls -ld SAMPLE_DIR| grep ^d | wc -l -eq 1]] && echo मौजूद है || अस्तित्व में नहीं है- ksh: नहीं: नहीं मिला [ऐसी कोई फ़ाइल या निर्देशिका नहीं]


एक से अधिक निर्देशिका जांचने के लिए इस कोड का उपयोग करें:

if [ -d "$DIRECTORY1" ] && [ -d "$DIRECTORY2" ] then
    # Things to do
fi

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

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

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

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

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

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

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

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

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

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


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

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

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
    

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

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

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


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

(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 ~/Desktop/TEMPORAL/ ] && echo "DIRECTORY EXISTS" || echo "DIRECTORY DOES NOT EXIST"

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

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

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

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


मुझे test के tldp.org/LDP/abs/html/testconstructs.html#DBLBRACKETS संस्करण को लेखन तर्क परीक्षण अधिक प्राकृतिक बनाता है:

if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
    echo "It's a bona-fide directory"
fi

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

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

if [ -d "$DIRECTORY" ]; then  
    # Here if $DIRECTORY exists  
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 स्थिति से बाहर निकल जाएगा, जिससे आपके ब्लॉक को निष्पादित करने की अनुमति मिल जाएगी।


  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' नहीं बना सकता: फ़ाइल मौजूद है


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




posix