Bash Scripting در لینوکس

 

bash یک پوسته (shell) قدرتمند و پرکاربرد برای سیستم عامل لینوکس است که به شما اجازه میدهد تا با استفاده از دستورات و ساختارهای کنترل جریان، عملیات مختلف را روی فایلها، دایرکتوریها، پروسسها و داده ها انجام دهید. bash همچنین یک زبان برنامه نویسی مفسری (interpreted) است که به شما اجازه میدهد تا اسکریپت های bash را نوشته و اجرا کنید. این اسکریپتها مجموعه ای از دستورات bash هستند که در یک فایل متنی قرار دارند و با پسوند .sh نشان داده میشوند.

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

 

اصول bash

برای شروع کار با bash، شما نیاز دارید که یک ترمینال (terminal) را در لینوکس باز کنید. ترمینال یک برنامه است که به شما اجازه میدهد تا با استفاده از صفحه کلید، با پوسته bash ارتباط برقرار کنید و دستورات خود را وارد کنید. شما معمولاً با فشار دادن ترکیب کلید Ctrl+Alt+T میتوانید یک ترمینال را باز کنید. هنگام باز شدن ترمینال، با چیزی شبیه به عبارت زیر روبرو خواهید شد:

username@hostname:~$

این عبارت را prompt گویند و نشان دهنده آن است که bash آماده است تا دستورات شما را دریافت کند. در اینجا، username نام کاربری شما، hostname نام سیستم شما و ~ نشانگر دایرکتوری خانگی (home directory) شما است. $ نشانگر این است که شما به عنوان یک کاربر معمولی وارد شده اید. اگر به عنوان یک کاربر مدیر (administrator) وارد شوید، به جای $ علامت # را خواهید دید.

حالا شما میتوانید دستورات bash را در prompt وارد کنید و با فشار دادن Enter آنها را اجرا کنید. برای مثال، اگر بخواهید ببینید که در حال حاضر در کدام دایرکتوری هستید، میتوانید دستور pwd را وارد کنید:

username@hostname:~$ pwd 
/home/username

این دستور نشان میدهد که شما در دایرکتوری خانگی خود هستید. اگر بخواهید محتوای یک دایرکتوری را ببینید، میتوانید دستور ls را وارد کنید:

username@hostname:~$ ls
Desktop Documents Downloads Music Pictures Public Templates Videos

 

این دستور لیست فایلها و زیردایرکتوریهای موجود در دایرکتوری فعلی را نشان میدهد. اگر بخواهید به یک زیردایرکتوری بروید، میتوانید دستور cd را با نام زیردایرکتوری مورد نظر وارد کنید:

username@hostname:~$ cd Documents
username@hostname:~/Documents$

این دستور شما را به زیردایرکتوری Documents منتقل میکند. توجه کنید که prompt تغییر کرده است و نشان میدهد که شما در زیردایرکتوری Documents هستید. اگر بخواهید به دایرکتوری قبلی برگردید، میتوانید دستور cd .. را وارد کنید:

username@hostname:~/Documents$ cd ..
username@hostname:~$

.. نشانگر دایرکتوری پدر (parent directory) است. اگر بخواهید به دایرکتوری خانگی خود بروید، میتوانید دستور cd ~ را وارد کنید:

username@hostname:~/Documents$ cd ~
username@hostname:~$

نشانگر دایرکتوری خانگی است. اگر بخواهید یک فایل را باز کنید، میتوانید نام فایل را با استفاده از تابع cat نمایش دهید:

username@hostname:~$ cat hello.txt
Hello, world!

cat چندین فایل را به عنوان ورودی میگیرد و محتوای آنها را به عنوان خروجی نمایش میدهد. اگر بخواهید چندین فایل را با هم الحاق (concatenate) کنید و در یک فایل جدید ذخیره کنید، میتوانید علامت > را بعد از لیست فایلها قرار دهید:

 

مثالهایی از Bash

