انا العطشان

دست نویسی از زنجیره نامتناهی افکارم...

دست نویسی از زنجیره نامتناهی افکارم...

انا العطشان

مکانی برای ثبت خاطرات، دلنوشته ها و ...

آخرین نظرات
۱۴
فروردين ۹۴

Script ها کدی که می‌نویسیم تا پشت سر هم اجرا بشود (مثل فایل‌های Bat. و Cmd. در MS Win/DOS )

test.sh:

echo "Hello World!"
echo "Salam be jahan!"

برای اجرا باید دستوری مثل sh test.sh بنویسیم اگه بخوایم که فایل text تبدیل به فایل اجرایی بشه در اول فایل خط

#!/bin/sh

رو وارد کنیم و فایل رو با دستور

chmod +x test.sh

به فایل اجرایی تبدیل کنیم بعد از اون می‌تونیم فایل رو مثل فایل‌های اجرایی دیگه اجرا کنیم:

./test.sh

نوشتن comment در برنامه

با گذاشتن علامت # در ابتدای هر خط ، آن خط از برنامه comment می شود البته !# یک حالت استثناست .

پایان خط در shell

  • اول بگم که هر جا خواستیم به خط جاری پایان بدیم و ادامه‌ی اون رو توی خط بعدی بنویسیم از \ استفاده می‌کنیم:

echo \
"Salam"

  • دوم هر کجا که به خط بعد رفتیم معادل ; حساب می‌شه و بلعکس. این دو قسمت معادلند:

if true
then
        echo "Condition is true"
fi

if true; then echo "Condition is true"; fi

متغییرها

متغییرها به صورت name=value اختصاص داده می‌شوند و با name$ فراخوانی می‌شوند.

myname="Arman"
echo "My name is $myname"

دستور read

با دستور read می‌تونیم از ورودی متغییرها رو بخونیم

read varname

بلوک if

ساختار if به صورت زیر است:

if condition
then commands
[elif condition
then commands]
[else commands]
fi

به جای condition شرط را وارد می‌کنیم و جای commands دستورات رو. قسمت‌های elif و else اختیاری هستند برای نوشتن conditionهای مختلف از برنامه‌ی test استفاده می‌کنیم به دو صورت می‌تونیم از test استفاده کنیم:

  • test condition
  • [condition ]

مثال:

read name

if [ $name = "Arman" ]
then
        echo "Your name is Arman"
elif [ $name = "Mehdi" ] # ;))
then
        echo "Your name is Mehdi"
else
        echo "I don’t know you"
fi

 Shell شرط ورودی رو اجرا می‌کنه و اگر مقدار صفر رو برگردونند دستورات رو اجرا می‌کنه و اگر غیر صفر بود اجرا نمی‌کنه (یا else رو اجرا می‌کنه)

بهتره این‌جوری بگم که برعکس زبان‌هایی مانند خانواده‌ی C که صفر برابر False (غلط) و غیر صفر برابر True (درست) هست توی shell صفر برابر True و غیر صفر برابر False هست

پارامترهای مختلف test

دستور test پارامترهای زیادی داره بعضی از اون‌ها رو نوشتم: exp = عبارت str = رشته int = عدد صحیح file = اسم فایل

!exp اگر exp غلط باشد (not)

exp1 -a exp2 اگر exp1 و exp2 هردو درست باشند (and)

exp1 -o exp2 اگر exp1 یا exp2 یا هردو درست باشند (or)

str اگر طول str ناصفر باشد

str1 = str2 اگر str1 برابر str2 باشد

str1 != str2 اگر str1 مخالف str2 باشد

int1 -eq int2 اگر int1 برابر int2 باشد

int1 -nq int2 اگر int1 مخالف int2 باشد

int1 -gt int2 اگر int1 بزرگ‌تر از int2 باشد

int1 -ge int2 اگر int1 بزرگ‌تر یا مساوی int2 باشد

int1 -lt int2 اگر int1 کوچک‌تر از int2 باشد

int1 -le int2 اگر int1 کوچک‌تر یا مساوی int2 باشد

-e file اگر file وجود داشته یاشد

-d file اگر file یک دیرکتوری باشد

-f file اگر file وجود داشته باشد و یک فایل معمولی باشد

