shell scripting
توسط royaflash دذ ۲۱ آذر, ۱۳۹۶ دذ ۰۲:۴۷ بعد از ظهر | دسته‌بندی شده در shell, خط فرمان, گنو/لینوکس | با ۰ دیدگاه |501 views

SHELL چیست ؟؟


SHELL واسط میان ما و سیستم عامل است. SHELL دستورات را از کاربر گرفته و به زبان سطح پایین قابل فهم برای سیستم عامل ترجمه میکند. SHELL ها میتوانند بصورت رابط خط دستور CLI و یا بصورت رابط گرافیکی GUI باشند. مثلا در ویندوز Command Prompt یا CMD یک SHELL است. در بسیاری از توزیع های لینوکس SHELL پیش فرض BASH است. BASH یک رابط خط دستور است. انواع دیگری از SHELL هم وجود دارد به نام های ksh و csh و bsh و … که کمتر و در موارد خاص استفاده میشوند و ما بیشتر با همان Bash کار میکنیم.

حال ترمینال سیستم خود را باز کنید. برای اینکه بفهمید از کدام SHELL استفاده میکنید دستور زیر را وارد کنید.

۱
۲
۳
[[email protected] ~]# echo $0
bash

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

۱
۲
۳
[[email protected] ~]# echo $SHELL
/bin/bash

 

تعریف متغیر

تعریف متغیر ها در Bash بسیار ساده است. ابتدا نام متغیر و سپس مساوی و مقدار آن. (بدون space). متغیر ها حساس به حروف کوچک و بزرگ هستند، ینی متغیر color با Color فرق دارد. برای چاپ کردن محتوای یک متغیر از کلمه کلیدی echo و علامت $ قبل نام متغیر استفاده میکنیم. برای جدا کردن دستورات از ; استفاده کنید.

۱
۲
۳
۴
۵
۶
۷
۸
۹
۱۰
۱۱
[[email protected] ~]# color=’blue’
[[email protected] ~]# echo $color
blue
[[email protected] ~]# Color=’red’
[[email protected] ~]# echo $Color
red
[[email protected] ~]# echo $Color ; echo $color
red
blue

از دستور echo برای چاپ انواع خروجی در صفحه استفاده میشود. برای چاپ مقدار محتوای یک متغیر در جمله از ساختار زیر استفاده کنید. به تفاوت دستور ها دقت کنید.

۱
۲
۳
۴
۵
۶
۷
[[email protected] ~]# echo “my Tshirt is $color”
my Tshirt is blue
[[email protected] ~]# echo ‘my Tshirt is $color’
my Tshirt is $color
[[email protected] ~]# echo my Tshirt is $color
my Tshirt is blue

برای دیدن نام کاربری که با آن وارد شدیم و مسیر home directory آن کاربر میتوانید متغیری که این مقادیر در آنها دخیره شده را چاپ کنید.

۱
۲
۳
۴
۵
[[email protected] ~]# echo $USER
root
[[email protected] ~]# echo $HOME
/root

حال یک Shell دیگر با دستور bash باز کنید. دوباره سعی کنید که متغیر color را چاپ کنید. میبینید که همچین متغیری وجود ندارد. وقتی یک متغیر تعریف میکنیم، فقط در همان شلی که هستیم وجود دارد. برای اینکه متغیر سراسری شود، از دستور export استفاده میکنیم. هر shell یا بهتر بگم هر پروسه یک شماره شناسایی یکتا به نام pid در سیستم دارد با دستور $$ echo میتوان این شماره شناسایی یکتای شلی که در آن هستیم را ببینیم. به کد های زیر دقت کنید.

۱
۲
۳
۴
۵
۶
۷
۸
۹
۱۰
۱۱
۱۲
۱۳
۱۴
۱۵
۱۶
۱۷
۱۸
۱۹
[[email protected] ~]# color=red // یک متغیر تغریف کردم
[[email protected] ~]# echo $$ // چاپ شماره شناسایی شلی که توش هستم
۱۱۰۸۰
[[email protected] ~]# bash  // با این دستور یک شل جدید زیر مجموعه این شل درست کردم
[[email protected] ~]# echo $$ حالا شماره این شل جدید رو میخوام
۱۱۰۹۲
[[email protected] ~]# echo $color // ببینم متغیر اینجا هم هست یا نه
[[email protected] ~]# exit // خروج از شل زیر مجموعه
exit
[[email protected] ~]# echo $$ // مطمئن بشم تو شل قبلی هستم
۱۱۰۸۰
[[email protected] ~]# export color // متعیر رو سراسری میکنم
[[email protected] ~]# bash // دوباره یک شل زیرمجموعه میسازم
[[email protected] ~]# echo $$ // میبینم که شماره شناساییش جدیده پس درست ایجاد شده
۱۱۱۰۱
[[email protected] ~]# echo $color // دوباره ببینم متغیر هست یا نه
red

