في نافذة الطباعة اختر «حفظ كملف PDF» كوجهة.
نظم التشغيل 1، الدرس العملي 11
اكتب أول سكربتاتك: شغلها، وخزن القيم، واقرأ الإدخال، واحسب، واتخذ القرارات.
./script.sh وbash script.sh#!/bin/bash، والأمر chmod 755، وسبب الحاجة إلى ./$( ) والوسائط (arguments) $1 و$# و$@read وread -p وread -s ومن STDINlet وexpr و$(( ))if وelif وelse، ومعاملات (operators) الأمر test، و&& و|| وcaseأول السكربتات
ملف نصي عادي من الأوامر
.sh (myscript.sh)؛ أما لينكس نفسه فلا يحتاج إلى الامتدادالبرنامج
تعليمات مخزنة على القرص
العملية
نسخة عاملة في الذاكرة RAM
سكربتك
يعمل في عملية bash جديدة
cp تعنيان عمليتي cpexport)#!/bin/bash
# A sample Bash script
echo Hello World!#echo يطبع رسالة، كما يفعل عند المحثالملف الجديد ليس له إذن التنفيذ (execute permission). توقع ما يطبعه كل أمر.
$ ./myscript.sh
$ ls -l myscript.sh
$ chmod 755 myscript.sh
$ ls -l myscript.sh
$ ./myscript.sh$ ./myscript.sh
bash: ./myscript.sh: Permission denied
$ ls -l myscript.sh
-rw-r--r-- 1 student student 53 Sep 25 12:10 myscript.sh
$ chmod 755 myscript.sh
$ ls -l myscript.sh
-rwxr-xr-x 1 student student 53 Sep 25 12:10 myscript.sh
$ ./myscript.sh
Hello World!يبحث Bash عن الأمر فقط في المجلدات المذكورة في $PATH
$ myscript.sh
bash: myscript.sh: command not found
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
$ /home/student/lab11/myscript.sh
Hello World!:؛ والمجلد الحالي ليس منها./myscript.sh (نسبي) أو المسار المطلق الكاملls في مجلد ما لا يشغل مصادفة أبدايبدأ badbang.sh بالسطر #!/bin/bas، وينقصه حرف واحد. توقع التشغيلين.
#!/bin/bas
# the interpreter path is misspelled
echo Hello World!$ ./badbang.sh
$ bash badbang.sh$ ./badbang.sh
bash: ./badbang.sh: cannot execute: required file not found
$ bash badbang.sh
Hello World!تخزين القيم
مخازن مؤقتة للمعلومات
name=value، بلا $، وبلا مسافات حول =$name؛ قبل تنفيذ السطر يستبدل bash كل متغير بقيمتهmyvar وMYVAR متغيران مختلفان$ myvar = Hello
$ myvar=Hello
$ echo $myvar
$ echo $MYVAR$ myvar = Hello
bash: myvar: command not found
$ myvar=Hello
$ echo $myvar
Hello
$ echo $MYVAR
توقع خرج (output) ./simplevariables.sh
#!/bin/bash
# A simple variable example
myvariable=Hello
anothervar=Linux
echo $myvariable $anothervar
echo
sampledir=/etc/apt
ls $sampledirecho بلا وسائط يطبع سطرا فارغاls $sampledir هو ls /etc/apt قبل تنفيذه$ ./simplevariables.sh
Hello Linux
apt.conf.d auth.conf.d keyrings preferences.d sources.list sources.list.d trusted.gpg.dيقسم Bash الكلمات عند المسافات؛ وعلامات التنصيص تجعلها عنصرا واحدا. توقع كل سطر.
$ myvar=Hello World
$ myvar='Hello World'
$ echo $myvar
$ newvar="More $myvar"
$ echo $newvar
$ newvar='More $myvar'
$ echo $newvar$ myvar=Hello World
bash: World: command not found
$ myvar='Hello World'
$ echo $myvar
Hello World
$ newvar="More $myvar"
$ echo $newvar
More Hello World
$ newvar='More $myvar'
$ echo $newvar
More $myvarاحفظ خرج أمر في متغير (command substitution)
$ myvar=$( ls /etc | wc -l )
$ echo There are $myvar entries in the directory /etc
There are 74 entries in the directory /etc
$ ls /etc/apt
apt.conf.d auth.conf.d keyrings preferences.d sources.list sources.list.d trusted.gpg.d
$ files=$( ls /etc/apt )
$ echo $files
apt.conf.d auth.conf.d keyrings preferences.d sources.list sources.list.d trusted.gpg.dls -l /etc يعطي ls وسيطين؛ والسكربت يستقبل وسائطه بالطريقة نفسها
#!/bin/bash
# A simple copy script
cp $1 $2
# Let's verify the copy worked
echo Details for $2
ls -lh $2$ ./mycopy.sh salesdata.txt backup.txt
Details for backup.txt
-rw-r--r-- 1 student student 123 Sep 25 12:11 backup.txtيخزنها النظام لكل سكربت
| المتغير | يحمل |
|---|---|
$0 | اسم السكربت |
$1 إلى $9 | أول تسعة وسائط لسطر الأوامر |
$# | عدد الوسائط الممررة |
$@ | كل الوسائط |
$? | حالة الخروج (exit status) لآخر أمر |
توقع ./args.sh red green blue
#!/bin/bash
# special variables set by the system
echo "Script name: $0"
echo "Number of arguments: $#"
echo "All arguments: $@"
echo "Second argument: $2"
echo "User: $USER, host: $HOSTNAME"
echo "This is line $LINENO"$ ./args.sh red green blue
Script name: ./args.sh
Number of arguments: 3
All arguments: red green blue
Second argument: green
User: student, host: ubuntu-lab
This is line 8يشغل script1.sh السكربت script2.sh. توقع الأسطر الثلاثة.
#!/bin/bash
# demonstrate variable scope 1.
var1=blah
var2=foo
# Let's verify their current value
echo $0 :: var1 : $var1, var2 : $var2
export var1
./script2.sh
# Let's see what they are now
echo $0 :: var1 : $var1, var2 : $var2#!/bin/bash
# demonstrate variable scope 2
# Let's verify their current value
echo $0 :: var1 : $var1, var2 : $var2
# Let's change their values
var1=flop
var2=bleh$ ./script1.sh
./script1.sh :: var1 : blah, var2 : foo
./script2.sh :: var1 : blah, var2 :
./script1.sh :: var1 : blah, var2 : fooقراءة البيانات
دع المستخدم يقدم البيانات
#!/bin/bash
# Ask the user for their city
echo Hello, which city are you from?
read varcity
echo It\'s nice to meet someone from $varcity$ ./introduction.sh
Hello, which city are you from?
Mansoura
It's nice to meet someone from Mansoura#!/bin/bash
# Ask the user for login details
read -p 'Username: ' uservar
read -sp 'Password: ' passvar
echo
echo Thank you $uservar, we now have your login details$ ./login.sh
Username: student
Password:
Thank you student, we now have your login detailsتوقع الخرج عندما يكتب المستخدم أربع سيارات، ثم سيارتين فقط.
#!/bin/bash
# Demonstrate how read actually works
echo What cars do you like?
read car1 car2 car3
echo Your first car was: $car1
echo Your second car was: $car2
echo Your third car was: $car3$ ./cars.sh
What cars do you like?
Jaguar Maserati Bentley Lotus
Your first car was: Jaguar
Your second car was: Maserati
Your third car was: Bentley Lotus
$ ./cars.sh
What cars do you like?
Jaguar Maserati
Your first car was: Jaguar
Your second car was: Maserati
Your third car was:#!/bin/bash
# A basic summary of my sales report
echo Here is a summary of the sales data:
echo ====================================
echo
cat /dev/stdin | cut -d' ' -f 2,3 | sort$ cat salesdata.txt | ./summary.sh
Here is a summary of the sales data:
====================================
apples 20
oranges 5
peaches 7
watermelons 12| الطريقة | الأفضل عندما |
|---|---|
| وسائط سطر الأوامر | معظم السكربتات: تحفظ في سجل الأوامر، ويسهل على السكربتات الأخرى استدعاؤها |
read | يجب ألا تبقى البيانات في سجل الأوامر، مثل كلمة المرور |
| STDIN | السكربت مرشح (filter) في خط أنابيب (pipeline) |
الأعداد الصحيحة
الجمع والطرح والضرب والقسمة
يحفظ let النتيجة في متغير. توقع ./let_example.sh 15
#!/bin/bash
# Basic arithmetic using let
let a=5+4
echo $a
let "a = 5 + 4"
echo $a
let a++
echo $a
let "a = 4 * 5"
echo $a
let "a = $1 + 30"
echo $a$ ./let_example.sh 15
9
9
10
20
45expr يطبع النتيجة. توقع ./expr_example.sh 12
#!/bin/bash
# Basic arithmetic using expr
expr 5 + 4
expr "5 + 4"
expr 5+4
expr 5 \* $1
expr 11 % 2
a=$( expr 10 - 3 )
echo $a$ ./expr_example.sh 12
9
5 + 4
5+4
60
1
7$ expr 5 * 4
expr: syntax error: unexpected argument ‘args.sh’
$ expr 5 \* 4
20الطريقة الموصى بها. توقع الأعداد السبعة.
#!/bin/bash
# Basic arithmetic using double parentheses
a=$(( 4 + 5 )); echo $a
a=$((3+5)); echo $a
b=$(( a + 3 )); echo $b
b=$(( $a + 4 )); echo $b
(( b++ )); echo $b
(( b += 3 )); echo $b
a=$(( 4 * 5 )); echo $a$ ./expansion2.sh
9
8
11
12
13
16
20| المعامل | المعنى |
|---|---|
+ - * / | الجمع، والطرح، والضرب، والقسمة |
% | الباقي بعد القسمة |
var++ var-- | إضافة 1، وطرح 1 |
b += 3 | اختصار للتعبير b = b + 3 |
${#var} | طول القيمة (بالأحرف) |
$ echo $(( 7 / 2 )) $(( 7 % 2 ))
3 1
$ echo $(( 2 * 3 + 4 )) $(( 2 * (3 + 4) ))
10 14
$ a='Hello World'
$ echo ${#a}
11اختيار المسار
اتخاذ القرارات
#!/bin/bash
# Basic if statement
if [ $1 -gt 100 ]
then
echo Hey that\'s a large number.
pwd
fi
date$ ./if_example.sh 15
Fri Sep 25 12:13:04 PM UTC 2026
$ ./if_example.sh 150
Hey that's a large number.
/home/student/lab11
Fri Sep 25 12:13:05 PM UTC 2026[ اسم آخر للأمر test، ولذلك يحتاج إلى مسافات مثل أي أمر
$ [5 -lt 12]
bash: [5: command not found
$ [ 5 -lt 12]
bash: [: missing `]'
$ [ 5 -lt 12 ]
$ echo $?
0كل مثال أدناه صحيح (تحققنا من كل واحد منها بالأمر echo $?)
| المعامل | يكون صحيحا عندما | مثال |
|---|---|---|
-eq | يساوي عدديا | [ 5 -eq 5 ] |
-gt | أكبر من | [ 9 -gt 5 ] |
-lt | أصغر من | [ 3 -lt 8 ] |
-ge | أكبر من أو يساوي | [ 7 -ge 7 ] |
-le | أصغر من أو يساوي | [ 4 -le 6 ] |
| الاختبار | يكون صحيحا عندما |
|---|---|
S1 = S2 | النصان متساويان |
S1 != S2 | النصان غير متساويين |
-n S | S غير فارغ |
-z S | S فارغ |
| الاختبار | يكون صحيحا عندما يكون المسار |
|---|---|
-e P | موجودا |
-d P | موجودا وهو مجلد |
-s P | موجودا وغير فارغ |
-w P | موجودا وقابلا للكتابة |
-x P | موجودا وقابلا للتنفيذ |
لا يطبع test شيئا؛ بل تجيب حالة خروجه: 0 صحيح، و1 خطأ. توقع كل $?.
$ test 001 = 1
$ test 001 -eq 1
$ touch myfile; test -s myfile
$ ls /etc > myfile; test -s myfile$ test 001 = 1
$ echo $?
1
$ test 001 -eq 1
$ echo $?
0$ touch myfile
$ test -s myfile
$ echo $?
1
$ ls /etc > myfile
$ test -s myfile
$ echo $?
0توقع التشغيلات الثلاثة أدناه.
#!/bin/bash
# elif statements
if [ $1 -ge 18 ]
then
echo You may go to the party.
elif [ $2 == 'yes' ]
then
echo You may go to the party but be back before midnight.
else
echo You may not go to the party.
fi$ ./if_elif.sh 20 no
$ ./if_elif.sh 16 yes
$ ./if_elif.sh 16 no$ ./if_elif.sh 20 no
You may go to the party.
$ ./if_elif.sh 16 yes
You may go to the party but be back before midnight.
$ ./if_elif.sh 16 no
You may not go to the party.توقع الخرج للأعداد 150 و151 و50.
#!/bin/bash
# Nested if statements
if [ $1 -gt 100 ]
then
echo Hey that\'s a large number.
if (( $1 % 2 == 0 ))
then
echo And is also an even number.
fi
fi$ ./nested_if.sh 150
Hey that's a large number.
And is also an even number.
$ ./nested_if.sh 151
Hey that's a large number.
$ ./nested_if.sh 50توقع الخرج للرمز والعمر 1100 5 و1100 45 و1200 45
#!/bin/bash
echo "Enter your code"
read code
echo "Enter your age"
read age
if [[ $age -ge 18 && $code -eq '1100' ]]
then
echo "You are eligible to see the movie"
else
echo "You are not eligible to see the movie"
fi| الرمز | العمر | الخرج |
|---|---|---|
| 1100 | 5 | You are not eligible to see the movie |
| 1100 | 45 | You are eligible to see the movie |
| 1200 | 45 | You are not eligible to see the movie |
#!/bin/bash
# case example
case $1 in
start) echo starting ;;
stop) echo stopping ;;
restart) echo restarting ;;
*) echo don\'t know ;;
esac$ ./case2.sh start
starting
$ ./case2.sh stop
stopping
$ ./case2.sh restart
restarting
$ ./case2.sh pause
don't knowدورك
نحو 30 دقيقة: توقع على الورق، ثم اكتب سكربتاتك وشغلها
نحو 5 دقائق
#!/bin/bash
a=7
b=3
echo '$a + $b'
echo "$a + $b"
echo $(( a + b )) $(( a / b )) $(( a % b ))
expr $a \* $b
let "c = a * b - 1"
echo $c ${#c}$ ./practice1.sh
$a + $b
7 + 3
10 2 1
21
20 2$a + $b حرفيا7 / 3 يساوي 2، و7 % 3 يساوي 1expr إلى \*؛ وc = 7 * 3 - 1 = 20، وعدد أحرفها 2نحو 5 دقائق
test 5 -lt 12test abc = ABCtest 010 -eq 10test 010 = 10test -z ""test -e nofile.txt (لا يوجد ملف بهذا الاسم)$ test 5 -lt 12
$ echo $?
0
$ test abc = ABC
$ echo $?
1
$ test 010 -eq 10
$ echo $?
0$ test 010 = 10
$ echo $?
1
$ test -z ""
$ echo $?
0
$ test -e nofile.txt
$ echo $?
1نحو 8 دقائق
larger.sh؛ وهو يأخذ عددين وسيطين في سطر الأوامرThe larger number is N مع العدد الأكبرBoth numbers are N./larger.sh 17 42 و42 17 و9 9#!/bin/bash
# print the larger of two numbers
if [ $1 -gt $2 ]
then
echo "The larger number is $1"
elif [ $1 -lt $2 ]
then
echo "The larger number is $2"
else
echo "Both numbers are $1"
fi$ ./larger.sh 17 42
The larger number is 42
$ ./larger.sh 42 17
The larger number is 42
$ ./larger.sh 9 9
Both numbers are 9نحو 10 دقائق
bill.sh؛ واسأل بالأمر read -p عن سعر القطعة الواحدة وعن الكميةTotal: T بالصيغة $(( )) واطبعه500 أو أكثر، فاطبع خصما بنسبة 10% (total / 10) والمبلغ المطلوب دفعهNo discount, to pay: T120 x 3 ثم 200 x 3#!/bin/bash
# a shop bill with a discount
read -p "Price of one item: " price
read -p "Quantity: " qty
total=$(( price * qty ))
echo "Total: $total"
if [ $total -ge 500 ]
then
discount=$(( total / 10 ))
echo "Discount: $discount"
echo "To pay: $(( total - discount ))"
else
echo "No discount, to pay: $total"
fi$ ./bill.sh
Price of one item: 120
Quantity: 3
Total: 360
No discount, to pay: 360
$ ./bill.sh
Price of one item: 200
Quantity: 3
Total: 600
Discount: 60
To pay: 540#!/bin/bash أولا، ثم chmod 755، ثم ./script.shname=value بلا مسافات؛ و$name يقرؤه؛ وعلامات التنصيص المزدوجة تستبدل، والمفردة لا تستبدل$1 $# $@ من سطر الأوامر، وread -p / read -s من لوحة المفاتيح، و/dev/stdin من أنبوب$(( )) هي الطريقة المفضلة للحساب؛ والنتائج أعداد صحيحة[ ] هو test: حالة الخروج 0 تعني صحيح؛ و-eq يقارن الأعداد، و= يقارن النصوصif / elif / else / fi، مع الربط بـ&& و||، أو case للأنماطMahmoud Abas|برمجة Bash، الجزء 1: المتغيرات والإدخال والعمليات الحسابية وجمل if