برای اطلاعات بیشتر به man test مراجعه کنید

حلقه‌ها

بلوک while

while condition
do commands
done

تا وقتی که condition درست باشد (کد خروجی از اجرا condition صفر باشد) commands اجرا می‌شوند

scrip هر ثانیه یک x رو صفحه می‌گذارد و وقتی تعداد آن‌ها به ۵ رسید حلقه‌ی while به پایان می‌رسه

a=
while [ "$a" != "....." ]
do
        a="$a."
        echo x
        sleep 1
done

  • به جای while ! condition می‌توانیم از until condition استفاده کنیم

a=
until [ "$a" = "....." ]
do
        a="$a."
        echo x
        sleep 1
done

بلوک for

for name in list
do commands
done

به ازای هر بار اجرای command متغییر name یکی از مقادیر list رو به خود می‌گیره

این script اعداد ۱ تا ۶ رو می‌نویسه

for number in 1 2 3 4 5 6
do
        echo -n "$number "
done
echo

این یکی اسم تمام فایل‌های دیرکتوری جاری رو می‌نویسه

for fn in *
do
        echo $fn
done

دستورهای break و continue

با دستور continue دستورهای بعدی حلقه استفاده اجرا نمی‌شود و دوباره به اول حلقه می‌رود با دستور break دستورهای بعدی حلقه استفاده اجرا نمی‌شود و برنامه از حلقه خارج می‌شود

اگر حلقه‌های تو در تو داریم و می‌خواهیم دو یا چند بار break یا continue کنیم جلوی این دستورات تعداد را وارد می‌کنیم

این script تمام اعداد دو رقمی قبل از ۷۳ را می‌نویسد

for a in 0 1 2 3 4 5 6 7 8 9
do
        for b in 0 1 2 3 4 5 6 7 8 9
        do
                echo "$a$b"

                if [ "$a$b" = "72" ]
                then
                        break 2
                fi
        done
done

بلوک case

case name in
match1) commands ;;
match2) commands ;;
esac

اگر می‌خواهیم مقدارهای مختلف یک متغییر را بررسی کنیم می‌توانیم به جای چندین if از case استفاده کنیم در صورتی که می‌خواهیم چند مقدار را بررسی کنیم (با یک عبارت) آن‌ها را با | از هم دیگر جدا می‌کنیم مثلا

name|NAME)
        commands
        ;;

مثال

echo -n "Enter your command: "
read cmd

case $cmd in

    listFiles)
        ls
        ;;

    showDirectory)
        pwd
        ;;

    calender)
        date
        echo
        cal
        ;;
                           
    *)
        echo "OOoops commands are: listFiles, showDirectory, calender"
        ;;
esac

|| و &&

command1 && command2

این دستور command1 را اجرا می‌کند و اگر خروجی صفر بود (درست) command2 اجرا می‌شود

[ -f fileName ] && ./fileName

این قطعه کد (که خیلی استفاده می‌شه) یعنی اگر فایل fileName وجود داشت آن‌را اجرا کن در غیر این صورت کاری انجام نمی‌دهد

  • اگر بخواهیم چند کار انجام دهیم آن‌ها رو با {} احاطه می‌کنیم

|| برعکس && هست یعنی اگر خروجی command1 غیر صفر بود command2 اجرا می‌شود

Redirecting

توی shell سه نوع ورودی/خروجی داریم:

  1. - ورودی از keyboard اسم:standard input
  2. - خروجی به console اسم:standard output
  3. - خروجی به console برای خطاها اسم: standard error
  4. برای توضیح بگم که stderr با stdout هیچ فرقی نداره و فقط برای جداسازی این دوتا هست

[n] > file

خروجی استاندارد یا شماره n را در file می‌ریزد

[n]>> file

خروجی استاندارد یا شماره n را در انتهای file می‌ریزد و آن‌را پاک نمی‌کند

[n]< file

ورودی استاندارد یا شماره n را از file می‌خواند

[n]<> file

فایل file را برای ورودی و خروجی استاندارد یا n باز می‌کند

[n1]>&n2

خروجی استاندارد یا شماره n1 را به n2 می‌فرستد

[n1]<&n2

ورودی استاندارد یا شماره n1 را به n2 می‌فرستد

[n]<&-