دستور bash اصطلاحا یک subshell میسازد. وجود این subshell وابسته به وجود پدر خود است. اگر پدر از بین رود تمام subshell ها نابود میشوند. با دستور export یک متغیر را در شل پدر در شل های فرزندش کپی کردیم. با دستور ps میتوان دید چه پروسه هایی در حال اجراست. به خوبی مشخص میشود که چند subshell در حال اجرا هستند.

۱
۲
۳
۴
۵
۶
۷
۸
۹
۱۰
۱۱
  PID TTY          TIME CMD
۱۱۳۳۸ pts/0    ۰۰:۰۰:۰۰ bash
۱۱۳۴۸ pts/0    ۰۰:۰۰:۰۰ bash
۱۱۳۵۷ pts/0    ۰۰:۰۰:۰۰ bash
۱۱۳۶۸ pts/0    ۰۰:۰۰:۰۰ bash
۱۱۳۷۷ pts/0    ۰۰:۰۰:۰۰ ps

با دستور set میتوان تمام متغیر های محلی و سراسری را نشان داد و با دستور env میتوان متغیر های export شده را دید.

 

در این جلسه به بررسی بعضی از تنطیمات shell میپردازیم. برای دیدن اینکه shell چه تنظیمانی دارد از دستور زیر استفاده کنید.

۱
۲
۳
۴
۵
۶
۷
۸
۹
۱۰
۱۱
۱۲
۱۳
۱۴
۱۵
۱۶
۱۷
۱۸
۱۹
۲۰
۲۱
۲۲
۲۳
۲۴
۲۵
۲۶
۲۷
۲۸
[[email protected] ~]# set -o
allexport       off
braceexpand     on
emacs           on
errexit         off
errtrace        off
functrace       off
hashall         on
histexpand      on
history         on
ignoreeof       off
interactive-comments    on
keyword         off
monitor         on
noclobber       off
noexec          off
noglob          off
nolog           off
notify          off
nounset         off
onecmd          off
physical        off
pipefail        off
posix           off
privileged      off
verbose         off
vi              off
xtrace          off

برای روشن کردن یک option از set -o به همراه نام option و برای خاموش کردن آن از set +o و نام آن option استفاده میکنیم.

۱
۲
[[email protected] ~]# set -o allexport //روشن کردن
[[email protected] ~]# set +o allexport //خاموش کردن

این allexport باعث میشود اگر یک با چند subshell درست کردیم، بلافاصله تمام متغیر های شل پدر در آن کپی میشود و دیگر نیاز نیست دستی، تک تک متغیر ها را export کنیم.

۱
۲
۳
۴
۵
۶
۷
۸
[[email protected] ~]# set -o allexport
[[email protected] ~]# var1=amy
[[email protected] ~]# var2=taylor
[[email protected] ~]# echo $var1; echo $var2
amy
taylor

یا مثلا اگر درون یک subshell باشیم، دکمه کنترل و d را فشار دهیم، از subshell خارج میشود. برای خاموش کردن این shortkey از یک option به نام ignoreeof استفاده میکنیم.

۱
۲
۳
۴
۵
۶
۷
۸
۹
۱۰
۱۱
۱۲
۱۳
۱۴
۱۵
۱۶
۱۷
[[email protected] ~]# set -o allexport
[[email protected] ~]# var1=amy
[[email protected] ~]# var2=taylor
[[email protected] ~]# echo $var1; echo $var2
amy
taylor
[[email protected] ~]# set -o ignoreeof
[[email protected] ~]# Use “exit” to leave the shell.  //اینجا کنترل و دی زده بودم که خطا داد
[[email protected] ~]# exit // اینجا کلمه خروج رو نوشتم تا خارج بشه
exit

یا یک option دیگر مثل noclober باعث میشود که نتوان در یک فایل overwrite کرد. البته میتوان با کمی تغییر دستور این overwrite را force کرد ولی این option بیشتر جنبه احتیاطی و هشدار دادن دارد. به مثال توجه کنید.