مثال ۱: حلقه for

حلقه for یکی از ساختارهای کنترل جریان bash است که به شما اجازه میدهد تا یک دستور را برای هر عنصر از یک لیست اجرا کنید. برای مثال، اگر بخواهید یک پیام خوشامدگویی را برای هر نام از یک لیست نمایش دهید، میتوانید از حلقه for به شکل زیر استفاده کنید:

#!/bin/bash # این خط نشان میدهد که این فایل یک اسکریپت bash است 
# ایجاد آرایه
names=(Diaco , Saman , Shahrad , Hurad ) 
# شروع حلقه 
for for name in ${names[@]} do 
# نمایش پیام خوشامدگویی برای هر نام 
echo "Hello, $name!" done 
# پایان حلقه for

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

Hello, Diaco!
Hello, Saman!
Hello, Shahrad!
Hello, Hurad!

 

مثال ۲: شرط if

شرط if یک ساختار کنترل جریان دیگر bash است که به شما اجازه میدهد تا براساس یک شرط، عملیات مختلف را انجام دهید. برای مثال، اگر بخواهید ببینید که یک فایل وجود دارد یا خیر، میتوانید از شرط if به شکل زیر استفاده کنید:

#!/bin/bash 
# دریافت نام فایل به عنوان ورودی 
filename=$1 
# -fبررسی وجود فایل با استفاده از عملگر 
 if [ -f $filename ] then 
# نمایش پیام در صورت وجود فایل 
echo "$filename exists." 
else 
# نمایش پیام در صورت عدم وجود فایل 
echo "$filename does not exist." 
fi

مثال ۳: تابع define

تابع define یک روش bash است که به شما اجازه میدهد تا گروهبندی دستورات را با یک نام خاص تعریف کنید و سپس آنها را با صدا زدن نام تابع، اجرا کنید. برای مثال، اگر بخواهید یک تابع را بنویسید که جمع دو عدد را محاسبه و نمایش دهد، میتوانید به شکل زیر عمل کنید:

#!/bin/bash

# تعریف تابع sum با دو پارامتر a و b
sum () {
# محاسبه جمع دو پارامتر و ذخیره آن در متغیر result
result=$(( $1 + $2 ))
# نمایش مقدار متغیر result
echo $result
}

# صدا زدن تابع sum با دو عدد 3 و 5 به عنوان ورودی
sum 3 5

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

8

 

دستور grep

یک دستور bash است که به شما اجازه میدهد تا یک الگو (pattern) را در یک یا چند فایل یا خروجی دیگر دستورات جستجو کنید و خطوط مطابق با آن را نمایش دهید. الگو میتواند یک رشته ساده یا یک عبارت منظم (regular expression) باشد.

سینتکس اصلی دستور grep به شکل زیر است:

grep [OPTIONS] PATTERN [FILE...]

OPTIONS –  گزینه های grep که رفتار آن را کنترل میکنند.
PATTERN – الگوی جستجو.
FILE –  نام فایلهای ورودی.

برای مثال، برای نمایش تمام خطوط حاوی رشته bash از فایل /etc/passwd، شما میتوانید دستور زیر را اجرا کنید:

grep bash /etc/passwd

خروجی به شکل زیر خواهد بود:

root:x:0:0:root:/root:/bin/bash
linuxize:x:1000:1000:linuxize:/home/linuxize:/bin/bash

grep شامل تعداد زیادی از گزینه های مختلف است که میتوانید با مراجعه به صفحه man آنها را ببینید. برخی از مهمترین گزینه های grep عبارتند از:

• -i : نادیده گرفتن حروف بزرگ و کوچک در جستجو.

• -v : نمایش خطوط غیرمطابق با الگو.

• -c : نمایش تعداد خطوط مطابق با الگو.

• -n : نمایش شماره خط همراه با خروجی.

• -l : نمایش نام فایلهای حاوی الگو.

