منبع اصلی نوشتار زیر در این لینک قرار دارد

آموزش بش اسکریپت (قسمت اول)

بش اسکریپت که شل اسکریپت نیز نامیده می‌شود, یک زبان برنامه نویسی ساده و در عین حال جالب است که دستورات گنو/لینوکس را در یک فایل متنی توسط تعدادی syntax کنترل می‌کند. در این آموزش راجع به درک شل اسکرپیت, نحوه‌ی ساخت فایل متنی, اجرایی کردن آن و آشنایی با اصطلاحات بش و کار با آن‌ها صحبت می‌کنیم و باید بدانید این آموزش فقط گذری مختصر بر روی بش است.

 

شما باید ویرایشگری که با آن قصد برنامه نویسی را دارید انتخاب کنید که می‌توانید از ویرایشگرهای تحت خط فرمان مانند vim و nano یا از ویرایشگر‌های گرافیکی مانند gedit و atom استفاده کنید در قدم بعدی باید بدانید که از چه نسخه‌ی بش استفاده می‌کنید برای این کار کافی است دستور زیر را در ترمینال وارد کنید :

bash $BASH_VERSION

که خروجی مانند زیر خواهد داشت :

[hossein@hossein ~]$ bash $BASH_VERSION
bash: 4.3.42(1)-release

در حال حاضر آخرین نسخه‌ ۴.۳.۴۲ می‌باشد پس از آپدیت بودن ورژن بش خود اطمینان حاصل فرمایید. اکنون نوبت به ساخت فایل متنی رسیده, هر اسکریپتی که نوشته می‌شود نسبت به زبان خود قالبی دارد برای مثال قالب اسکریپت‌هایی که با زبان پایتون نوشته می‌شوند py هستند, قالب فایل‌های بش هم sh است اما شما می‌توانید یک فایل متنی بدون هیچ قالبی درست کنید و سپس آن را مستقیم اجرا کنید که در ادامه راجع به آن صحبت می‌کنیم اکنون با دستور زیر یک فایل متنی ایجاد کنید :

touch name_of_your_file

به جای name_of_your_file کلمه‌ای دیگر به عنوان نام اسکریپت بگذارید برای مثال من نام اسکریپت خود را pac می‌گذارم و ادامه‌ی آموزش را طبق این نام پیش می‌بریم . تمام اسکریپت‌هایی که به زبان بش نوشته شده‌اند با

#!/bin/bash

شروع می‌شوند پس در ابتدا‌ی فایل متنی خود باید این عبارت را بنویسید. هر چیزی که شما بعد از این عبارت بنویسید عملیاتی است که اسکریپت شما انجام می‌دهد برای مثال کلمه‌ی echo برای نشان دادن  یک عبارت یا نوشتن چیزی استفاده می‌شود و ما می‌توانیم از آن در اسکریپت خود استفاده کنیم :

#!/bin/bash
echo "Hello shell scripting!"

اسکریپت بالا باید Hello Shell Scripting را نشان دهد پس به آن اجازه‌ی اجرا شدن میدهیم برای اینکار دستور زیر را وارد کنید :

sudo chmod u+x pac

اکنون ما به اسکریپت خود که pac نام داشت قابلیت اجرا شدن دادیم برای اینکه مطمئن شویم دستور ls -lthr را وارد می‌کنیم که خروجی آن مانند زیر خواهد بود :

[hossein@hossein ~]$ ls -lthr
total 52K
drwxrwxrwx 2 hossein users 4.0K Nov  4 21:45 Telegram
drwxrwxrwx 2 hossein users 4.0K Nov 28 17:15 Templates
drwxrwxrwx 2 hossein users 4.0K Nov 28 17:15 Public
drwxrwxrwx 5 hossein users 4.0K Nov 29 16:51 Movies
drwxrwxrwx 4 hossein users 4.0K Dec  2 17:12 VirtualBox VMs
drwxrwxrwx 2 hossein users 4.0K Dec  2 17:41 Desktop
-rwxrw-r-- 1 hossein users  1 Dec  3 16:37 pac
drwxrwxrwx 4 hossein users 4.0K Dec  3 20:23 Pictures
drwxrwxrwx 4 hossein users 4.0K Dec  4 06:38 Downloads
drwxrwxrwx 2 hossein users 4.0K Dec  4 07:01 Videos
drwxrwxrwx 4 hossein users 4.0K Dec  4 07:02 Music
drwxrwxrwx 2 hossein users 4.0K Dec  4 07:09 Documents

همان‌طور که می‌بینید در خروجی بالا تمام محتویات خانه من را به اضافه‌ی آن فایل pac نشان داده است  در قسمتی که مربوط به دسترسی‌ها می‌شود فایل pac حرف x که به معنی excute است را در سه حرف اول خود دارد پس فایل متنی pac را می‌شود به راحتی توسط کاربری که آن را اجرایی کرده با یکی دستورات زیر اجرا کرد :

sh pac

./pac

فایل‌های شلی که توسط کاربر اجرایی نشده‌اند با sh اجرا می‌شوند.

زمانی که اسکریپت را با یکی از دستورات بالا اجرا کردید باید خروجی مانند زیر داشته باشد :

