معنى - كيف يمكنني معرفة ما إذا كان الملف العادي غير موجود في Bash؟
bash معنى (12)
أبسط طريقة
FILE=$1
[ ! -e "${FILE}" ] && echo "does not exist" || echo "exists"
https://code.i-harness.com
لقد استخدمت البرنامج النصي التالي لمعرفة ما إذا كان الملف موجودًا:
#!/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
أفضل القيام بما يلي أحادي الخطوط ، في تنسيق متوافق مع shell POSIX :
$ [ -f "/$DIR/$FILE" ] || echo "$FILE NOT FOUND"
$ [ -f "/$DIR/$FILE" ] && echo "$FILE FOUND"
بالنسبة إلى أمرين ، مثلما يمكنني فعله في نص برمجي:
$ [ -f "/$DIR/$FILE" ] || { echo "$FILE NOT FOUND" ; exit 1 ;}
بمجرد أن بدأت في القيام بذلك ، نادراً ما أستخدم تركيب الجملة المكتوب بالكامل!
تجدر الإشارة إلى أنه إذا كنت بحاجة إلى تنفيذ أمر واحد ، فيمكنك الاختصار
if [ ! -f "$file" ]; then
echo "$file"
fi
إلى
test -f "$file" || echo "$file"
أو
[ -f "$file" ] || echo "$file"
في
[ -f "$file" ]
[
الأمر هو stat()
(غير lstat()
) استدعاء النظام على المسار المخزن في $file
وإرجاع true إذا نجح ذلك استدعاء النظام ونوع الملف كما تم إرجاعها بواسطة stat()
هو "عادي".
لذا إذا عاد [ -f "$file" ]
إلى true ، فيمكنك أن تقول أن الملف موجود وأنه عبارة عن ملف عادي أو رابط يرمز إليه في النهاية إلى ملف عادي (أو على الأقل كان في وقت إصدار stat()
).
ولكن إذا كانت ترجع false (أو إذا كان [ ! -f "$file" ]
أو ! [ -f "$file" ]
بإرجاع true) ، فهناك العديد من الاحتمالات المختلفة:
- الملف غير موجود
- الملف موجود ولكن ليس ملف عادي
- الملف موجود ولكن ليس لديك إذن بحث إلى الدليل الأصل
- الملف موجود ولكن هذا المسار للوصول إليه طويل جدًا
- الملف عبارة عن رابط إلى ملف عادي ، ولكن ليس لديك إذن بحث لبعض الدلائل المتضمنة في حل الشفرة.
- ... أي سبب آخر قد يفشل استدعاء النظام
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
(يخبرنا 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
يقول لي على الأقل أنه ليس بسبب عدم وجود الملف الذي يفشل. لأنه لا يمكنه معرفة ما إذا كان الملف موجودًا أم لا. الأمر [
تجاهل المشكلة فقط.
باستخدام shell zsh
، يمكنك الاستعلام عن رمز الخطأ المتغير الخاص $ERRNO
بعد فشل الأمر [
، وفك ترميز ذلك باستخدام الصفيف الخاص $errnos
في الوحدة النمطية zsh/system
:
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
(حذار دعم $errnos
مع بعض إصدارات zsh
عند إنشاء الإصدارات الأخيرة من gcc
).
قد يكون الشيء test
أيضا. عملت لي (استناداً إلى Bash Shell: ملف التحقق موجود أو غير موجود ):
test -e FILENAME && echo "File exists" || echo "File doesn't exist"
لاختبار وجود الملف ، يمكن أن تكون المعلمة أيًا مما يلي:
-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
هذا الرمز يعمل أيضا.
#!/bin/bash
FILE=$1
if [ -f $FILE ]; then
echo "File '$FILE' Exists"
else
echo "The File '$FILE' Does Not Exist"
fi
هناك ثلاث طرق مميزة للقيام بذلك:
قم بإلغاء حالة الخروج مع bash (لم يرد أي إجابة أخرى):
if ! [ -e "$file" ]; then echo "file does not exist" fi
أو:
! [ -e "$file" ] && echo "file does not exist"
قم بإبطال الاختبار داخل أمر الاختبار
[
(هذه هي الطريقة التي تقدم بها معظم الإجابات قبل تقديمها):if [ ! -e "$file" ]; then echo "file does not exist" fi
أو:
[ ! -e "$file" ] && echo "file does not exist"
التصرف بناءً على نتيجة الاختبار السلبية (
||
بدلاً من&&
):فقط:
[ -e "$file" ] || echo "file does not exist"
هذا يبدو سخيفًا (IMO) ، لا تستخدمه ما لم يكن رمزك محمولًا إلى غلاف Bourne (مثل
/bin/sh
لـ Solaris 10 أو ما قبله) التي تفتقر إلى عامل إلغاء خط أنابيب (!
):if [ -e "$file" ]; then : else echo "file does not exist" fi
يحتوي الأمر test ( [
هنا] على عامل تشغيل منطقي "غير" وهو نقطة التعجب (على غرار العديد من اللغات الأخرى). جرب هذا:
if [ ! -f /tmp/foo.txt ]; then
echo "File not found!"
fi
يعمل هذا البرنامج النصي shell أيضاً للبحث عن ملف في دليل:
echo "enter file"
read -r a
if [ -s /home/trainee02/"$a" ]
then
echo "yes. file is there."
else
echo "sorry. file is not there."
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
- تحقق ما إذا كان الملف حجم غير صفري
-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"
من المحتمل أيضًا أن يكون الملف عبارة عن رابط رمزي معطل ، أو ملف غير منتظم ، على سبيل المثال ، مقبس أو جهاز أو جهاز fifo. على سبيل المثال ، لإضافة علامة اختيار للارتباطات symlinks المعطلة:
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