پرسش و پاسخ شماره ۹۴ - آموزش اسکریپت نویسی
X
تبلیغات
رایتل

آموزش اسکریپت نویسی

آموزش اسکریپت نویسی پوسته گنو-لینوکس

#!/bin/bash

پرسش و پاسخ شماره ۹۴

پرسش و پاسخ شماره ۹۴

می‌خواهم وقتی دیسک پُر می‌شود یک هشدار دریافت کنم(با تجزیه خروجی df).

متأسفانه، تجزیه خروجی فرمان df واقعاً معتبرترین روش تعیین پر شدن کامل دیسک در اکثر سیستم‌عامل‌ها می‌باشد. به هر حال، لطفاً توجه نمایید که این کم ضررترین پاسخ است، نه بهترین جواب. تجزیه خروجی هر ابزار گزارش خط فرمانی هرگز خوش‌آیند نمی‌باشد. مقصود از این FAQ کوششی برای تشریح تمام مشکلات شناخته شده رویاروی این راهکار، و عبور موقت از آنها می‌باشد.

نخست، بزرگترین مشکل با df آن است که در تمام سیستم‌عامل‌ها به صورت یکسان کار نمی‌کند. یونیکس به طور عمده به دو خانواده تقسیم می‌شود-- ‎System V‎ و BSD. در سیستم‌های خانواده BSD(در این وضعیت، شامل لینوکس)، df یک گزارش قابل خواندن انسانی ارائه می‌کند:

  •  ~$ df
     Filesystem           1K-blocks      Used Available Use% Mounted on
     /dev/sda2              8230432   3894324   3918020  50% /
     tmpfs                   253952         8    253944   1% /lib/init/rw
     udev                     10240        44     10196   1% /dev
     tmpfs                   253952         0    253952   0% /dev/shm

در حالیکه، در سیستم‌های هم‌خانواده با ‎System-V‎، خروجی به طور کامل متفاوت است:

  •  $ df
     /net/appl/clin   (svr1:/dsk/2/clin/pa1.1-hpux10HP-UXB.10.20):  1301728 blocks            -1 i-nodes
     /net/appl/tool-share (svr2:/dsk/4/dsk3/tool/share): 51100992 blocks       4340921 i-nodes
     /net/appl/netscape (svr2:/dsk/4/dsk3/netscape/pa1.1-hpux10HP-UXB.10.20): 51100992 blocks       4340921 i-nodes
     /net/appl/gcc-3.3 (svr2:/dsk/4/dsk3/gcc-3.3/pa1.1-hpux10HP-UXB.10.20): 51100992 blocks       4340921 i-nodes
     /net/appl/gcc-3.2 (svr2:/dsk/4/dsk3/gcc-3.2/pa1.1-hpux10HP-UXB.10.20): 51100992 blocks       4340921 i-nodes
     /net/appl/tool   (svr2:/dsk/4/dsk3/tool/pa1.1-hpux10HP-UXB.10.20): 51100992 blocks       4340921 i-nodes
     /net/home/wooledg    (/home/wooledg       ):   658340 blocks     87407 i-nodes
     /net/home            (auto.home           ):        0 blocks         0 i-nodes
     /net/hosts           (-hosts              ):        0 blocks         0 i-nodes
     /net/appl            (auto.appl           ):        0 blocks         0 i-nodes
     /net/vol             (auto.vol            ):        0 blocks         0 i-nodes
     /nfs                 (-hosts              ):        0 blocks         0 i-nodes
     /home                (/dev/vg00/lvol5     ):   658340 blocks     87407 i-nodes
     /opt                 (/dev/vg00/lvol6     ):   623196 blocks     83075 i-nodes
     /tmp                 (/dev/vg00/lvol4     ):    86636 blocks     11404 i-nodes
     /usr/local           (/dev/vg00/lvol9     ):   328290 blocks     41392 i-nodes
     /usr                 (/dev/vg00/lvol7     ):   601750 blocks     80228 i-nodes
     /var                 (/dev/vg00/lvol8     ):   110696 blocks     14447 i-nodes
     /stand               (/dev/vg00/lvol1     ):   110554 blocks     13420 i-nodes
     /                    (/dev/vg00/lvol3     ):   190990 blocks     25456 i-nodes

