في نافذة الطباعة اختر «حفظ كملف PDF» كوجهة.
نظم التشغيل 1، الدرس العملي 10
راقب البرامج العاملة، وأرسل إليها الإشارات، ورتب أولوياتها، ثم تدرب على مجموعة الأوامر التي يستخدمها مهندس DevOps كل يوم.
R وS وD وT وZ في ps وtopkill وkill -9 و-STOP و-CONTnice وrenicesudo وid وchown وgrep وsort وtail وcut وtr وsed وdiff وfind وdd وtar وdf وdu وfree وhistory وhostname وifconfig وping وtelnetالجزء 1
برنامج قيد التنفيذ
| النوع | يسمى أيضا | هل تعتمد على المستخدم؟ |
|---|---|---|
| في المقدمة | تفاعلية (interactive) | نعم: تنتظر إدخالك |
| في الخلفية | غير تفاعلية، تلقائية | لا: تعمل وحدها |
ينتظر sleep 300 مدة 300 ثانية. ويبدؤه & في الخلفية، فيعود المحث (prompt) فورا. توقع: ماذا يعرض ps الآن؟
$ sleep 300 &
[1] 953$ ps
PID TTY TIME CMD
942 pts/0 00:00:00 bash
953 pts/0 00:00:00 sleep
954 pts/0 00:00:00 ps| الحالة | الحرف | المعنى |
|---|---|---|
| قيد التشغيل | R | تعمل، أو جاهزة للعمل |
| نائمة (قابلة للمقاطعة) | S | تنتظر موردا؛ وتستيقظ لمعالجة الإشارات (signals) |
| نائمة (غير قابلة للمقاطعة) | D | تنتظر موردا؛ ولا تستيقظ للإشارات |
| موقوفة | T | استقبلت إشارة إيقاف |
| زومبي | Z | ميتة، لكن مدخلها ما زال في جدول العمليات (process table) |
الجزء 2
لقطة، وعرض حي
يضيف ps -u الأعمدة %CPU و%MEM وSTAT (الحالة). توقع حرف الحالة في كل سطر.
$ ps -u
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
student 942 0.5 0.0 7608 4440 pts/0 Ss 08:03 0:00 bash
student 953 0.0 0.0 5688 2148 pts/0 S 08:03 0:00 sleep 300
student 955 0.0 0.0 10888 4352 pts/0 R+ 08:03 0:00 ps -uلا يعرض ps وحده إلا عمليات هذه الطرفية (terminal)؛ ويعرض -A كل العمليات، حتى غير المرتبطة بها
$ ps -A
PID TTY TIME CMD
1 ? 00:00:00 bash
7 ? 00:00:00 sleep
43 pts/0 00:00:00 bash
53 pts/0 00:00:00 sleep
54 pts/0 00:00:04 yes
56 pts/0 00:00:00 ps$ ps -A | grep sleep
7 ? 00:00:00 sleep
53 pts/0 00:00:00 sleepيحدث top الجدول في الوقت الحقيقي. بدأنا sleep 300 & وyes > /dev/null & (يطبع yes الحرف y إلى الأبد؛ ويتخلص > /dev/null من الخرج). توقع S و%CPU لكل منهما.
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
54 student 20 0 5688 1976 1860 R 90.0 0.0 0:03.76 yes
53 student 20 0 5688 2024 1916 S 0.0 0.0 0:00.01 sleep| العمود | المعنى |
|---|---|
PID وUSER | معرف العملية، والمستخدم الذي يملكها |
PR وNI | أولوية الجدولة (priority)، وقيمة اللطف (العمود الرابع) |
VIRT وRES وSHR | الذاكرة الافتراضية، والذاكرة الفعلية، والذاكرة المشتركة مع العمليات الأخرى |
S | الحالة: D أو R أو S أو T أو Z |
%CPU و%MEM وTIME+ | نسبة المعالج والذاكرة RAM المستخدمة، ومجموع زمن المعالج المستهلك |
الجزء 3
إنهاء العملية وإيقافها واستئنافها
يعرض kill -L الإشارات بأرقامها (الأسطر الأولى):
$ kill -L
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM| الأمر | الإشارة | الأثر |
|---|---|---|
kill PID | 15 SIGTERM (الافتراضية) | تطلب من العملية أن تنتهي |
kill -9 PID | 9 SIGKILL | للعملية التي تتجاهل القتل العادي |
توقع خرج ps الثاني.
$ sleep 300 &
[1] 84
$ kill 84$ ps
PID TTY TIME CMD
72 pts/0 00:00:00 bash
91 pts/0 00:00:00 ps
[1]+ Terminated sleep 300يتجاهل stubborn.sh الإشارة SIGTERM. توقع خرج كل ps.
#!/bin/bash
# ignores the polite kill signal (15, SIGTERM)
trap '' TERM
while true; do
sleep 1
done$ ./stubborn.sh &
[1] 92
$ kill 92
$ ps
PID TTY TIME CMD
72 pts/0 00:00:00 bash
92 pts/0 00:00:00 stubborn.sh
104 pts/0 00:00:00 sleep
105 pts/0 00:00:00 ps
$ kill -9 92
[1]+ Killed ./stubborn.shويعرض kill -L أيضا 19 SIGSTOP و18 SIGCONT
$ kill -STOP 130
$ ps -u
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
student 130 0.0 0.0 5688 2024 pts/0 T 08:06 0:00 sleep 300
[1]+ Stopped sleep 300
$ kill -CONT 130
$ ps -u
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
student 130 0.0 0.0 5688 2024 pts/0 S 08:06 0:00 sleep 300العملية sleep 300 موقوفة (T). نرسل kill الافتراضي. توقع: هل اختفت؟ ثم نرسل -CONT.
$ sleep 300 &
[1] 366
$ kill -STOP 366
$ kill 366$ ps -u
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
student 366 0.0 0.0 5688 112 pts/0 T 08:39 0:00 sleep 300
$ kill -CONT 366
[1]+ Terminated sleep 300ينشئ (sleep 1 & exec sleep 60) & عملية أب (sleep 60) تنتهي عمليتها الابن بعد ثانية واحدة ولا يجمعها أبدا. توقع ما يفعله kill -9 بالزومبي.
$ ps -u
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
student 188 0.0 0.0 5688 2136 pts/0 S 08:07 0:00 sleep 60
student 189 0.0 0.0 0 0 pts/0 Z 08:07 0:00 [sleep] <defunct>$ kill -9 189
$ ps -u
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
student 189 0.0 0.0 0 0 pts/0 Z 08:07 0:00 [sleep] <defunct>
$ kill 188
$ ps -u
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
student 178 0.6 0.0 7608 4276 pts/0 Ss 08:07 0:00 bash
student 204 0.0 0.0 10888 4308 pts/0 R+ 08:07 0:00 ps -u
[1]+ Terminated ( sleep 1 & exec sleep 60 )يختار -o الأعمدة؛ وPPID هو معرف العملية الأب. تشغيل آخر للأمر نفسه:
$ (sleep 1 & exec sleep 60) &
[1] 896
$ ps -o pid,ppid,stat,cmd
PID PPID STAT CMD
889 888 Ss bash
896 889 S sleep 60
897 896 Z [sleep] <defunct>
899 889 R+ ps -o pid,ppid,stat,cmdالجزء 4
من يحصل على المعالج أولا
قيمة الأولوية للعملية هي قيمة اللطف (niceness)
$ nice --help | head -4
Usage: nice [OPTION] [COMMAND [ARG]...]
Run COMMAND with an adjusted niceness, which affects process scheduling.
With no COMMAND, print the current niceness. Niceness values range from
-20 (most favorable to the process) to 19 (least favorable to the process).-20 إلى 19؛ والقيمة الافتراضية `0`nice -n [value] [command]renice [value] -p PID$ nice -n 10 sleep 300 &
[1] 32
$ top -b -n 1 -p 32
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
32 student 30 10 5688 1932 1824 S 0.0 0.0 0:00.00 sleep
$ renice 15 -p 32
32 (process ID) old priority 10, new priority 15كل سطر من أسطر top في هذا الدرس العملي يخضع لقاعدة واحدة. توقع PR عندما تكون NI = 10 و15 و5.
| NI | PR | ظهرت في |
|---|---|---|
10 | 20 + 10 = 30 | nice -n 10 sleep 300 |
15 | 20 + 15 = 35 | بعد renice 15 |
5 | 20 + 5 = 25 | بعد sudo renice 5 (المثال التالي) |
قيمة لطف العملية الآن 15. ونطلب 5 بصفتنا المستخدم student. توقع الرد.
$ renice 5 -p 32renice: failed to set priority for 32 (process ID): Permission denied
$ sudo renice 5 -p 32
[sudo] password for student:
32 (process ID) old priority 15, new priority 5الجزء 5
التطوير والتشغيل فريقا واحدا
فريق التطوير
يخطط، ويصمم، ويبني
فريق التشغيل
يختبر، وينفذ
التخطيط
البرمجة
Git (التحكم في الإصدارات)
البناء
Maven، Gradle
الاختبار
Selenium
النشر
Ansible، Docker، Kubernetes
المراقبة
Nagios
Git، Selenium، Docker، Nagios، Jenkins. توقع مرحلة كل منها.
| الأداة | المرحلة |
|---|---|
| Git | البرمجة: التحكم في الإصدارات (version control)، أي مستودع للإصدارات تدمج عند الحاجة |
| Selenium | الاختبار: الاختبار الآلي |
| Docker | النشر (مع Ansible وKubernetes) |
| Nagios | مراقبة المنتج بعد النشر |
| Jenkins | التكامل المستمر: إرسال الشيفرة للبناء والاختبار |
الجزء 6
تشغل معظم الشركات خوادمها على لينكس؛ وتعمل هذه الأوامر بالطريقة نفسها في آلتك الافتراضية، وعلى الخادم، وداخل حاوية (container)
يشغل sudo أمرا واحدا بصلاحيات الجذر (المستخدم الخارق، superuser)
$ id
uid=1001(student) gid=1001(student) groups=1001(student),27(sudo)
$ sudo groupadd devops
[sudo] password for student:
$ sudo useradd -m deploy
$ sudo usermod -g devops deploy
$ id deploy
uid=1002(deploy) gid=1002(devops) groups=1002(devops)| الأمر | ما يفعله |
|---|---|
sudo useradd -m NAME | يضيف مستخدما (مع مجلد رئيسي) |
sudo groupadd NAME | يضيف مجموعة (group) |
sudo usermod -g GROUP NAME | يعين المجموعة الأساسية للمستخدم |
sudo userdel وgroupdel | يحذف المستخدم، والمجموعة |
id -u و-g و-G و-n | معرف المستخدم، ومعرف المجموعة، وكل المجموعات، والأسماء |
chown [OWNER][:[GROUP]] FILE؛ وإعطاء ملف لغيرك يحتاج إلى sudo
$ ls -l servers.txt
-rw-r--r-- 1 student student 105 Sep 25 08:03 servers.txt
$ sudo chown deploy servers.txt
$ ls -l servers.txt
-rw-r--r-- 1 deploy student 105 Sep 25 08:03 servers.txt
$ sudo chown root:devops servers.txt
$ ls -l servers.txt
-rw-r--r-- 1 root devops 105 Sep 25 08:03 servers.txtفي app.log 10 أسطر (INFO وWARN وERROR، وسطر واحد فيه info بأحرف صغيرة). توقع كل رقم.
$ grep -c ERROR app.log
$ grep info app.log
$ grep -i info app.log
$ grep -c -v INFO app.log| الأمر | الإجابة | السبب |
|---|---|---|
grep -c ERROR | 3 | يعد -c الأسطر المطابقة |
grep info | سطر واحد (1) | حالة الأحرف مهمة: السطر ذو الأحرف الصغيرة فقط |
grep -i info | 5 أسطر | يتجاهل -i حالة الأحرف |
grep -c -v INFO | 6 | يبقي -v الأسطر الخالية من النمط |
يحتوي ports.txt الأرقام 8080 22 443 5432 80 3306، رقما في كل سطر. توقع خرج sort وsort -n.
$ sort ports.txt
22
3306
443
5432
80
8080$ sort -n ports.txt
22
80
443
3306
5432
8080تنمو السجلات (logs) من أسفل، ولذلك يقرأ DevOps النهاية أولا
$ tail -n 3 app.log
2026-09-25 09:05:44 WARN db1 disk usage 85 percent
2026-09-25 09:06:10 INFO web1 deploy version 2.4 finished
2026-09-25 09:07:02 ERROR web1 out of memory
$ tail -n +9 app.log
2026-09-25 09:06:10 INFO web1 deploy version 2.4 finished
2026-09-25 09:07:02 ERROR web1 out of memory
$ tail -c 20 app.log
web1 out of memory$ cut -c1-2 servers.txt
we
db
we
ca
ba
$ cut -d , -f 1,3 servers.txt
web1,8080
db1,5432
web2,8080
cache1,6379
backup1,22يقرأ tr من أنبوب، لا من اسم ملف
$ cat servers.txt | tr a-z A-Z
WEB1,CAIRO,8080,4
DB1,MANSOURA,5432,16
WEB2,ALEXANDRIA,8080,4
CACHE1,CAIRO,6379,8
BACKUP1,MANSOURA,22,32
$ echo "web1 db1 cache1" | tr -s " "
web1 db1 cache1
$ echo "web1 web2 db1" | tr -d 0-9
web web dbتوقع ما يعرضه cat servers.txt بعد الأمر sed.
$ sed 's/8080/9090/' servers.txt
web1,cairo,9090,4
db1,mansoura,5432,16
web2,alexandria,9090,4
cache1,cairo,6379,8
backup1,mansoura,22,32$ cat servers.txt
web1,cairo,8080,4
db1,mansoura,5432,16
web2,alexandria,8080,4
cache1,cairo,6379,8
backup1,mansoura,22,32توقع معنى كل سطر من الخرج.
$ diff config.old config.new
1c1
< port=8080
---
> port=9090
3c3
< debug=true
---
> debug=false
4a5
> timeout=30$ find . -name "*.log"
./app.log
./logs/old/web-0924.log
./logs/web.log
$ ls -i app.log
4456513 app.log
$ find . -inum 4456513
./app.log
$ find . -name "*.log" -ok rm {} \;
< rm ... ./app.log > ? n
< rm ... ./logs/old/web-0924.log > ? n
< rm ... ./logs/web.log > ? y$ dd if=/dev/zero of=disk.img bs=1M count=5
5+0 records in
5+0 records out
5242880 bytes (5.2 MB, 5.0 MiB) copied, 0.013896 s, 377 MB/s
$ dd if=/dev/urandom of=key.bin bs=16 count=1
1+0 records in
1+0 records out
16 bytes copied, 0.000774319 s, 20.7 kB/sc ينشئ، وt يعرض، وx يستخرج، وz يمرر عبر gzip، وf ملف الأرشيف
$ tar czf lab10.tar.gz app.log servers.txt notes.txt
$ tar tzf lab10.tar.gz
app.log
servers.txt
notes.txt
$ mkdir restore
$ tar xzf lab10.tar.gz -C restore
$ ls restore
app.log notes.txt servers.txt$ gzip app.log
$ ls -l app.log*
-rw-r--r-- 1 student student 264 Sep 25 10:31 app.log.gz-h: أحجام سهلة القراءة؛ وdu -s: سطر ملخص واحد
$ df -h /
Filesystem Size Used Avail Use% Mounted on
overlay 916G 822G 52G 95% /
$ du -h /var/log
40K /var/log/apt
304K /var/log
$ du -sh /var/log
304K /var/log$ free -m
total used free shared buff/cache available
Mem: 31866 30491 398 471 2276 1375
Swap: 24575 24575 0$ history 5
177 dd if=servers.txt of=upper.txt conv=ucase
178 cat upper.txt
179 free -m
180 free -g
181 history 5$ hostname
ubuntu-lab$ ifconfig -s
Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
eth0 1500 43 0 0 0 3 0 0 0 BMRU
lo 65536 0 0 0 0 0 0 0 0 LRUيتوقف -c 4 بعد 4 حزم؛ وبدونه أوقف ping بالضغط على Ctrl+C
$ ping -c 4 google.com
PING google.com (142.251.27.138) 56(84) bytes of data.
64 bytes from cv-in-f138.1e100.net (142.251.27.138): icmp_seq=1 ttl=109 time=47.4 ms
64 bytes from cv-in-f138.1e100.net (142.251.27.138): icmp_seq=2 ttl=109 time=49.8 ms
64 bytes from cv-in-f138.1e100.net (142.251.27.138): icmp_seq=3 ttl=109 time=46.8 ms
64 bytes from cv-in-f138.1e100.net (142.251.27.138): icmp_seq=4 ttl=109 time=46.7 ms
--- google.com ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3003ms
rtt min/avg/max/mdev = 46.666/47.683/49.815/1.263 msخدمة تجريبية تستمع على المنفذ (port) 8080؛ ولا شيء يستمع على 9090. توقع نتيجتي telnet.
$ telnet localhost 8080
Trying ::1...
Connection failed: Connection refused
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
$ telnet localhost 9090
Trying ::1...
Connection failed: Connection refused
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refusedالجزء 7
نحو 30 دقيقة: ثلاثة تمارين على الورق، ثم مهام في آلتك الافتراضية
نحو 6 دقائق
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
student 563 0.7 0.0 7608 4436 pts/0 Ss 09:03 0:00 bash
student 571 0.0 0.0 5688 2088 pts/0 S 09:03 0:00 sleep 500
student 572 0.0 0.0 5688 1984 pts/0 T 09:03 0:00 sleep 700
student 579 98.1 0.0 5688 1920 pts/0 R 09:03 0:03 yes
student 580 0.0 0.0 5688 2036 pts/0 S 09:03 0:00 sleep 90
student 581 0.0 0.0 0 0 pts/0 Z 09:03 0:00 [sleep] <defunct>
student 582 0.0 0.0 10888 4476 pts/0 R+ 09:03 0:00 ps -ukill 572؟ وبعد kill -CONT 572؟572 (T). والتي تستخدم المعالج: 579، أي yes (R، 98.1%)581 (Z، <defunct>). لا يستطيع kill إزالتها؛ والحل إنهاء عمليتها الأب، 580 (sleep 90)، التي يعرضها ps -o pid,ppid,stat,cmd في العمود PPIDkill 572: لا شيء بعد، فالعملية الموقوفة تحتفظ بالإشارة. kill -CONT 572: تستأنف وتصبح Terminatedنحو 6 دقائق
nice -n 19 sleep 100 & العملية ذات المعرف 615. ما قيمتا NI وPR لها؟student: renice 10 -p 615. ماذا يحدث؟sudo renice -20 -p 615. ما قيمتا NI وPR الآن؟student: nice -n -5 sleep 1. ماذا يحدث؟$ top -b -n 1 -p 615 | tail -2
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
615 student 39 19 5688 2132 2024 S 0.0 0.0 0:00.00 sleep
$ renice 10 -p 615
renice: failed to set priority for 615 (process ID): Permission denied$ sudo renice -20 -p 615
[sudo] password for student:
615 (process ID) old priority 19, new priority -20
$ top -b -n 1 -p 615 | tail -2
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
615 student 0 -20 5688 2132 2024 S 0.0 0.0 0:00.00 sleep
$ nice -n -5 sleep 1
nice: cannot set niceness: Permission deniedنحو 10 دقائق. الملف deploy.log:
09:10 OK build web1
09:12 FAIL test web1
09:15 OK build web2
09:16 ok test web2
09:20 FAIL deploy web2
09:25 OK deploy web1FAIL؟ok بأي حالة أحرف، مع أرقام الأسطرFAILRETRY مكان FAIL في الخرج فقط$ grep -c FAIL deploy.log
2
$ grep -n -i ok deploy.log
1:09:10 OK build web1
3:09:15 OK build web2
4:09:16 ok test web2
6:09:25 OK deploy web1
$ grep FAIL deploy.log | cut -d " " -f 4
web1
web2cut -d " " -f 3 deploy.log: build test build test deploy deploysed 's/FAIL/RETRY/' deploy.log: يتغير سطران، ولا يتغير الملفtail -n 2 deploy.log: سطرا 09:20 و09:25نحو 8 دقائق
app.log وstubborn.sh من صفحة الدرس؛ ونفذ chmod +x stubborn.shsleep 600 & و./stubborn.sh &؛ وجد معرفي العمليتين بالأمر ps -usleep بالخيار -STOP، وتحقق من T، واستأنفها، ثم أنهها بالأمر killstubborn.sh: أي إشارة تنجح؟nice -n 5 sleep 600 &، واقرأ PR وNI في top، ثم نفذ عليها renice 12grep ERROR app.log | cut -d " " -f 4 | sort وتحقق منه في الأداة التفاعليةps لقطة (snapshot)، وtop عرض حيR قيد التشغيل، وS/D نائمة، وT موقوفة، وZ زومبيkill الإشارة 15 (SIGTERM، ويمكن تجاهلها)؛ ويرسل kill -9 الإشارة SIGKILL؛ ويوقف -STOP مؤقتا ويستأنف -CONT-20 إلى 19؛ وPR = 20 + NI؛ ولا يخفضها إلا الجذرgrep وcut وsort وtail وsed وdiff السجلات وملفات الإعدادات؛ ويؤرشف tar؛ وتفحص df وdu وfree وifconfig وping وtelnet الجهازMahmoud Abas|أوامر لينكس، الجزء 2: العمليات وأوامر DevOps