۱
۲
۳
۴
۵
۶
۷
۸
۹
۱۰
۱۱
[[email protected] ~]# ls > file1
[[email protected] ~]# ls > file1
[[email protected] ~]# ls > file1   // قبل از روشن کردن میتوان روی فایل قبلی نوشت
[[email protected] ~]# set -o noclobber
[[email protected] ~]# ls > file1
bash: file1: cannot overwrite existing file   // خطا میدهد که نمیتوانید روی فایلی که محتوا دارد بنویسید
[[email protected] ~]# ls > file2
[[email protected] ~]# ls > file2
bash: file2: cannot overwrite existing file
[[email protected] ~]# ls >| file2   // با گذاشتن یک پایپ این عمل نوشتن رو فایل را فورس کردم

ضمیمه : دستور ls محتویات مسیری که هستیم را نشان میدهد. (امتحان کنید). یعنی نام فایل و ها پوشه های مسیری که در آنیم را نشان میدهد. با < خروجی این دستور رو ریختم تو یه فایل یه اسم مثلا file1 …. حالا با دستور cat file1 محتوبات این فایل را ببینید.

۱
۲
۳
۴
۵
۶
۷
۸
۹
۱۰
۱۱
۱۲
۱۳
۱۴
۱۵
۱۶
۱۷
۱۸
۱۹
۲۰
۲۱
۲۲
۲۳
۲۴
۲۵
۲۶
۲۷
۲۸
۲۹
۳۰
۳۱
۳۲
۳۳
a                d          file1  nohup.out         proje.sh  Templates  VMwareTools-10.0.6-3595377.tar.gz
anaconda-ks.cfg  Desktop    file2  Pictures          Public    test
b                Documents  IFS    post-install      sfk       Videos
c                Downloads  Music  post-install.log  temp      vm
[[email protected] ~]# ls > file1
[[email protected] ~]# cat file1
a
anaconda-ks.cfg
b
c
d
Desktop
Documents
Downloads
file1
file2
IFS
Music
nohup.out
Pictures
post-install
post-install.log
proje.sh
Public
sfk
temp
Templates
test
Videos
vm
VMwareTools-10.0.6-3595377.tar.gz

aa

یکی از مهم ترین feature های shell شاید alias باشد. alias نشان دهنده دستور است. برای اینکه یک دستور طولانی و یا پیچیده را بصورت کوتاه تر استفاده کنیم، برای آن یک alias نعریف میکنیم. alias مثل یک نام مستعار است. یک نام مستعار کوتاه تر و قابل یادآوری که به جای دستور طولانی یا پیچیده مینشیند. alias در حافظه موقت سیستم ذخیره میشود و با هر بار reboot سیستم مجبوریم آن را دوباره تعریف کنیم مگر اینکه آنرا ذخیره دائمی کرده باشیم. alias قبل از اینکه مسیر PATH برای هر کاربر پردازش شود، چک میشود. یکی از alias های پیش فرض سیستم، دستور ls است. در ترمینال خود type ls را وارد کنید. میبینید که دستور ls در حقیقت یک alias از دستور ls با سویچ اضافه است. به کد های زیر دقت کنید (اگه کد رو کپی میکردم رنگش نمی افتاد.)
در خط اول از دستور ls استفاده کردیم. محتویات درون مسیری که هستیم را نشان میدهد. رنگ آبی نشان دهنده مسیر است. رنگ سیاه یعنی فایل است. اگر هم فایل exe میداشتم سبز نشون میداد. سویچ F- نشان میدهد که جنس خروجی چیست. مثلا اگر directory باشد یک / میگذارد. اگر بخواهیم که دستور در حالت عادی اجرا شود و از alias استفاده نشود، قبل دستور یک \ میگذاریم. میبینید که وقتی \ گذاشتنم دیگه رنگی نشون نمیده. برای دیدن alias ها در ترمینال واژه alias را وارد کنید.

حال میخواهم خودم یک alias ایجاد کنم. کلمه alias را مینویسم، سپس کلمه ای که به عنوان alias در نظر دارم. بعد از آن مساوی و درون ‘ ‘ دستور اصلی را وارد میکنم.