ورودی استاندارد یا n را می‌بندد

[n]>&-

خروجی استاندارد یا n را می‌بندد

[n]<< endWord
        write here
        and here
endWord

هرچه بین دو تا endWord نوشته شده باشه رو به ورودی استاندارد یا n می‌فرستد

اگر می‌خواهید از دستور cmd هیچ خروجی روی تصویر نشان داده نشود:

cmd 2>&1 >/dev/null

* /dev/null مثل یک سطل آشغال هست هرچی توش بریزین به هیچ جایی نمیره

پایپ

فرض کنیم می‌خواهیم اسم فایل‌های یک دیرکتوری را با ls بگیریم و با sort مرتب کنیم

ls > temp
sort < temp

به جای استفاده از فایل واسطه می‌توانیم مستقیما از خروجی یک دستور خوانده و به ورودی دیگری بدیم با یه پایپ (لوله)!

ls | sort

توابع و پارامترها

توی shell توابع یک نوع برنامه هستند و بلعکس! برای همین همه‌ی مطالب این قسمت (به جز تعریف تابع) برای یک script بدون تابع هم (که خودش یک برنامه است) برقرار است

تعریف تابع

FunctionName()
{
        commands
        .
        .
        .
        return exitStatus
}

exitStatus یک عدد صحیح است که به عنوان خروجی در نظر گرفته می‌شود

صدازدن تابع

از اون جایی تابع همون برنامه‌س از همون syntax استفاده می‌کنیم

func param1 param2

و کد خروجی هم (از اون‌جایی که یه برنامه هست ) توی متغییر ?$ ذخیره می‌شه

  • برای کسانی که نمی‌دونن هم بگم هر برنامه یه کد خروجی داره که توی ? ذخیره می‌شه که معمولا نشان دهنده‌ی اینه که برنامه درست اجرا شده یا نه:

arman:~$ ls /
bin   cdrom  etc   initrd      lib         media  opt   root  srv  tmp  var
boot  dev    home  initrd.img  lost+found  mnt    proc  sbin  sys  usr  vmlinuz
arman:~$ echo $?
0
arman:~$ ls /err
ls: /err: No such file or directory
arman:~$ echo $?
2

برای اینکه کد خروج کل shell script رو معین کنیم یا از کل برنامه خارج شویم از تابع exit استفاده می‌کنیم

مثلا

exit 2

پارامترها

پارامتر اول توی 1$، پارامتر دوم توی 2$، ... و پارامتر صفرم توی 0$ ذخیره می‌شه

test.sh:
#!/bin/sh

echo "0 = $0 1 = $1 2 = $2"

arman:~$ ./test.sh hello world
0 = ./test.sh 1 = hello 2 = world

پارامترهای خاص

  • پارامتر صفرم (0$) همون اسم برنامه هست (به همون طریقی که اجرا شده)
  • متغییر #$ تعداد پارامترها را مشخص می‌کنه
  • متغییر @$ شامل تمام متغییرها است که وقتی به string تبدیل می‌شود پارامترها را جداگانه مشخص می‌کند
  • متغییر *$ شامل تمام متغییرها است که وقتی به string تبدیل می‌شود پارامترها به هم می‌چسبند و بین آن‌ها اولین کاراکتر متغییر IFS هست (که معمولا space هست)
  • متغییر $$ شماره پروسه shell جاری هست
  • متغییر !$ شماره پروسه آخرین دستور background یا آخرین پایپ است

ابن مثال خیلی واضح تر از بالاست

test.sh:

#!/bin/sh

echo "0 = $0"
echo "# = $#"
echo "@ = $@"
for a in "$@"; do
    echo $a
done
IFS="/"
echo "* = $*"
for a in "$*"; do
    echo $a
done
echo "\$ = $$"

arman:~$ ./test.sh "hello world" hello2 world2
0 = ./test.sh
# = 3
@ = hello world hello2 world2
hello world
hello2
world2
* = hello world/hello2/world2
hello world hello2 world2
$ = 19750

 

موافقین ۰ مخالفین ۰ ۹۴/۰۱/۱۴
سعید زینلی

linux

script

اسکریپت

لینوکس

نظرات (۰)

هیچ نظری هنوز ثبت نشده است

ارسال نظر

ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
تجدید کد امنیتی