آموزش Bash Scripting
۲۶ اسفند ۱۳۹۹
در این مقاله شما را با اسکریپتنویسی و چگونگی شروع کار با آن آشنا خواهیم کرد بنابراین فرض را براین میگیریم که با دستورهای Shell و Linux آشنا هستید.
Shell Script چیست؟
Shell Script یک برنامه متنی ساده مبتنی بر Command line است که دستورهایی را بهترتیب توسط مفسر Bash اجرا میکند. اکثرا از Shell Script برای خودکارسازی فرایندهای روزمره مانند پشتیانگیری از فایلها، نصب پکیجهای مورد نیاز روی سرورهای مختلف، عیبیابی و … استفاده میکنند زیرا به صرفهجویی در وقت و افزایش بهرهوری توسعهدهنده و مسئول DevOps یا حتی کاربران عادی کمک میکند.
اگر برای انجام یک کار مرتبا دستورهای ساده یا حتی پیچیده را پشت سر هم اجرا میکنید بنابراین یادگیری نوشتن Shell Script میتواند برای شما مفید باشد. نامگذاری Shell Script بر عهدهی شما است و میتوانید از نامهای دلخواه خودتان استفاده کنید اما بایستی به مجوزهای مورد نیاز برای اجرای آن اسکریپت نیز توجه داشته باشید. توصیه ما این است که از نامهای توصیفی استفاده کنید.
از پسوند .sh
در نامگذاری اسکریپتها استفاده میشود زیرا مشخص میکند که این فایل یک اسکریپت است اما در سیستمعامل Linux میتوانید اسکریپتها را بدون نیاز به استفاده از این پسوند، اجرا کنید.
ساختار یک Shell Script
در خط اول اسکریپت بایستی مفسری که اسکریپت را اجرا میکند، مشخص کنیم:
#!/bin/bash
بعد از مشخص کردن مفسر میتوانید توضیحهای مورد نیاز، نام توسعهدهنده و دیگر موارد اینچنینی را قرار دهید. هر چیزی که پس از یک #
قرار بگیرد بهعنوان یک کامنت در اسکریپت شناخته شده و مفسر آن را اجرا نمیکند:
# Name of Script: test.sh
# A simple bash script to illustrate some basic concepts
# Author: Goodness Chris-Ugari
# Date: 16-02-2021
پس از قرار دادن توضیحها در حالت کامنت میتوانید مجموعه دستورهایی که میخواهید اجرا شوند را در اسکریپت تعریف کنید:
#!/bin/bash
# Name of Script: test.sh
# A simple bash script to illustrate some basic concepts
# Author: Goodness Chris-Ugari
# Date: 16-02-2021
# Display Hello, World
echo Hello, world
# Display the present/current working directory
pwd
کدهای فوق را در یک فایل با نام test.sh
ذخیره کرده و با اجرای دستور ./test.sh
در مسیر این اسکریپت میتوانید خروجی آن را مشاهده کنید:
استفاده از متغیرها
استفاده از متغیرها در زمانی که میخواهید دادههایی را موقتا ذخیره کنید بسیار مفید است. توجه داشته باشید که Bash به حروف کوچک و بزرگ حساس است بنابراین در تعریف و استفاده از متغیرها دقت داشته باشید. پس از تعریف متغیر میتوانید مقدار آن را با استفاده از $
فراخوانی کنید:
# Declare a variable NAME and assign a value to it.
MOOD=Excited!
# Display "I am Excited!"
echo I am $MOOD
مطمئنا میتوانید خروجی اسکریپت فوق را حدس بزنید. برای رشتههای (strings) پیچیدهتر بایستی از double quotationها استفاده کنید. برای مثال:
# Declare a variable NAME and assign a value to it.
MOOD="very excited"
# Display "I am very excited"
echo I am $MOOD
جایگزینی دستورها
شما میتوانید خروجی یک دستور را در یک متغیر ذخیره کنید و این کار باعنوان Command Substitution شناخته میشود. برای پیادهسازی Command Substitution بایستی از $
قبل از پرانتزهای دربرگیرندهی دستور مورد نظر استفاده کنید:
#The code below will return the number of entries in a directory.
dirContents=$(ls | wc -l)
echo The number of entries in this directory is $dirContents
متغیرهای خاص
متغیرهای خاص متغیرهایی هستند که بهطور خودکار برای شما تنظیم میشوند. در اینجا برخی از آنها ذکر شده است:
$0
: نام اسکریپت در این متغیر ذخیره میشود.$n
: پارامترهای ورودی اسکریپت در این متغیر بهصورت$1
یعنی پارامتر اول یا$2
یعنی پارامتر دوم، ذخیره میشود.$#
: این متغیر تعداد پارامترهای ورودی را نشان میدهد.$*
: تمام پارامترهای ورودی در این متغیر ذخیره میشوند.$?
: وضعیت خروجی آخرین دستور اجرا شده نمایش داده میشود. 0 بهمعنای موفقیت آمیز بودن اجرا دستور و 1 بهمعنی اجرا نشدن دستور است.$$
: شناسه فرایند فعلی اسکریپت در این متغیر ذخیره میشود.
اپراتورهای اصلی
در Bash میتوانید به اپراتورهایی که در ادامه بررسی میکنیم دسترسی داشته باشید:
اپراتورهای محاسباتی
اپراتور | توضیحات | نحوهی استفاده |
+ | جمع | num1 + num2 |
– | تفریق | num1 – num2 |
* | ضرب | num1 * num2 |
/ | تقسیم | num1 / num2 |
% | مدول | num1 % num2 |
= | مقداردهی | $num = value |
میتوانید از اپراتورهای محاسباتی بهچندین روش مانند استفاده از کلیدواژههای let
یا expr
، پرانتز یا براکت بههمراه $
استفاده کنید. همچنین توجه داشته باشید که نمیتوانید مستقیما از اپراتورهای محاسباتی استفاده کنید:
#!/bin/bash
#
let myVariable=2+3 #If you are declaring the expression without quotes, then you must ensure that the expression doesn't contain spaces.
echo $myVariable #This will output 5
#Using the let command
let "myVariable = 2 + 3" #You can have spaces within quotes.
echo $myVariable # This will output 5
let myVariable++ #Will increment the last value of $myVariable, so $myVariable will now be 6
#Using the expr command
expr 2 + 3 #You must include space when using the expr command and do not enclose the expression in quotes. This line will output the addition of the two numbers.
expr "2 + 3" #Will be treated as a string and will output 2 + 3
expr 2+3 #Will be treated as a string and will output 2+3
#Using brackets
echo $[2+3] #Will work with or without spaces and output the addition of the numbers.
echo $((2+3)) #Will also work with or without spaces.
توجه داشته باشید که کلید واژهی let
به شما کمک میکند تا خروجی محاسبات را در یک متغیر ذخیره کنید اما expr
فقط نتیجه را در خروجی نمایش میدهد.
اپراتورهای رابطهای
اپراتور | توضیحات | نحوهی استفاده |
-eq | برابر است با | $num1 -eq $num2 |
-ne | برابر نیست با | $num1 -ne $num2 |
-gt | بزرگتر از | $num1 -gt $num2 |
-lt | کوچکتر از | $num1 -lt $num2 |
-ge | بزرگتر یا مساوی است با | $num1 -ge $num2 |
-le | کوچکتر یا مساوری است با | $num1 -le $num2 |
توجه داشته باشید که اپراتورهای رابطهای را نمیتوانید برای stringها استفاده کنید.
Boolean
اپراتور | توضیحات | نحوهی استفاده |
! | نفی | ! |
-o | یا | conditon1 -or condition2 |
-a (&&) | و | condition1 -a condition2 |
علاوهبراینها میتوانید از ||
بهعنوان OR و از &&
بهعنوان AND استفاده کنید.
اپراتورهای مرتبط با String
اپراتور | توضیحات | نحوهی استفاده |
= | برابر است با، نتیجه بهصورت مقادیر بولی برگشت داده میشود | $string1=string2 |
!= | برابر نیست با، نتیجه بهصورت مقادیر بولی برگشت داده میشود | $string1!=$string2 |
-z | تعداد کاراکترهای یک رشته را بررسی میکند. اگر تعداد کاراکترهای برابر با صفر بود، مقدار صحیح برگشت داده میشود | -z $string |
-n | بررسی میشود که کاراکترهای یک رشته برابر با صفر نباشد. | -n $string |
اپراتورهای مرتبط با فایل
اپراتور | توضیحات | نحوهی استفاده |
-d | دایرکتوری بودن ورودی را بررسی میکند | -d $file |
-f | فایل بودن ورودی را بررسی میکند | -f $file |
-p | نامگذاری ورودی بررسی میشود | -p $file |
-r | مجوز خواندن فایل بررسی میشود | -r $file |
-w | مجوز نوشتن در فایل بررسی میشود | -w $file |
-x | قابل اجرا بودن فایل بررسی میشود | -x $file |
-s | بررسی میشود که اندازهی فایل بیشتر از صفر باشد | -s $file |
-e | موجود بودن فایل بررسی میشود | -e $file |
حلقهها
از حلقهها برای اجرای مکرر یک سری دستورها میتوان استفاده کرد.
حلقه for
سینتکس حلقه For به شکل زیر است:
for var in <list>
do
<command>
done
مثال:
#!/bin/bash
#This will print numbers 1 to 5
for value in {1..5}
do
echo $value
done
حلقه while
از این حلقه در حالی استفاده میشود که یک شرط مشخص برابر با true باشد. سینتکس حلقهی While به شکل زیر است:
while [ <condition> ]
do
<command>
done
مثال:
#Will print numbers 1 to 5
count=1
while [ $count -le 5 ]
do
echo $count
((count++)) #Will increment count by 1 after every loop
done
حلقه until
این حلقه تا زمانی که یک شرط معین برابر با true شود به اجرای دستورهای درون خود ادامه میدهد. سینتکس حلقه Until به شکل زیر است:
until [ <condition> ]
do
<command>
done
مثال:
#Will print numbers 1 to 5
count=1
until [ $count -gt 5 ] #Loop will stop one count is greater than 5
do
echo $count
((count++)) #Will increment count by 1 after every loop
done
فانکشن
فانکشن یک بلوک از کدها است که قابلیت استفاده مجدد دارد بنابراین میتوان با تعریف آنها از تکرار کدها جلوگیری کنیم و هر زمان که به یک عملکرد خاص نیاز داشتیم فقط از فانکشن آن استفاده کنیم. از سینتکس زیر برای تعریف فانکشن استفاده میشود:
#Without the function keyword
function_name () {
<commands>
}
یا
#With the function keyword
function function_name {
<commands>
}
مثال:
#!bin/bash
#A function that prints out the first argument supplied to it
function printArg () {
echo The first argument is $1
}
#Function call with an argument
printArg "Hello World"
#The output of the function above will be "The first argument is Hello World"
هر دو سینتکس فوق قابل استفاده هستند و نتیجهی یکسانی دارند بنابراین تصمیم استفاده از هرکدام آنها با خود شما است. پرانتزهایی که پس از فانکشن printArg
قرار داده شده برخلاف دیگر زبانهای برنامهنویسی که از آنها برای پارامترهای ورودی استفاده میشود، Bash به این شکل نیست.
نباید چیزی در این پرانتزها قرار دهید و برای ارسال پارامترهای مختلف به هر فانکشن بایستی مستقیما دادههای ورودی خود را پس از فانکشن قرار دهید. توجه داشته باشید که قبل از تعریف یک فانکشن نمیتوانید آن را فراخوانی کنید.
عبارتهای شرطی در اسکریپتهای Bash
عبارتهای شرطی به شما امکان میدهند تا عملکردهای خاصی را بر اساس شرایط معین شدهای ارائه دهید.
عبارت شرطی if
در عبارت شرطی if اگر شرط تعیین شدهی ما برابر با true باشد، عملکردهای مورد نظر ما اجرا میشوند در غیر این صورت، این بخش از کد نادیده گرفته شده و بقیهی کدها اجرا میشوند. سینتکس تعریف عبارت شرطی if به شکل زیر است:
if [ <condition/test> ]
then
<command>
fi
عبارت شرطی if else
این عبارت شرطی عملکردی شبیه عبارت شرطی if دارد اما با استفاده از این عبارت شرطی، مفسر پس از برقرار نشدن شرط اولیه، کدهای بلوک دوم این عبارت شرطی را اجرا میکند. سینتکس این عبارت شرطی به شکل زیر است:
if [ <condition/test> ]
then
<command1>
else
<command2>
fi
مثال:
#!bin/bash
#This script will take 2 numbers as command-line arguments. It will print to the screen the larger of the two numbers.
if [ $1 -gt $2 ]
then
echo $1
else
echo $2
fi
عبارت شرطی if elif else
برای تعیین کردن چند شرط مختلف میتوانیم از عبارت شرطی if elif else استفاده کنیم که سینتکس آن به شکل زیر است:
if [ <condition1> ]
then
<command1>
elif [ <condition2> ]
then
<command2>
elif [ <condition3> ]
then
<command3>
else
<command>
fi
مثالی که یک پیام ساده را بر اساس روزهای هفته چاپ میکند:
#!/bin/bash
#script to print a message based upon which day of the week it is.
day_of_the_week=$(date +%u)
if [ $day_of_the_week -eq 1 ]
then
echo Today is Monday, aargh!
elif [ $day_of_the_week -eq 2 ]
then
echo Today is Tuesday
elif [ $day_of_the_week -eq 3 ]
then
echo Today is Wednesday
elif [ $day_of_the_week -eq 4 ]
then
echo Today is Thursday
elif [ $day_of_the_week -eq 5 ]
then
echo Today is Friday, TGIF!
elif [ $day_of_the_week -eq 6 ]
then
echo Today is Saturday
elif [ $day_of_the_week -eq 7 ]
then
echo Today is Sunday
else
echo Something is wrong
fi
برای مشاهدهی نتایج مختلف میتوانید زمان سیستم خود را تغییر دهید. همچنین میتوانید به هرتعداد که میخواهید از elif برای تعیین کردن شروط مختلف استفاده کنید، علاوهبرآن میتوانید عبارتهای شرطی if را بهصورت تودرتو استفاده کنید اما بایستی فاصلهها را رعایت کنید.
عبارت شرطی case
درمواردی که عبارتهای شرطی if و elif باعث ایجاد پیچیدگی میشوند میتواند از عبارت شرطی case استفاده کنید که سینتکس آن به شکل زیر است:
Case <variable> in
<pattern1>)
<command>
;;
<pattern2>)
<command2>
;;
esac
مثال:
#!/bin/bash
echo Which color do you prefer? Blue, Green or Yellow? #This will be printed first when you run the script.
read color #Prompt to accept input
case $color in #Compare using the value entered for color at the prompt********
Blue)
echo Feeling blue today?
;;
Green)
echo The land is green!
;;
Yellow)
echo It is going to be a sunny day!
;;
*)
echo Try Again
;;
esac #Indicates the end of the case statement
منبع: https://goodiec.hashnode.dev/beginners-guide-to-shell-scripting