فهرست مطالب
BASH دستورات را از ورودی( که میتواند ترمینال یا یک فایل باشد ) میخواند. با هر سطری که میخواند به عنوان یک دستور رفتار میکند -- یک دستورالعمل که باید انجام بشود(چند حالت پیشرفتهتری از قبیل دستوراتی که سطرهای چندتایی را دربرمیگیرند، موجود است، اما در حال حاضر نگران آنها نمیباشیم.)
BASH هر سطر را از محل هرکاراکتر فضای سفید( فاصله و Tab ) به کلمهها تقسیم میکند. اولین کلمهای که پیدا میکند نام دستوری است که باید اجرا شود. تمام کلمات باقیمانده شناسهها برای دستور تلقی میگردند(گزینهها، نام فایلها و غیره).
فرض کنیم شما در یک دایرکتوری خالی هستید. (اگر میخواهید این کد را امتحان کنید میتوانید دایرکتوری به نام
$ ls # | لیست فایلها در دایرکتوری جاری(بدون خروجی: فایلی موجود نیست). |
$ touch a b c # | فایلهای 'a' و 'b' و 'c' را ایجاد میکند. |
$ ls # | دوباره لیست فایلها، این دفعه در خروجی سه فایل ایجاد شده نمایش داده میشود. |
|
touchیک برنامه کاربردی است که زمان آخرین ویرایش یک فایل معین را به زمان حال تغییر میدهد. اگر فایل نامبرده در حال حاضر موجود نباشد، به سادگی آن را، به عنوان یک فایل جدید خالی ایجاد میکند . در این مثال، ما سه شناسه به آن دادهایم. touch برای هر یک از آنها یک فایل ایجاد میکند. فرمان ls سه فایل ایجاد شده را به ما نشان میدهد.
$ rm * # | تمام فایلهای دایرکتوری فعلی را حذف میکند |
$ ls | |
$ # | لیست فایلهای دایرکتوری جاری(فایل موجود نیست) |
$ touch a b c # | فایلهای a و b و c را ایجاد میکند |
$ ls # | دوباره لیست فایلها، این دفعه فایلهای a و b و c در خروجی نمایش داده میشود. |
rm ابزاری برای حذف فایلهایی میباشد که به عنوان شناسه به آن داده شدهاند.
حالا توجه نمودید که بین a و b و همچنین مابین b و c چند تا فاصله وجود داشت؟ همینطور نیز متوجه شدید که نتیجه، یعنی فایلهای ایجاد شده توسط touch با دفعه قبل که فقط یک فاصله بین آنها بود تفاوتی ندارد. حال آگاه شدید که تعداد فضاهای سفید بین شناسهها اهمیت ندارد. دانستن این مطلب با اهمیت است. برای مثال:
$ echo This is a test.This is a test. $ echo This is a test.This is a test.
echo دستوری است که شناسههایش را در خروجی استاندارد (که در این حالت ترمینال است) مینویسد. در این مثال، ما دستور echo را با چهار شناسه به کار بردهایم: 'This'و 'is'و 'a' و 'test.' که فرمان echo این شناسهها را میگیرد، وآنها را یک به یک با یک فاصله مابین آنها در خروجی چاپ میکند. در حالت دوم دقیقاً همان اتفاق رخ میدهد. فاصلههای اضافی تفاوتی ایجاد نمیکنند. اگر واقعاً فاصلههای اضافی را خواسته باشیم، لازم است جمله را به صورت یک شناسه منفرد به آن بدهیم. میتوانیم این کار را با استفاده از نقلقولها انجام بدهیم:
$ echo "This is a test."This is a test.
نقلقولها هر چیز در داخلشان را به صورت یک شناسه منفرد بستهبندی میکنند. این شناسه منفرد 'This is a test.' میباشد، با فاصلههای صحیح. توجه داشته باشید که نقلقولها بخشی از شناسه نیستند، BASH قبل از تحویل شناسه به فرمان echo آنها را حذف میکند. echoاین شناسه منفرد را درخروجی چاپ میکند، درست مانند آنچه همیشه انجام میدهد
در اجتناب از موارد ذیل دقیق باشید:
$ ls # | لیست فایلهای دایرکتوری جاری. |
| |
$ rm The secret voice in your head.mp3 # | فرمان rm را با 6 شناسه اجرا میکند، نه با یکی! |
| |
$ ls # | لیست فایلهای دایرکتوری جاری: فایل مورد نظر هنوز آنجاست. |
| اما فایل secret شما حالا دیگر نیست! |
شما باید در محصور کردن صحیح نام فایل با علائم نقلقول دقیق باشید. اگر محتاط نباشید، فایلهای اشتباهی را حذف خواهید نمود! فرمان rm نام فایلها را به عنوان شناسه میپذیرد. اگر نامهایی که در آنها کاراکتر فاصله وجود دارد را نقلقولی نکنید، rm فکر میکند که هر شناسه یک نام فایل است. نظر به اینکه BASH شناسهها را از محل فضای سفید تفکیک میکند، rm سعی خواهد نمود هر کلمه را به طور جداگانه حذف کند. در مثال فوق، به جای نام فایل صوتی، سعی کرده هر یک از کلمات موجود در نام فایل مورد نظر را حذف نماید. این موجب گردیده فایل secret ما حذف گردد، و فایل صوتی را پشت سر باقی بگذارد!
شناسهها از نام دستور و از یکدیگر نسبت به فضای سفید( فاصله، Tab، و سطر جدید) جدا میشوند. به خاطر سپردن این مطلب اهمیت دارد، برای مثال، مورد زیر اشتباه است:
$ [-f file]
شما میخواهید دستور [ از شناسههای
$ [-f file ]
( ما فرمان [ را در آینده مفصلتر شرح خواهیم داد. افراد زیادی را دیدهایم که با آن سر در گم شدهاند، و گمان بردهاند که میتوان از فضای سفید میان آن و شناسههایش صرفنظر نمود، بنابراین،
و البته اگر نام فایل شما شامل فضای سفید و یا دیگر کاراکترهای خاص باشد، باید نقلقولی بشود:
$ [ -f "my file" ]
توجه: لطفاً اگر هنوز مطلب برای شما خیلی واضح نیست، از شناسهها، نقلقولها، تفکیک کلمه و http://wiki.bash-hackers.org/syntax/words دید خوبی در این موارد حاصل نمایید. این مهم است که شما قبل از ادامه این راهنما، درک مناسبی از اینکه شل دستوراتی را که به آن میدهید چگونه تفسیر میکند، داشته باشید.
تکرار مفید:
شما باید همواره جملهها و رشتههایی که مرتبط با یکدیگر هستند، حتی اگر به طور قطعی ضرورت ندارد، را نقلقولی کنید. این شما را گوش به زنگ نگاه میدارد و ریسک خطای انسانی در اسکریپتها را کاهش میدهد.
برای مثال، همیشه باید شناسههای فرمان echo را نقلقولی کنید.
در پرسش و پاسخهای رایج:
من سعی میکنم یک فرمان را در متغیری قرار دهم، اما همیشه در حالتهای پیچیدهتر شکست میخورم!
چگونه میتوانم شناسههای( گزینههای ) خطفرمان را به آسانی مدیریت کنم؟
شناسهها: اینها کلمات اختیاری اضافهای هستند که میتوانید موقع اجرای فرمانها تعیین کنید. آنها پس از نام فرمانها آورده میشوند('ls -l foo' فرمان ls را با دو شناسه اجرا میکند).
نقلقولها: دو نوع نقلقول( ' و ") برای محافظت از کاراکترهای خاص معین در داخل عبارت نقلقولی، از تفسیر شدن به عنوان کاراکتر خاص توسط BASH، استفاده میکنیم. تفاوت بین
BASH چند نوع مختلف از دستورات را شناسایی میکند: مستعارها، توابع، دستورات داخلی، کلمات کلیدی، و اجراییها.
مستعارها: مستعارها روشی برای کوتاه نمودن دستورات است. اینها فقط در پوستههای محاورهای به کار میروند، نه در اسکریپتها. ( این یکی از معدود تفاوتهای یک اسکریپت و یک پوسته محاورهای میباشد.) مستعار یک نام کوتاه شده برای یک رشته معین است. موقعی که آن نام به عنوان یک دستور استفاده شود، قبل از اینکه فرمان اجرا گردد، نام با رشته جایگزین میگردد. بنابراین به جای آن اجرا میگردد:
$ nmap -P0 -A --osscan_limit 192.168.0.1
میتوانید از یک مستعار به این شکل استفاده کنید:
$ alias nmapp='nmap -P0 -A --osscan_limit' $ nmapp 192.168.0.1
قدرت مستعارها محدود است، جایگزینی فقط در اولین کلمه رخ میدهد. اگر قابلیت انعطاف بیشتری میخواهید، از یک تابع استفاده کنید. مستعارها فقط به عنوان میانبرهای متنی مفید میباشند.
دستورات داخلی: BASH تعدادی دستور اصلی در ساختمان خودش دارد، از قبیل cd (تغییر دایرکتوری)، echo (نوشتن خروجی)، وغیره. میتوانید آنها را به عنوان توابعی که از قبل فراهم شدهاند در نظر بگیرید.
کلمات کلیدی: کلمههای کلیدی کاملاً مانند دستورات داخلی میباشند، فقط اختلاف اصلی آنها درقواعد تجزیه ویژه در نظر گرفته شده برای آنها میباشد. برای مثال، [ یک دستور داخلی است، در حالیکه
$ [ a< b ]-bash: b: No such file or directory $[[ a< b ]]
مثال اول یک خطا باز میگرداند، زیرا bash سعی میکند فایل b را به دستور [ a ] تغییر مسیر بدهد(بخش تغییر مسیر فایل را ملاحظه کنید) مثال دوم به طور واقعی آنچه شما انتظار دارید انجام میدهد. کاراکتر
اجراییها: آخرین نوع دستوری که میتواند توسط bash اجرا بشود، یک دستور اجرایی است، که همچنین یک دستور خارجی یا برنامهکاربردی نیز نامیده میشود. اجراییها با استفاده از نام مسیر فراخوانی میشوند. اگر فایل اجرایی در دایرکتوری جاری است، به صورت
برای اندکی آسانتر نمودن زندگی شما، بههرحال، BASH از متغیری استفاده میکند، که بگوید در مواقعی که شما فقط نام برنامه کاربردی را میدانید و نه نام مسیرکامل آنرا، در کجا برنامه را پیدا کند. این متغیر
نکته:
میتوانید از فرمان type برای پیبردن به نوع یک فرمان استفاده کنید.
به عنوان مثال:
$ type rmrm is hashed (/bin/rm) $ type cdcd is a shell builtin
در مستندات گنو: دستورات ساده
در پرسش و پاسخهای رایج:
تفاوت بین test و [ و
چگونه میتوانم مستعاری ایجاد کنم که یک شناسه دریافت کند؟
مستعارها: یک نام که به یک رشته نسبت داده شده است. موقعی که نام به عنوان یک فرمان به کار برود، با رشته نسبت داده شده تعویض میگردد.
تابع: یک نام که به یک مجموعه از دستورات نسبت داده شده است . وقتی که نام به عنوان یک دستور استفاده شود، تابع با شناسههای به کار رفته در خطفرمان ، فراخوانی میشود. توابع روش اصلی برای ایجاد فرمانهای جدید هستند.
دستورات داخلی: فرمانهای معینی که در داخل BASH ساخته شدهاند. اینها موقعی که در خطفرمان اجرا شوند به طور داخلی اجرا میشوند( و پردازش جدیدی ایجاد نمیکنند ).
برنامههای کاربردی: یک برنامه که میتواند با ارجاع به نام مسیر آن اجرا شود(
یک اسکریپت اساساً یک سلسله دستورات در داخل یک فایل است. BASH فایل را میخواند و دستورات را به ترتیب پردازش میکند. فقط وقتی به دستور بعدی میرود که اجرای دستور فعلی به پایان رسیده باشد، مگر اینکه دستور جاری به طور غیر همزمان اجرا گردیده باشد( در پسزمینه ). در مورد حالت اخیر خیلی نگران نباشید، در آینده بیشتر در باره آن خواهید آموخت.
در واقع هر مثالی که در این راهنما ملاحظه میکنید، دقیقاً میتواند به همان خوبی خطفرمان در اسکریپتها به کار برده شود.
ساخت یک اسکریپت آسان است. شما فقط یک فایل جدید بسازید و جمله زیر را در ابتدای آن قرار دهید:
#! /usr/bin/env bash
این سرآیند اطمینان ایجاد میکند که هرگاه اسکریپت اجرا شود، BASH به عنوان مفسر آن به کار خواهد رفت. ( روشهای معتبر دیگری نیز برای انجام این امر وجود دارد.) کاراکترهای
لطفاً با مثالهای موجود در اینترنب که از
همچنین، خواهشمند است از دادن پسوند گمراه کننده
و در ضمن اگر از Windows برای نوشتن اسکریپتهایتان استفاده میکنید، در هرحال از کاربرد Notepad برای نوشتن اسکریپت اجتناب نمایید. Microsoft Notepad فقط میتواند فایلهای با انتهای سطر به روش DOS ایجاد نماید. یعنی هر سطری که در notepad ایجاد میکنید با دو کاراکتر خاتمه مییابد: یک کاراکتر رفتن سر سطر و یک کاراکتر سطرجدید. BASH فقط سطرهایی که به یک کاراکتر سطرجدید خاتمه مییابند را میخواند. در نتیجه، کاراکتر رفتن سرسطرCarriage Return وقتی که نمیدانید آنجا هست باعث دردسر باور نکردنی شما خواهد شد( پیغام خطاهای خیلی مرموز). در هر حالت ازویرایشگر محبوبی مانند Vimو Emacsو kate و GEdit و GVIM یا xemacs استفاده کنید. اگر چنین نکنید، بعد قبل از اجرای اسکریپت لازم است تمام کاراکترهای CR( رفتن سرسطر) را پاک کنید.
وقتی که اسکریپت شما آماده شد، میتوانید آن را به صورت زیر اجرا کنید:
$ bash myscript
در این مثال، ما BASH را اجرا کرده و به او میگوییم اسکریپت ما را بخواند، سطر
به طور جایگزین میتوانید به اسکریپت خود مجوزهای اجرا بدهید. موفعی که این کار را انجام دهید، به جای فراخوانی BASH به طور دستی، میتوانید اسکریپت را به طور واقعی به عنوان یک برنامه کاربردی اجرا نمایید:
$ chmod +x myscript $ ./myscript
موقعی که اسکریپت به این روش اجرا میشود، سطر
بعضیها مایل هستند اسکریپتهای خود را در یک دایرکتوری شخصی نگهداری نمایند. دیگرانی مایل میباشند اسکریپتهایشان را در محلی که در متغیر
$ mkdir-p "$ HOME /bin" $ echo 'PATH=" /bin:$ HOME$ PATH "'>> "$ HOME /.bashrc" $ exec bash
دستور اول، دایرکتوری با نام
تغییرات در DotFiles (از قبیل
در هر حال، اکنون میتوانیم اسکریپت خودمان را در دایرکتوری
$ mv myscript "$ HOME /bin" $ myscript
نکته:
وقتی شما در سرآیند اسکریپت نوع مفسر را تعیین میکنید، همچنین میتوانید زمان کوتاهی را برای شرح دادن عملکرد اسکریپت و شناسههای مورد نیاز آن صرف کنید:
#! /usr/bin/env bash # # شناسه ها نام اسکریپت # # .توضیح کوتاهی در تشریح هدف اسکریپت # # Copyright [date], [name]
نکته:
میتوانید سرآیند را با یک کلمه از شناسههای اختیاری که میخواهید به مفسر ارسال کنید به کار ببرید. به عنوان مثال، شناسههای زیر اشکالزدایی تفصیلی را فعال میکنند:
#! /bin/bash-xv
لیکن دانستن آنکه Bash کجا نصب گردیده، لازم است، و همیشه هم در
#! /usr/bin/env bash-xv
به علت آنکه برای آن، دو کلمه در سرآیند لازم است. یونیکس آن را اجازه نمیدهد.میتوانید به جای آن اینطور بنویسید:
#! /usr/bin/env bash set -xv
برای جزئیات بیشتر بخش اشکالزدایی را ملاحظه کنید.
سرآیند: سرآیند یک اسکریپت برنامه کاربردی که به عنوان مفسر عمل خواهد نمود، را تعیین میکند( ماننذ bash و sh و perl و ...). به طور مصطلح یک shebang نیز نامیده میشود-- یک عبارت عامیانه که از ترکیب hash (