• -r : جستجو به صورت بازگشتی در دایرکتوریها و زیردایرکتوریها.

• -e : تعیین چندین الگو برای جستجو.

• -w : جستجو بر اساس کلمات کامل.

برای مثال، برای جستجو در تمام فایلهای موجود در دایرکتوری فعلی و زیردایرکتوریهای آن به دنبال رشته linux، شما میتوانید دستور زیر را اجرا کنید:

grep -r linux .

خروجی به شکل زیر خواهد بود:

./file1.txt:This is a file about linux.
./file2.txt:Linux is an operating system.
./subdir/file3.txt:Linux is open source.

 

دستور wget

یک دستور bash است که به شما اجازه میدهد تا فایلها را از وب با استفاده از پروتکلهای HTTP، HTTPS و FTP دانلود کنید. wget شامل تعداد زیادی از گزینه هایی است که به شما امکان میدهند تا دانلودهای چندگانه، ادامه دانلودهای قطع شده، محدود کردن پهنای باند، دانلود بازگشتی، دانلود در پس زمینه، آینه سازی یک وبسایت(Mirroring) و غیره را انجام دهید.

سینتکس اصلی دستور wget به شکل زیر است:

wget [OPTIONS] [URL]

برای مثال، برای دانلود فایل iso سیستم عامل CentOS ۷، شما میتوانید دستور زیر را اجرا کنید:

wget http://mirrors.mit.edu/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-1804.iso

خروجی:

--2021-11-01 12:34:56-- http://mirrors.mit.edu/centos/7/isos/x86_64/CentOS-7-x86_64-Minimal-1804.iso
Resolving mirrors.mit.edu (mirrors.mit.edu)... 18.181.0.31, 2603:9000:6:1::31
Connecting to mirrors.mit.edu (mirrors.mit.edu)|18.181.0.31|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 949051392 (905M) [application/octet-stream]
Saving to: ‘CentOS-7-x86_64-Minimal-1804.iso’

CentOS-7-x86_64-Minimal-1804.iso 100%[==========================================================>] 905.00M 101MB/s in 9.0s

2021-11-01 12:35:05 (100 MB/s) - ‘CentOS-7-x86_64-Minimal-1804.iso’ saved [949051392/949051392]

بعد از پایان دانلود، میتوانید فایل دانلود شده را در دایرکتوری فعلی خود پیدا کنید.

برخی از مهمترین آپشن های wget عبارتند از:

• -O : تعیین نام فایل خروجی.

• -P : تعیین محل ذخیره فایل خروجی.

• -c : ادامه دانلود فایل قطع شده.

• -b : دانلود در پسزمینه.

• -r : دانلود بازگشتی.

• –limit-rate : محدود کردن سرعت دانلود.

 

چگونه متغیر های bash را در یک shell script به صورت پارامتر اعمال کنیم؟

متغیرهای bash را میتوانید به عنوان پارامترهای خط فرمان به یک اسکریپت shell انتقال دهید. برای این کار، شما باید مقادیر متغیرها را بعد از نام اسکریپت shell قرار دهید. در داخل اسکریپت shell، شما میتوانید به پارامترهای خط فرمان با استفاده از متغیرهای موقعیتی (positional variables) دسترسی پیدا کنید. متغیرهای موقعیتی با علامت دلار ( $) و یک عدد شناسایی میشوند. برای مثال، $۱ نشانگر پارامتر اول و $۲ نشانگر پارامتر دوم است.

برای مثال، فرض کنید شما یک اسکریپت shell به نام hello.sh دارید که چاپ کند Hello, name! که name یک پارامتر خط فرمان است. در این صورت، شما میتوانید اسکریپت را به شکل زیر بنویسید:


#!/bin/bash

# تعریف یک متغیر موقعیتی
name=$1

# چاپ پیام خوشامدگویی
echo "Hello, $name!"

بعد از نوشتن اسکریپت، شما باید آن را با دستور chmod قابل اجرا کنید:

chmod +x hello.sh

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

./hello.sh Ali

خروجی به شکل زیر خواهد بود:

Hello, Ali!

شما میتوانید بیش از یک پارامتر خط فرمان به اسکریپت shell خود بدهید. در حالت کلی، سینتکس انتقال چندین پارامتر به هر اسکریپت shell به شکل زیر است:

script.sh arg1 arg2 arg3 ...

پارامتر سوم با $۳ و غیره شناسایی میشود. همچنین تعداد پارامترهای خط فرمان را میتوانید با استفاده از متغیر $ # ببینید.

 

یک سناریوی واقعی

یک سناریوی کاملا کاربردی از bash نویسی در لینوکس میتواند این باشد که بخواهید یک اسکریپت bash بنویسید که به صورت خودکار فایلهای بکاپ یک کاربر را از یک سرور به یک سرور دیگر منتقل کند. برای این کار، شما میتوانید از دستورات زیر استفاده کنید:

• scp : برای انتقال فایلها از طریق پروتکل SSH.

• ssh : برای اجرای دستورات روی سرور از راه دور.

• find : برای جستجو و فیلتر کردن فایلهای بکاپ.

• tar : برای فشردهسازی و باز کردن فایلهای بکاپ.

• date : برای تولید نام فایلهای بکاپ با تاریخ و زمان.

فرض کنید میخواهید فایلهای بکاپ کاربر linuxize را از سرور source به سرور destination منتقل کنید. همچنین فرض کنید شما دسترسی SSH به هر دو سرور دارید و میتوانید با استفاده از کلید عمومی خود وارد شوید. در این صورت، شما میتوانید یک اسکریپت bash به شکل زیر بنویسید:

#!/bin/bash

# تعریف متغیرهای مورد نیاز
USER=linuxize
SOURCE_SERVER=192.168.1.10
DESTINATION_SERVER=192.168.1.20
BACKUP_DIR=/home/$USER/backup
BACKUP_FILE=backup-$(date +%Y-%m-%d).tar.gz

# انتقال به دایرکتوری بکاپ روی سرور source
ssh $USER@$SOURCE_SERVER "cd $BACKUP_DIR"

# جستجو و فشردهسازی فایلهای بکاپ روی سرور source
ssh $USER@$SOURCE_SERVER "find . -type f -name '*.bak' | tar czvf $BACKUP_FILE -T -"

# انتقال فایل فشردهشده روی سرور destination
scp $USER@$SOURCE_SERVER:$BACKUP_DIR/$BACKUP_FILE $USER@$DESTINATION_SERVER:$BACKUP_DIR

# باز کردن فایل فشردهشده روی سرور destination
ssh $USER@$DESTINATION_SERVER "cd $BACKUP_DIR && tar xzvf $BACKUP_FILE"

# حذف فایل فشردهشده روی هر دو سرور
ssh $USER@$SOURCE_SERVER "rm $BACKUP_DIR/$BACKUP_FILE"
ssh $USER@$DESTINATION_SERVER "rm $BACKUP_DIR/$BACKUP_FILE"

# نمایش پیام موفقیت
echo "Backup files transferred successfully."

بعد از نوشتن اسکریپت، شما میتوانید آن را با دستور chmod قابل اجرا کنید:

chmod +x backup.sh

سپس میتوانید اسکریپت را با دستور زیر اجرا کنید:

./backup.sh

خروجی به شکل زیر خواهد بود:

 

Backup files transferred successfully.

 

برای یادگیری Bash منابع فارسی و زبان اصلی زیادی وجود دارد. توصیه می شود حتما از منابع و مستندات خود لینوکس استفاده نمایید.

ثبت رای
جستجو

سرفصل های مقاله

نظرات کاربران
دیدگاهتان را بنویسید

لطفا علاوه بر متن نظر، نام و ایمیل خود را نیز وارد کنید. (ایمیل شما منتشر نخواهد شد)