[hossein@hossein ~]$ ./pac
Hello Shell Scripting!

.

تبریک :)  شما یاد گرفتید که یک اسکریپت خیلی ساده‌ی بش چطوره نوشته و اجرا میشه !!!

.

اکنون وقت آن رسیده که با اصطلاحات و بعضی از سینتکس‌های بش آشنا شوید و از آن‌ها استفاده کنید به کد زیر دقت کنید :

display () 
{
START=$(date +%s); FR_CNT=0; ETA=0; ELAPSED=0
while [ -e /proc/$PID ]; do                        
    sleep 1
    VSTATS=$(tail -n1 "$RM"/ffmpeg-* | egrep -o 'frame=[0-9]+' | grep -Po 'd+' | tail -n1) 
    if [ $VSTATS -gt $FR_CNT ] 2> /dev/null; then
        FR_CNT=$VSTATS
        PERCENTAGE=$(( 100 * FR_CNT / TOT_FR )) 
        ELAPSED=$(( $(date +%s) - START )); echo $ELAPSED > /tmp/elapsed.value
        ETA=$(date -d @$(awk 'BEGIN{print int(('$ELAPSED' / '$FR_CNT') *
        ('$TOT_FR' - '$FR_CNT'))}') -u +%H:%M:%S) 
    echo "# Working on file: $COUNT of $OF - Length: $DUR - Frames: $TOT_FR
    nFilename: ${NFILE%.*}nSaved to: $SAVEAS
    nRe-muxing with FFmpeg
    nFrame: $FR_CNT of $TOT_FR   Elapsed: $(date -d @$ELAPSED -u
    +%H:%M:%S)   ET to finish: $ETA" 
    echo $PERCENTAGE                               
    fi
done | zenity
    --progress
    --window-icon $ICON
    --title="Remuxing to $EXT"
    --text="Initializing please wait..."
    --percentage=0
    --auto-close
    --auto-kill
}

این کد قسمتی از یک اسکریپت است که در تابع display قرار دارد, تابع ها تقریبا در همه‌ی زبان‌های برنامه نویسی وجود دارند , در واقع تابع‌ها برای مشخص کردن یک قسمت خاص از یک اسکریپت هستند که در صورتی که تابع با موفقیت کار خود را انجام داده باشد در ادامه‌ی اسکریپت نیز فراخوانی می‌شوند البته این به مقصود برنامه‌نویس بستگی دارد که شرط اینکه اگر تابع با مشکل برخورد خروج کند را بگذارد !! در کل اگر بخواهم تابع‌ها را در بش با یک جمله تعریف کنم باید بگویم تابع‌ها پروسه‌های کوچکی در پروسه‌ی اصلی هستند که موقع نیاز صدا زده می‌شوند !!

توابع در بش با علامت( } ) شروع و با ( { ) تمام می‌شوند. برای مثال این یک اسکریپت است که در آن از دو تابع استفاده شده :

#!/bin/bash
function numbers {
         for i in {10..20}
              do
                   echo $i
              done
}

function hello {
        echo hello
}

hello
sleep 2
echo The numbers are :
numbers
exit

همان‌طور که در اسکریپت می‌بینید اسم یکی از تابع‌ها number است که اعداد ۱۰ تا ۲۰ را می‌شمارد و تابع دیگری به نام hello که کلمه‌ی hello را نشان می‌دهد وجود دارد و در ادامه‌ی اسکریپت این دو تابع صدا شده‌اند تا کار خود را انجام بدهند و خروجی زیر را تشکیل داده‌اند :

[hossein@hossein ~]$ ./pac
hello
The numbers are :
10
11
12
13
14
15
16
17
18
19
20

 

آشنایی با شروط‌, حلقه‌ها و Syntax ها :

if که در لغت به معنی اگر است و در بش نیز به کار می‌رود برای مثال برنامه نویسی یک پوسته گرافیکی ساده طراحی کرده است که نوشته که تحت بش است و کد زیر می‌گوید اگر کاربر در پوسته‌ی گرافیکی پروسه‌ را لغو کرد دیگر ادامه نده :

if [ $? = 1]; then exit
fi

اما اگر این کد نباشد زمانی که کاربر با پوسته‌ی گرافیکی لغو می‌کند پروسه به کار خودش ادامه می‌دهد و باید آن را دستی kill کرد. عبارتی که به عنوان شرط هست همیشه درون کروشه و جلوی if قرار دارد و همیشه در پایان حلقه‌ی شرط باید از fi استفاده شود یک مثال دیگر :

#!/bin/bash
pass="hossein"
if [ "$pass" = "hossein" ] ; 
echo "That is okay !"
then exit; fi

اسکریپت بالا گفته کلمه‌ی (pass) مساوی است با (hossein) و بعد درون شرط گفته شده اگر (pass) مساوی بود با (hossein) جمله‌ی (! That is okay) را نمایش بده و بعد خارج شو. یکی دیگر از عبارت‌هایی که در شل اسکریپت به کار می‌رود else است به اسکریپت زیر دقت کنید :

#!/bin/bash
pass="arch"
if [ "$pass" = "hossein" ] ; then
 echo "That is okay !"
else
 echo "That is not okay :("
fi

در اسکریپت بالا مشخص کردیم که کلمه‌ی (pass) مساوی است با (arch) و گفتیم اگر (pass) مساوی بود با (arch) بگو (That is okay) و اگر با (arch) مساوی نبود بگو( ): That is not okay) و خارج شو. اکنون این اسکریپت را اجرا می‌کنیم :