بنابراین، اولین سد راه شما، تشخیص آن خواهد بود که ممکن است نسبت به آنکه با کدام سیستم عامل کار می‌کنید، دستور متفاوتی لازم داشته باشید(به عنوان مثال bdf در HP-UX)، و شاید سیستم‌هایی باشند که واقعاً در آنها انجام این کار با اسکریپت پوسته به هیچ وجه امکان‌پذیر نباشد.

برای بقیه این مبحث، ما فرض خواهیم نمود که شما سیستمی با فرمان df هم‌خانواده BSD در اختیار دارید.

مشکل بعدی آن است که قالب خروجی df در تمام سکوها(پلاتفرم‌ها) یکسان نمی‌باشد.بعضی سکوها از خروجی شش ستونی و برخی از هفت ستونی استفاده می‌کنند. برخی سکوها(مانند لینوکس)، موقع گزارش فضای واقعی استفاده شده یا در دسترس، به طور پیش‌فرض بلوک‌های یک کیلوبایتی به کار می‌برند، دیگران، مانند OpenBSD یا IRIX، به طور پیش‌فرض بلوک‌های 512 بایت را به کار می‌برند و برای استفاده از کیلوبایت‌ها گزینه ‎-k‎ را لازم دارند.

بدتر از آن، اغلب یک سطر خروجی در صفحه نمایش به چند سطر تقسیم خواهد شد. برای مثال(لینوکس):

  •  Filesystem           1K-blocks      Used Available Use% Mounted on
     ...
     svr2:/dsk/4/dsk3/tool/i686Linux2.4.27-4-686
                           35194552   7856256  25550496  24% /net/appl/tool

اگر نام دستگاه به اندازه کافی طولانی باشد(با فایل‌سیستم‌های متصل‌شده شبکه خیلی رایج است)، df ممکن است در کوشش برای حفظ خوانایی ستونها برای انسان، خروجی را به دو سطر تقسیم کند. یا شاید نکند...برای مثال، ‎OpenBSD 4.3‎ را ببینید:

  •  ~$ df
     Filesystem  512-blocks      Used     Avail Capacity  Mounted on
     /dev/wd0a       253278    166702     73914    69%    /
     /dev/wd0d      8121774   6904178    811508    89%    /usr
     /dev/wd0e      8121774   6077068   1638618    79%    /var
     /dev/wd0f       507230        12    481858     0%    /tmp
     /dev/wd0g      8121774   5653600   2062086    73%    /home
     /dev/wd0h    125253320 116469168   2521486    98%    /export
    
     ~$ sudo mount 192.168.2.5:/var/cache/apt/archives /mnt
     ~$ df
     Filesystem                          512-blocks      Used     Avail Capacity  Mounted on
     /dev/wd0a                               253278    166702     73914    69%    /
     /dev/wd0d                              8121774   6904178    811508    89%    /usr
     /dev/wd0e                              8121774   6077806   1637880    79%    /var
     /dev/wd0f                               507230        12    481858     0%    /tmp
     /dev/wd0g                              8121774   5653600   2062086    73%    /home
     /dev/wd0h                            125253320 116469168   2521486    98%    /export
     192.168.2.5:/var/cache/apt/archives    1960616   1638464    222560    88%    /mnt

اکثر نگارش‌های df گزینه ‎-P‎ را در اختیار شما قرار می‌دهند که به منظور میزان کردن خروجی است... نسبتاً. نگارش‌های قدیمی‌تر OpenBSD حتی موقعی که گزینه ‎-P‎ فراهم می‌شود، بازهم سطرهای خروجی را تقسیم می‌کنند، اما لینوکس به طور کلی خروجی برای هر فایل‌سیستم در یک سطر را تحمیل می‌کند.

بنابراین، اگر می‌خواهید اسکریپت نیرومندی بنویسید، نمی‌توانید فرض کنید خروجی برای یک فایل‌سیستم معین در یک سطر منفرد خواهد بود. ما بعداً به این مورد باز می‌گردیم.

