unix تحقق من وجود دليل في برنامج نصي shell





15 Answers

تذكر دائمًا أن تقوم بلف المتغيرات في علامات اقتباس مزدوجة عند الرجوع إليها في برنامج نصي bash. يكبر الأطفال هذه الأيام بفكرة أنهم يمكن أن يكون لديهم مساحات والكثير من الشخصيات المضحكة الأخرى في أسماء الدليل الخاصة بهم. (مساحات! العودة في أيامي ، لم يكن لدينا أي مسافات الهوى! ؛))

يوم واحد ، سيقوم أحد هؤلاء الأطفال بتشغيل البرنامج النصي الخاص بك مع $DIRECTORY لتعيين "My M0viez" و "My M0viez" البرنامج النصي الخاص بك. أنت لا تريد ذلك لذلك استخدم هذا.

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

ما هو الأمر الذي يمكن استخدامه للتحقق من وجود دليل أم لا ، داخل نص برمجي shell؟




أجد أن الإصدار tldp.org/LDP/abs/html/testconstructs.html#DBLBRACKETS من test يجعل اختبارات الكتابة المنطقية أكثر طبيعية:

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



للتحقق من وجود دليل ، يمكنك استخدام بنية بسيطة مثل:

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 



يمكنك استخدام test -d (انظر man test ).

-d file صحيح إذا كان الملف موجودا وهو دليل.

فمثلا:

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

ملاحظة: الأمر test هو نفس التعبير الشرطي [ (انظر: man [ ) ، لذلك يكون محمولًا عبر برامج نصية shell.

[ - هذا مرادف لـ test builtin ، لكن يجب أن تكون الوسيطة الأخيرة ، حرفيًا ] ، لمطابقة الفتحة [ .

لمعرفة الخيارات الممكنة أو المساعدة الإضافية ، تحقق من:

  • help [
  • help test
  • man test أو man [



هنا تعبير براغماتي للغاية:

(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 داخل subshell ( ... ) ، لا يؤثر الأمر على الدليل الحالي للمتصل. إذا كان الدليل موجودًا ، فإن هذا المستند الفرعي والدالة هما مجرد إجراء.

التالي هو الوسيطة التي نمررها إلى cd : ${1:?pathname expected} . هذا هو شكل أكثر تفصيلاً لاستبدال المعلمات والذي يتم شرحه بمزيد من التفاصيل أدناه.

Tl؛ dr: إذا كانت السلسلة التي تم تمريرها إلى هذه الدالة فارغة ، فإننا نخرج مرة أخرى من subshell ( ... ) ونرجع من الدالة برسالة خطأ معينة.

نقلا عن صفحة رجل ksh93 :

${parameter:?word}

إذا تم تعيين parameter وهي غير فارغة ، فعليك استبدال قيمتها. خلاف ذلك ، قم بطباعة word والخروج من shell (إن لم يكن تفاعليًا). إذا تم حذف word فستتم طباعة رسالة قياسية.

و

إذا كانت النقطتين : تم حذفها من التعبيرات أعلاه ، فإن shell يقوم فقط بالتحقق من ضبط المعلمة أم لا.

الصياغة هنا غريبة على وثائق shell ، حيث قد تشير word إلى أي سلسلة معقولة ، بما في ذلك المسافات البيضاء.

في هذه الحالة بالذات ، أعلم أن رسالة الخطأ القياسية 1: parameter not set ليست كافية ، لذا أقوم بتكبير نوع القيمة التي نتوقعها هنا - pathname الدليل.

ملاحظة فلسفية: الصدفة ليست لغة موجهة للكائنات ، لذلك تقول الرسالة pathname ، وليس directory . في هذا المستوى ، سأفضل أن أبقيه بسيطًا - الحجج إلى الدالة هي مجرد سلاسل.




  1. برنامج نصي بسيط لاختبار ما إذا كان dir أو الملف موجودًا أم لا:

    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': الملف موجود




المزيد من الميزات باستخدام 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
    



للتحقق من أكثر من دليل واحد ، استخدم هذا الرمز:

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



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

ملاحظة: تعتبر متغيرات الاقتباس ممارسة جيدة.




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



باستخدام الاختيار -e سيتحقق من الملفات وهذا يتضمن الدلائل.

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



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

هذا ليس صحيحًا تمامًا ... إذا كنت تريد الانتقال إلى هذا الدليل ، يجب أن يكون لديك أيضًا حقوق التنفيذ في الدليل. ربما تحتاج إلى حقوق الكتابة كذلك.

الرسل:

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



file="foo" 
if [[ -e "$file" ]]; then echo "File Exists"; fi;



(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: not: not found [لا يوجد ملف أو دليل]




تجد أدناه يمكن استخدامها ،

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



Related