[hossein@hossein ~]$ ./pac
That is not okay :(

همان‌طور که انتظار داشتیم خروجی جمله‌ی (That is not okay) بود !!

شما می‌توانید عملی را برای شرط دوم و سوم و .. با عبارت elif در نظر بگیرید,  در بش هر جمله‌ای که با علامت مربع (#) شروع شود یک Comment به حساب می آید و اجرا نمی‌شود, کامنت‌ها معمولا اطلاعاتی راجع به اسکریپت می‌دهند. هر گاه شما در اسکریپت خود از عبارت sleep استفاده کنید نسبت به عدد بعد  از آن باعث توقف موقت می‌شود, برای گرفتن داده از کاربر نیز می‌توانید از عبارت read استفاده کنید حال با این تفاسیر اسکریپتی می‌نویسیم :

#!/bin/bash
# this stupid scripts has been written by Hossein Heydari and its about password !!
echo "What is the password ? "
sleep 3
read pass
if [ "$pass" = "hossein" ] ;  then
         echo "That is okay !"
elif [ "$pass" = "ubuntu" ] ; then
        echo " nice "
else
        echo "That is not okay, " $pass " is not password :("
fi

این اسکریپت سوالی را با echo می‌پرسد و بعد ۳ ثانیه صبر می‌کند سپس منتظر گرفتن داده از کاربر می‌شود و نسبت به شرط‌های تعیین شده ادامه می‌دهد. لطفا خودتان امتحانش کنید !!

یکی دیگر از حلقه‌های موجود (for) است, که توسط آن دو عبارت را به وسیله‌ی یک متغیر به هم‌ دیگر مرتبط می‌کنند یا یک پروسه‌ بسیار کوچک را در خودش نگه داری می‌کند یا می‌توانیم از طریق آن یک ورودی بگیرم و روی آن تغییراتی ایجاد کنیم در کل حلقه‌ی for کارایی های زیادی دارد برای مثال اسکریپت‌های زیر را نگاه کنید :

for i in $( ls )
do
  echo $i > list
done

این اسکریپت تمام محتویات موجود در خانه را در فایل متنی list/~ می‌نویسد یا اسکریپت زیر اعداد ۰ تا ۱۰۰ را ده تا ده تا می‌شمارد ! !

for boob in {0..100..10}
do
  echo number $boob
done

برای آشنایی بیشتر با حلقه‌ی for می‌توانید از این لینک استفاده نمایید. اکنون با چند سینتکس آشنا می‌شویم :

$۰ : نام فایل بش.

USER$ : کاربری که در حال حاضر اسکریپت را اجرا کرده.

= یا ==  : هر دو به معنی مساوی است.

?$ : وضعیت خروج از اسکریپت.

HOSTNAME$ : نام هاست کاربری که اسکریپت را اجرا کرده.

$$ : PID اسکریپت اجرا شده

variable$ : به جای variable متغیر قرار می‌گیرد در واقع هر حرف یا کلمه‌ای که بعد از علامت دلار باشد و خودش یک سینتکس نباشد یک متغیر است برای مثال user$ یک متغیر است اما USER$ نیست.

حال با این تفاسیر اسکریپتی می‌نویسیم که از سینتکس‌های بالا در آن استفاده شده باشد :

#!/bin/bash
echo "name of this script is :"
sleep 1
echo $0
sleep 1
echo "your user name is :"
sleep 1
echo $USER
sleep 1
echo "your host name is :"
sleep 1
echo $HOSTNAME
sleep 1
echo "should I kill this script ? yes or no "
sleep 1
for i in *
     do
          read ans
        if [ "$ans" == "yes" ] ; then
           kill $$
       elif [ "$ans" = "no" ] ; then
          echo "okay"
          sleep 1
          echo "give a number ! "
              for pop in *
                  do
                       read pop
                      expr $pop + 2
                 exit
done
      else 
          echo "Invalid Option ! Try again"
      fi
done
sleep 1
echo "give a number ! "
for pop in *
     do
          read pop
         expr $pop + 2
          exit
done
exit

اسکریپت را اجرا و نتیجه‌ی آن را ببینید D:

.

قسمت اول این آموزش به پایان رسید قسمت دوم را هم به زودی با ویدیو‌ ارائه می‌کنم توی قسمت دوم با حلقه‌‌های untill و while و همچنین عملیات‌های ریاضی در بش و …. صحبت می‌کنیم, فعلا یک ویدیو به زبان انگلیسی که تقریبا محتویات همین آموزش را درون اون قرار دادم در اینجا منتشر کردم می‌تونید ببینید.

یه چیز باحال در حال و هوای بش :

لیــــــنـــک

 

 

 

 



برچسب ها : , , , , , , ,