شما مرتب بودن عمودی ستونها را نیز نمی‌توانید فرض نمایید:

  •  ~$ df -P
     Filesystem         1024-blocks      Used Available Capacity Mounted on
     /dev/hda1               180639     93143     77859      55% /
     tmpfs                   318572         4    318568       1% /dev/shm
     /dev/hda5                90297      4131     81349       5% /tmp
     /dev/hda2              5763648    699476   4771388      13% /usr
     /dev/hda3              1829190    334184   1397412      20% /var
     /dev/sdc1            2147341696 349228656 1798113040      17% /data3
     /dev/sde1            2147341696 2147312400     29296     100% /data4
     /dev/sdf1            1264642176 1264614164     28012     100% /data5
     /dev/sdd1            1267823104 1009684668 258138436      80% /hfo
     /dev/sda1            2147341696 2147311888     29808     100% /data1
     /dev/sdg1            1953520032 624438272 1329081760      32% /mnt
     /dev/sdb1            1267823104 657866300 609956804      52% /data2
     imadev:/home/wooledg   3686400   3336736    329184      92% /net/home/wooledg
     svr2:/dsk/4/dsk3/tool/i686Linux2.4.27-4-686  35194552   7856256  25550496      24% /net/appl/tool
     svr2:/dsk/4/dsk3/tool/share  35194552   7856256  25550496      24% /net/appl/tool-share

بنابراین، به طور واقعی چه کار می‌توانید بکنید؟

  • گزینه ‎-P‎ را به کار ببرید. حتی اگر همه چیز را ‎100%‎ سازگار نمی‌کند، به طور کلی آزاری ندارد. مطابق کُد منبع ‎df.c‎ در coreutils لینوکس، گزینه ‎ -P‎ تضمین می‌کند که خروجی در یک سطر منفرد خواهد بود(اما این فقط برای لینوکس است).

  • منطقه خود را به ‎C‎ تنظیم کنید. شما نیازی به سرآیند ستونهای غیر انگلیسی درهم پیچیده ندارید.

  • اگر معتبر است، استفاده از ‎"stat --file-system --format="‎ را در نظر بگیرید. اگر در موقعیت شما قابلیت حمل مسئله‌ای نیست، صفحه man فرمان stat را بررسی کنید. در سیستم‌های بسیاری قادر خواهید بود اندازه بلوک، تعداد کل بلوکهای دیسک، وتعداد بلوکهای آزاد، همگی در قالب تعیین شده کاربر، را چاپ کنید.

  • به طور صریح یک فایل‌سیستم را انتخاب نمایید. اگر نتایج مربوط به یک فایل‌سیستم را می‌خواهید از چنین دستوری ‎df -P | grep /dev/hda2‎ استفاده نکنید. نام یک شاخه یا یک دستگاه را به عنوان یک شناسه به فرمان df بدهید به این طریق فقط خروجی آن فایل‌سیستم را در مکان اول می‌بینید.

    •   ~$  df -P /
        Filesystem         1024-blocks      Used Available Capacity Mounted on
        /dev/sda2              8230432   3894360   3917984      50% /
  • شمارش کلمات خروجی بدون رعایت سطرهای‌جدید. این یک راه غلبه بر مشکل سطرهایی است که به طور غیرقابل پیش‌بینی تقسیم می‌شوند. برای مثال، استفاده از آرایه Bash با نام df_arr:

    •   ~$ read -d '' -ra df_arr < <(LC_ALL=C df -P /); echo "${df_arr[11]}"
        50%

    به طوری که می‌توانید ببینید، ما به سادگی تمامی خروجی را به داخل یک آرایه منفرد مکیدیم و سپس کلمه دوازدهم را گرفتیم(شمارش شاخص آرایه از صفر است). نگران آن نبودیم که آیا خروجی تقسیم شده یا خیر، به علت آنکه تعداد کلمات تغییر نمی‌کند.

حذف علامت درصد، مقایسه عدد با مرز تعیین شده، زمان‌بندی یک روش خودکار برای اجرای اسکریپت، و غیره. به عنوان تمرینهای شما واگذار گردید.


CategoryShell

پرسش و پاسخ 94 (آخرین ویرایش ‎2013-08-10 20:27:02‎ توسط nrbg-4dbfc8a9)