اسکریپت‌نویسی با سلیقه

فصل ‎35‎- اسکریپت‌نویسی با سلیقه

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

در ادامه چند رهنمود سبک شناسانه آمده است. این رهنمودها (ضرورتاً) مانند یک مجموعه تعاریف رسمی اسکریپت‌نویسی در نظر گرفته نمی‌شوند.


‎35.1‎- مجموعه تعاریف غیر رسمی اسکریپت‌نویسی پوسته

  • کدتان را توضیح بدهید. این کار، فهمیدن (و درک کردن) آن را برای سایرین روانتر و نگهداری آن را هم آسانتر می‌نماید.

  • PASS="$PASS${MATRIX:$(($RANDOM%${#MATRIX})):1}"
    # وقتی سال گذشته آن را نوشتید کاملاً قابل فهم بود،
    #+                  اما اکنون یک معمای کامل است.
    #   (از اسکریپت ‎pw.sh‎ نوشته ‎scriptAntek Sawicki‎)

    به توابع و اسکریپت خود سرآیندهای توضیح‌دهنده اضافه کنید.

    #!/bin/bash
    
    
    
    E_BADDIR=85                       #برای «چنین شاخه‌ای موجود نیست»‏.
    projectdir=/home/bozo/projects    # دایرکتوری برای انجام پاکسازی.
    
    # 
    # 
    #              # تمام فایل‌ها در دایرکتوری تعیین شده را پاک می‌کند.
    #                                  # پارامتر:   ‎$target_directory‎
    # # با موفقیت ‎0‎، و اگر چیزی اشتباه باشد ‎$E_BADDIR‎ را برگشت می‌دهد.
    # 
    cleanup_pfiles ()
    {
      if [ ! -d "$1" ]        # بررسی آنکه دایرکتوری مقصد موجود باشد.
      then
        echo "$1 is not a directory."
        return $E_BADDIR
      fi
    
      rm -f "$1"/*
      return 0                # موفقیت.
    }  
    
    cleanup_pfiles $projectdir
    
    exit $? 
    	

  • از به کار بردن «اعداد جادویی» ‎[1]‎ یعنی ثابت‌های لفظی «درج شده در کد» پرهیز کنید. به جای آن از نام‌های با معنی متغیرها استفاده کنید. این کار فهمیدن اسکریپت را آسان‌تر می‌سازد و اجازه می‌دهد تغییرات و به روزرسانی‌ها، بدون خراب کردن برنامه کاربردی انجام گردد.

  • if [ -f /var/log/messages ]
    then
      ...
    fi
    #  یک سال بعد، شما تصمیم به تغییر اسکریپت برای بازبینی ‎/var/log/syslog‎ می‌گیرید.
    #   اکنون لازم است به طور دستی، مورد به مورد اسکریپت را تغییر بدهید و امید داشته
    #+                                                 باشید که هیچ چیزی خراب نشود.
    
    #                                                               یک روش مناسب‌تر:
    LOGFILE=/var/log/messages                # تنها سطری که لازم است تغییر داده شود.
    if [ -f "$LOGFILE" ]
    then
      ...
    fi
    	

  • برای متغیرها و توابع نام‌های توصیفی انتخاب کنید.

  • fl=`ls -al $dirname`                 # مرموز و مبهم.
    file_listing=`ls -al $dirname`       #  مناسب‌تر است.
    
    
    MAXVAL=10                            #   نام ثابت‌ها تماماً با حروف بزرگ.
    while [ "$index" -le "$MAXVAL" ]
    ...
    
    
    E_NOTFOUND=95                        #     نام با حروف بزرگ و پیشوند ‎E_‎
                                         #+                 برای یک کد خطا.
    if [ ! -e "$filename" ]
    then
      echo "File $filename not found."
      exit $E_NOTFOUND
    fi  
    
    
    MAIL_DIRECTORY=/var/spool/mail/bozo  #     حروف بزرگ برای یک متغیرمحیطی
    export MAIL_DIRECTORY                
    
    
    GetAnswer ()                         # حروف مختلط به خوبی برای نام تابع
    {                                    #+  کار می‌کند، مخصوصاً وقتی خوانایی
      prompt=$1                          #+                 را بهبود می‌دهد.
      echo -n $prompt
      read answer
      return $answer
    }  
    
    GetAnswer "What is your favorite number? "
    favorite_number=$?
    echo $favorite_number
    
    
    _uservariable=23                     #     جایز است، اما توصیه نمی‌گردد.
    #         بهتر است نام متغیرهای تعریف شده کاربر با یک خط زیر شروع نشود.
    #                   آن را (خط زیر را) برای متغیرهای سیستم باقی بگذارید.
    	

  • به یک روش مرتب و معنادار از کدهای خروج استفاده نمایید.

  • E_WRONG_ARGS=95
    ...
    ...
    exit $E_WRONG_ARGS

    همچنین پیوست E را مشاهده نمایید.

    Ender پیشنهاد می‌کند از کدهای خروج داخل ‎/usr/include/sysexits.h‎ در اسکریپت‌ها استفاده گردد، اگر چه اینها اصولاً برای برنامه‌نویسی ‎C‎ و ‎C++‎ در نظر گرفته شده‌اند.

  • نشانه پارامترهای استاندارد شده را برای فراخوانی اسکریپت استفاده کنید. Ender مجموعه نشانه‌های زیر را پیشنهاد می‌دهد.

  • -a      All: Return all information (including hidden file info).
    -b      Brief: Short version, usually for other scripts.
    -c      Copy, concatenate, etc.
    -d      Daily: Use information from the whole day, and not merely
            information for a specific instance/user.
    -e      Extended/Elaborate: (often does not include hidden file info).
    -h      Help: Verbose usage w/descs, aux info, discussion, help.
            See also -V.
    -l      Log output of script.
    -m      Manual: Launch man-page for base command.
    -n      Numbers: Numerical data only.
    -r      Recursive: All files in a directory (and/or all sub-dirs).
    -s      Setup & File Maintenance: Config files for this script.
    -u      Usage: List of invocation flags for the script.
    -v      Verbose: Human readable output, more or less formatted.
    -V      Version / License / Copy(right|left) / Contribs (email too).
    	

    همچنین بخش ‎G.1‎ را هم مشاهده کنید.

  • اسکریپت‌های پیچیده را به پیمانه‌های کوچکتر خُرد کنید. جایی که مناسب است از توابع استفاده کنید. مثال ‎37-4‎ را ببینید.

  • در جایی که یک ساختار ساده‌تر کار خواهد کرد، از ساختار پیچیده استفاده نکنید.

  • COMMAND
    if [ $? -eq 0 ]
    ...
    ...
    fi
    # زاید و اضافی.
    
    if COMMAND
    ...
    ...
    fi
    # فشرده‌تر (گرچه ممکن است کاملا روشن نباشد)‏.
    	

 

... با خواندن کد منبع یونیکس برای پوسته بورن ‎(/bin/sh)‎. غافلگیر شده بودم که چگونه الگوریتم‌های بسیار ساده به وسیله انتخاب یک سبک نگارشی ضعیف کدنویسی می‌توانست مرموز و بنابراین بلااستفاده گردد. از خود پرسیدم، «آیا کسی می‌تواند از این کد سربلند باشد؟»

‎--Landon Noll‎

یادداشت‌ها

‎[1]‎

در این مضمون، «اعداد جادویی» دارای معنای کاملا متفاوت از ‎magic numbers‎ به کار رفته برای برگزیدن نوع فایل است.