سؤال

فيما يلي ، سوف يعطي رمز shell غير المتقدم للغاية نقطة جبل $path:

 (for i in $(df|cut -c 63-99); do case $path in $i*) echo $i;; esac; done) | tail -n 1

هل هناك طريقة أفضل للقيام بذلك في شل؟

PostScript

هذا البرنامج النصي فظيع حقًا ، ولكن لديه جودة الاسترداد التي يعمل على أنظامي. لاحظ أن عدة نقاط التثبيت قد تكون بادئات من $path.

أمثلةعلى نظام Linux:

cas@txtproof:~$ path=/sys/block/hda1
cas@txtproof:~$ for i in $(df -a|cut -c 57-99); do case $path in $i*) echo $i;; esac; done| tail -1
/sys

على نظام Mac OSX

cas local$ path=/dev/fd/0
cas local$ for i in $(df -a|cut -c 63-99); do case $path in $i*) echo $i;; esac; done| tail -1
/dev

لاحظ الحاجة إلى تغيير معلمات القطع ، بسبب الطريقة التي يختلف بها إخراج DF ؛ يؤدي استخدام AWK إلى حل هذا ، ولكن حتى AWK غير قابل للحمل ، بالنظر إلى نطاق تنسيق النتائج المختلفة لعودة DF.

إجابهيبدو أن الناتج الجدولي المتهور هو الطريقة الوحيدة داخل القشرة ، ولكن

df -P "$path"  | tail -1 | awk '{ print $NF}'

استنادًا إلى إجابة GhostDog74 ، هو تحسن كبير على ما كان لدي. لاحظ مسألين جديدين: أولاً ، df $path يصر على ذلك $path أسماء ملف موجود ، فإن البرنامج النصي الذي كان لدي أعلاه لا يهتم ؛ ثانياً ، لا توجد تقلق بشأن تصادمات التخلص من الإخلاء. هذا لا يعمل إذا كان لديك نقاط تركيب مع مسافات فيها ، والتي تحدث إذا كان لدى المرء وسائط قابلة للإزالة مع مسافات في أسماء الحجم.

ليس من الصعب كتابة رمز بيثون للقيام بهذه المهمة بشكل صحيح.

هل كانت مفيدة؟

المحلول

df يأخذ المسار كمعلمة ، لذلك يجب أن يكون شيء من هذا القبيل قويًا إلى حد ما ؛

df "$path" | tail -1 | awk '{ print $6 }'

نصائح أخرى

نظريا stat سيخبرك بالجهاز الذي يعمل عليه الملف ، ويجب أن يكون هناك طريقة لتخطيط الجهاز إلى نقطة تثبيت.

على سبيل المثال ، على Linux ، يجب أن يعمل هذا:

stat -c '%m' $path

كان دائمًا من محبي استخدام خيارات التنسيق للبرنامج ، حيث يمكن أن يكون أكثر قوة من معالجة الإخراج (على سبيل المثال إذا كانت نقطة Mount Point تحتوي على مسافات). جنو df يسمح بما يلي:

df --output=target "$path" | tail -1

لسوء الحظ ، لا يوجد خيار يمكنني رؤيته لمنع طباعة رأس ، لذلك لا يزال الذيل مطلوبًا.

لا أعرف ماهية الإخراج المطلوب ، لذلك هذا تخمين

#!/bin/bash

path=/home
df | awk -v path="$path" 'NR>1 && $NF~path{
 print $NF
}'

إن استخدام CUT مع -C ليس موثوقًا به حقًا ، نظرًا لأن ناتج DF سيكون مختلفًا ، فإن 5 ٪ يمكن أن يتغير إلى 10 ٪ وسوف تفوتك بعض الشخصيات. نظرًا لأن Mount Point موجود دائمًا في الخلف ، يمكنك استخدام الحقول ومحددات المجال. في ما سبق ، $ nf هو العمود الأخير وهو نقطة جبل.

أود أن آخذ رمز المصدر إلى DF ومعرفة ما يفعله إلى جانب الاتصال stat كما يقترح دوغلاس ليدر.

تحليل خط على حدة df سيؤدي الإخراج إلى حدوث مشاكل كما تبدو هذه الخطوط في كثير من الأحيان

/dev/mapper/VOLGROUP00-logical--volume
                      1234567  1000000  200000  90% /path/to/mountpoint

مع التعقيد الإضافي لتحليل هذه الأنواع من الخطوط أيضًا ، ربما الاتصال stat وإيجاد نقطة الجبل أقل تعقيدًا.

mount | grep "^$path" | awk '{print $3}'

فاتني هذا عندما نظرت إلى أسئلة سابقة: Python: احصل على Mount Point على Windows أو Linux, الذي يقول ذلك os.path.ismount(path) يروي ما إذا كان المسار هو نقطة جبل.

تفضيلي هو حل قذيفة ، ولكن هذا يبدو بسيطًا جدًا.

انا استعمل هذا:

df -h $path | cut -f 1 -d " " | tail -1

Linux لديه هذا ، والذي سيتجنب مشكلة في المساحات:

lsblk -no MOUNTPOINT ${device}

لست متأكدا من الأرض BSD.

f () { echo $6; }; f $(df -P "$path" | tail -n 1)

إذا كنت ترغب في استخدام DF و AWK فقط للعثور على جهاز نظام الملفات/المشاركة عن بُعد أو نقطة تثبيت ، فإنها تتضمن مساحات يمكنك خداعها من خلال تحديد فاصل الحقل لـ AWK ليكون تعبيرًا منتظمًا يطابق تنسيق الأحجام الرقمية المستخدمة في عرض الحجم الكلي ، والمساحة المستخدمة ، والمساحة المتاحة والنسبة المئوية للسعة. من خلال تحديد تلك الأعمدة كفاصل الحقل ، تترك بعد ذلك $1 تمثيل جهاز نظام الملفات/المشاركة عن بُعد و $NF يمثل مسار الجبل.

خذ هذا على سبيل المثال:

[root@testsystem ~] df -P
Filesystem                       1024-blocks        Used Available Capacity Mounted on
192.168.0.200:/NFS WITH SPACES   11695881728 11186577920 509303808      96% /mnt/MOUNT WITH SPACES

إذا حاولت تحليل هذا مع سريع وقذرة awk '{print $1}' أو awk '{print $NF}' ستحصل فقط على جزء من نظام الملفات/مسار المشاركة عن بُعد ومسار MOTTL وهذا ليس جيدًا. الآن اجعل AWK استخدام أعمدة البيانات الرقمية الأربعة كفاصل الحقل.

[root@testsystem ~] df -P "/mnt/MOUNT WITH SPACES/path/to/file/filename.txt" | \
awk 'BEGIN {FS="[ ]*[0-9]+%?[ ]+"}; NR==2 {print $1}'
192.168.0.200:/NFS WITH SPACES

[root@testsystem ~] df -P "/mnt/MOUNT WITH SPACES/path/to/file/filename.txt" | \
awk 'BEGIN {FS="[ ]*[0-9]+%?[ ]+"}; NR==2 {print $NF}'
/mnt/MOUNT WITH SPACES

يتمتع :-)

تحرير: تستند هذه الأوامر إلى RHEL/CentOS/Fedora ولكن يجب أن تعمل على أي توزيع تقريبًا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top