آموزش‌های خط فرمانی

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

آموزش‌های خط فرمانی

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

نقل‌قول کردن

ادامه یادداشت قبل


2. نقل‌قولی کردن

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

اگر درک نکنید که تفکیک کلمه چطور کار می‌کند یا چه وقت اِعمال می‌شود، در استفاده از رشته‌ها و بسط پارامترها باید بسیار مراقب باشید. پیشنهاد می‌کنم اگر در مورد آگاهی خود تردید دارید،بیشتر در باره تفکیک کلمه مطالعه کنید.

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

    $ echo Push that word             away from me.
    Push that word away from me.
    $ echo "Push that word             away from me."
    Push that word             away from me.

حال، تصور نکنید که تفکیک کلمه برای فرو ریختن فاصله‌هاست. آنچه به طور واقعی در این مثال اتفاق می‌افتد، آنست که در مثال اول، هر یک از کلمات جمله ما به عنوان یک شناسه( argument) جداگانه به echo تحویل داده می‌شود. BASH جمله ما را به کلمات تجزیه می‌کند، از فضای سفید برای تعیین آن که هر شناسه از کجا شروع و به کجا ختم می‌گردد، استفاده می‌نماید. در مثال دوم BASH وادار شده تمام رشته نقل‌قولی شده را با هم نگاه دارد. به این معنا که به شناسه‌ها تفکیک نمی‌شوند و تمام رشته به عنوان یک شناسه به echo تحویل می‌شود. دستور echo همه شناسه‌هایی که به آن داده شود را با یک فاصله مابین آنها در خروجی چاپ می‌کند. اکنون باید اساس تجزیه کلمه را متوجه شده باشید.

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

    $ sentence="Push that word             away from me."
    $ echo $sentence
    Push that word away from me.
    $ echo "$sentence"
    Push that word             away from me.

به طوری که ملاحظه می‌کنید، در دستور echo اول، سهل‌انگاری کرده و نقل‌قول‌ها را از قلم انداخنه‌ایم. اشتباه بود. BASH جمله ما را بسط داده و سپس از تفکیک کلمه برای تجزیه نتیجه بسط به شناسه‌ها ‌جهت تحویل به echo استفاده نموده. در دومین مثال، نقل‌قول‌ها در اطراف بسط پارامتر جمله، اطمینان ایجاد می‌کند که BASH آن را به چندین شناسه پیرامون فضاهای سفید تجزیه نمی‌کند.

فقط فاصله‌ها نیستند که باید محافظت شوند. تفکیک کلمه در فاصله‌ها، tabها، سطر جدید، یا هر کاراکتر دیگری که در متغیر IFS باشد، صورت می‌گیرد. در اینجا مثال دیگری هست، که به شما نشان می‌دهد، چطور سهل‌انگاری در استفاده از نقل‌قول‌ها، موجب تجزیه نامناسبی می‌شود:

    $ echo "$(ls -al)"
    total 8
    drwxr-xr-x   4 lhunath users 1 2007-06-28 13:13 "."/
    drwxr-xr-x 102 lhunath users 9 2007-06-28 13:13 ".."/
    -rw-r--r--   1 lhunath users 0 2007-06-28 13:13 "a"
    -rw-r--r--   1 lhunath users 0 2007-06-28 13:13 "b"
    -rw-r--r--   1 lhunath users 0 2007-06-28 13:13 "c"
    drwxr-xr-x   2 lhunath users 1 2007-06-28 13:13 "d"/
    drwxr-xr-x   2 lhunath users 1 2007-06-28 13:13 "e"/
    $ echo $(ls -al)
    total 8 drwxr-xr-x 4 lhunath users 1 2007-06-28 13:13 "."/
	 drwxr-xr-x 102 lhunath users 9 2007-06-28 13:13 ".."/ -rw-r--r-- 1 lhunath users 0 2007-06-28 13:13 "a" -rw-r--r-- 1 lhunath users 0 2007-06-28 13:13 "b" -rw-r--r-- 1 lhunath users 0 2007-06-28 13:13 "c" drwxr-xr-x 2 lhunath users 1 2007-06-28 13:13 "d"/ drwxr-xr-x 2 lhunath users 1 2007-06-28 13:13 "e"/

در موقعیت‌های بسیار نادری ممکن است، صرفنظر از نقل‌قول‌ها مطلوب باشد. مواردی که شما نیاز به انجام تفکیک کلمه داشته باشید:

    $ friends="Marcus JJ Thomas Michelangelo"
    $ for friend in $friends
    > do echo "$friend is my friend!"; done
    Marcus is my friend!
    JJ is my friend!
    Thomas is my friend!
    Michelangelo is my friend!

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

    $ friends=( "Marcus The Rich" "JJ The Short" "Timid Thomas" "Michelangelo The Mobster" )
    $ for friend in "${friends[@]}"
    > do echo "$friend is my friend!"; done

توجه نمایید که در حلقه for قبلی، ما از ‎$friends‎ به شکلغیر نقل‌قولی استفاده کردیم. این کار BASH را برای جداکردن رشته friends به کلمات، مجاز می‌سازد. در مثال اخیر، بسط پارامتر${friends[@]}‎را نقل‌قولی کرده‌ایم . نقل‌قولی کردن یک آرایه با شاخص سراسری @ موجب می‌شود BASH آن آرایه را به صورت یک توالی از تمام عناصر که در آن هر یک در علامت نقل‌قول پیچیده شده، بسط بدهد.


ادامه دارد...
نظرات 0 + ارسال نظر
ایمیل شما بعد از ثبت نمایش داده نخواهد شد