۱
۲
۳
[[email protected] /]# alias la='ls -al --color=auto'
[[email protected] /]# type la
la is aliased to `ls -al --color=auto'

توجه داشته باشید که بصورت پیش فرض در همین ترمینال که هستم فقط این la تعریف شده است. برای از بین بردن alias هم از دستور unalias و نام alias استفاده کنید.

۱
۲
۳
۴
۵
۶
۷
۸
۹
۱۰
۱۱
۱۲
۱۳
۱۴
۱۵
۱۶
۱۷
۱۸
۱۹
۲۰
[[email protected] ~]# alias la='ls -al --color=auto'
alias cp='cp -i'
alias l.='ls -d .* --color=auto'
alias la='ls -al --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
[[email protected] ~]# unalias la
alias cp='cp -i'
alias l.='ls -d .* --color=auto'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias mv='mv -i'
alias rm='rm -i'
alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'

حاا این تنظیمات alias کجا ذخیره میشود؟؟ اگر شما هم مثل من از centos و یا یکی از توزیع های Red Hat استفاده میکنید، در مسیر home directory هر کاربر ( حتی root ) یک فایل به نام bashrc. وجود دارد. این فایل را باز کنید (با دستور cat) تا alias های دائمی را ببینید. برای اینکه یک alias همیشگی شود، آنرا در این فایل بنویسید. میتوانید از vim و یا gedit برای ویرایش این فایل استفاده کنید. با دستور ( vim .bashrc یا gedit .bashrc )

۱
۲
۳
۴
۵
۶
۷
۸
۹
۱۰
۱۱
۱۲
۱۳
۱۴
۱۵
۱۶
۱۷
۱۸
۱۹
۲۰
۲۱
۲۲
۲۳
۲۴
۲۵
۲۶
۲۷
۲۸
۲۹
[[email protected] ~]# whoami
root
/root
[[email protected] ~]# cat .bashrc
# .bashrc
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi
[[email protected] ~]# cd /home/mohammad/
[[email protected] mohammad]# cat .bashrc
# .bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi
# User specific aliases and functions
[[email protected] mohammad]#

همانطور که در شکل مشخص است برای root سه تا alias پیش فرض وجود دارد ولی برای کاربر yashar هنوز هیچ alias ثبت نشده است.
( فایل هایی مثل bashrc. که قبلشان نقطه است، اصطلاحا فایل های سیستمی هستند. )
تمرین : برای یک کاربر غیر از root یک alias درست کرده و برای همیشه آنرا ذخیره کنید. میتوانید از دستور << برای اضافه کردن ( append کردن) به انتهای فایل bashrc. استفاده کنید.

همانطور که کمی در قسمت قبل اشاره کردیم، برای اینکه Alias ها از بین نروند باید آنها را در bashrc. ذخیره کرد. در کل ۲ فایل وجود دارد که این اطلاعات environment (منظور محیطی که توش هستیم) را نگه میدارد. اصطلاحا به این ۲ فایل “Login Scripts” گفته میشود. با یکی از آنها آشنا شدیم که bashrc. نام دارد. دیگری bash_profile. نام دارد که این فایل هم در hone directory هر کاربر قرار دارد. حال هر کدام چه نقشی بازی میکنند؟
bash_profile. ===>> این فایل فقط یک بار آن هم در هنگام log in خوانده میشود. میتواند به PATH هر کاربر Append شود.
bashrc. ===>> هر بار که یک bash جدید باز میکنیم، خوانده میشود. برای تعریف متغیر ها و یا شخصی سازی prompt میتوان از آن استفاده کرد.

به دستورات زیر دقت کنید.

۱
۲
۳
۴
۵
# pwd
/home/mohammad
# ls -a .bash*
.bash_history  .bash_logout  .bash_profile  .bashrc
#

فایل bash_history. دستوراتی که این کاربر زده را نگه میدارد.
فایل bash_logout. اسکریپت های log out را نگه میدارد. مثلا اگر بخواهیم هنگام خروج یک کاربر دستوراتی اجرا شود در این فایل میگذاریم. مثلا اگر بخواهیم هنگامی که کاربر خارج میشود تاریخچه دستوراتی که وارد کرده پاک شود، دستورات لازم را اینجا میگذاریم.
فایل bash_profile. یک بار آن هم هنگام log in خوانده میشود.
فایل bashrc. میتواند بارها بعد از log in خوانده شود. بیشتر تنظیمات سفارشی کردن shell در این فایل انجام میشود.

بیایید نگاهی به محتویات bash_profile. بیندازیم.

۱
۲
۳
۴
۵
۶
۷
۸
۹
۱۰
۱۱
۱۲
۱۳
۱۴
۱۵
۱۶
۱۷
۱۸
۱۹
$ echo $HOME
/home/mohammad
$ pwd
/home/mohammad
$ cat .bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
    . ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH
$
$

دلیل اینکه این فایل یک بار خوانده میشود این است که وقتی کاربر وارد شد، برای او یک متغیر PATH تنظیم میشود. یک الگوی ثابت برای PATH وجود دارد و برای هر کاربر از این الگوی ثابت به اضافه مسیر bin که در home directory کاربر وجود دارد استفاده میشود. دقت کنید که متغیر PATH برابر مقدار پیش فرض خود به اضافه HOMEbin$ شده. منطقش اینه که PATH برابر خودش ( PATH=$PATH ) ، به اضافه HOME/bin$ که مقدار HOME$ را میبینید. از : برای جدا کردن مقادیر PATH استفاده میشود. شاید ندانید PATH چیست. در واقع PATH آدرس تمام دستوراتی است که یک کاربر میتواند اجرا کند، شامل کتابخانه ها و … .

۱
۲
۳
۴
۵
$
$ echo  $PATH
/usr/lib/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/mohammad/bin
$
$

به قسمت آخر PATH دقت کنید. اوت تیکه رو فایل bash-profile. درست کرده. این تعریف PATH فقط یکبار اتفاق میفته برای همین توی bash-profile. نوشته شده. اگه دوباره bash-profile. اجرا بشه، الکی طول این PATH زیاد میشه. ( شاید مشکلات دیگه ای هم باشه که من نمیدونم ). در قسمت بالای bash-profile. هم چک میکند که اگر bashrc. وجود دارد آنرا اجرا کند. برای همین بیشتر تنظیمات shell را در bashrc. میگذاریم.

حال یه نگاهی هم به bashrc. بیندازیم.

۱
۲
۳
۴
۵
۶
۷
۸
۹
۱۰
۱۱
$ cat .bashrc
# .bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi
# User specific aliases and functions
$
$

در قسمت بالای فایل ابتدا چک میکند که آیا فایل bashrc. سراسری وجود دارد یا نه، اگر باشد آنرا میخواند. bashrc. سراسری برای تنظیمات shell همه کاربران است. برای همین در مسیر etc قرار دارد. مثلا اگر بخواهیم یک alias برای همه کاربران تعریف شود، آنرا در bashrc. سراسری واقع در پوشه etc تعریف میکنیم. یا مثلا اگر خواستیم که هیچ کاربری نتواند هیچ فایلی را overwrite کند دستورش را در bashrc. سراسری وارد میکنیم.
حال اگر خواستیم فایل bashrc. دوباره خوانده شود، مثلا تغییراتی در آن داده ایم، از یکی از ۲ دستور زیر استفاده کنید. ممکن است هشداری مبنی بر تنظیمات جدید در سیستم دهد.

۱
۲
$ . .bashrc
$ source .bashrc

مثلا :

۱
۲
۳
۴
۵
۶
۷
۸
۹
۱۰
۱۱
۱۲
۱۳
۱۴
۱۵
۱۶
۱۷
$ echo "set -o noclobber" >> .bashrc
[[email protected] ~]$ source .bashrc
[[email protected] ~]$ cat .bashrc
# .bashrc
# Source global definitions
if [ -f /etc/bashrc ]; then
    . /etc/bashrc
fi
# User specific aliases and functions
set -o noclobber
$ ls > file1
$ ls > file1
-bash: file1: cannot overwrite existing file
$

درباره - یاشار اسمعیل دخت هستم ۲۷ سالمه (به دنیال یافتم آنم که کیستم)به صورت ۱۰۰٪ به گنو/لینوکس مهاجرت کردم . من رو با نام royaflash میشناسید . در زمینه شبکه و امنیت شبکه فعالیت میکنم . لینوکس همیشه چیزی برای یادگیری داره و لینوکس یه فرهنگه . در صورت نیاز میتونین با آدرس ایمیل : [email protected] یا شماره تلفن : 09141100257 در ارتباط باشید . وبلاگ شخصی من (-:) درباره من

فرستادن یک دیدگاه

XHTML: شما می‌توانید از این برچسب‌ها استفاده کنید: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>