كيف يمكنني التحقق من وجود دليل في نص برمجي لصدفة Bash؟

سئل على ١٢ سبتمبر ٢٠٠٨  ·  تمت مشاهدة 2.9M مرة  ·  مصدر

Grundlefleck picture
في ١٢ سبتمبر ٢٠٠٨

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

الإجابات

Grundlefleck picture
في ١٢ سبتمبر ٢٠٠٨
5294

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

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 في إجابة أخرى .

إذا كانت المتغيرات تحتوي على مسافات أو أحرف أخرى غير معتادة ، فمن المحتمل أن يتسبب ذلك في فشل البرنامج النصي.

8jean picture
في ١٦ سبتمبر ٢٠٠٨
544

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

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

if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists, even if it contains spaces
fi
Jon Ericson picture
في ١٢ سبتمبر ٢٠٠٨
236

لاحظ أن الاختبار -d يمكن أن ينتج عنه بعض النتائج المفاجئة:

$ ln -s tmp/ t
$ if [ -d t ]; then rmdir t; fi
rmdir: directory "t": Path component not a directory

الملف ضمن: "متى لا يكون الدليل دليلاً؟" الجواب: "عندما يكون رابطًا رمزيًا لدليل." اختبار أكثر شمولاً:

if [ -d t ]; then 
   if [ -L t ]; then 
      rm t
   else 
      rmdir t
   fi
fi

يمكنك العثور على مزيد من المعلومات في دليل Bash عن تعبيرات Bash الشرطية والأمر المدمج [ و المركب [[ .

yukondude picture
في ١٢ سبتمبر ٢٠٠٨
221

أجد أن إصدار الأقواس المزدوجة test يجعل كتابة اختبارات المنطق أمرًا طبيعيًا:

if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
    echo "It's a bona-fide directory"
fi
elmarco picture
في ١٢ سبتمبر ٢٠٠٨
165

شكل أقصر:

[ -d "$DIR" ] && echo "Yes"
Jorge Barroso picture
في ٨ أبريل ٢٠١٥
136

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

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
yoctotutor.com picture
في ١٥ مايو ٢٠١٨
127
  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
    

    ستتحقق البرامج النصية أعلاه مما إذا كان الدليل موجودًا أم لا

    $? إذا كان الأمر الأخير ناجحًا فإنه يُرجع "0" ، وإلا فإن القيمة غير الصفرية. افترض أن tempdir موجود بالفعل. ثم mkdir tempdir سيعطي خطأ كما يلي:

    mkdir: لا يمكن إنشاء الدليل "tempdir ": الملف موجود

kenorb picture
في ١٢ سبتمبر ٢٠١٥
94

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

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

فمثلا:

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

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

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

للحصول على خيارات محتملة أو مزيد من المساعدة ، تحقق من:

  • help [
  • help test
  • man test أو man [
Silly picture
في ١٧ أغسطس ٢٠٠٩
57

أو لشيء عديم الفائدة تمامًا:

[ -d . ] || echo "No"
Henk Langeveld picture
في ٩ أغسطس ٢٠١٢
55

إليكم مصطلح عملي للغاية:

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

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

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


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

${parameter:?word}

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

و

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

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

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

ملاحظة فلسفية:

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