Upload
coby
View
91
Download
1
Embed Size (px)
DESCRIPTION
תרגול מס' 2. כתיבת תסריטים ב- bash בקרת תהליכים ב- UNIX שאלות ממבחנים. תסריטים. הרצת תסריטים מבני בקרה ב- bash דוגמאות השוואה בין C ו- bash. אוטומטיזציה. נניח (מקרה היפותטי לחלוטין) שברשותנו קבצי בדיקה ופלט לתכנית שלנו וברצוננו לבדוק את נכונות התכנית מול קבצים אלו - PowerPoint PPT Presentation
Citation preview
2תרגול מס' -כתיבת תסריטים בbash-בקרת תהליכים בUNIXשאלות ממבחנים
2מבוא לתכנות מערכות - 234122
תסריטים
הרצת תסריטים-מבני בקרה בbashדוגמאות השוואה ביןC-ו bash
3מבוא לתכנות מערכות - 234122
אוטומטיזציה
נניח )מקרה היפותטי לחלוטין( שברשותנו קבצי בדיקה ופלט לתכניתשלנו וברצוננו לבדוק את נכונות התכנית מול קבצים אלו
פקודות לכל בדיקה3צריך לכתוב
גם עם שימוש במנגנון ההיסטוריה הרצת הבדיקותמעיקה ולוקחת הרבה זמן מיותר
:של הרצת הפקודות. ניצור קובץ אשר יכיל אוטומטיזציההפתרון " לפיו יורצו כל הפקודות לפי הסדרתסריט"
> mtm_rentals < test1.in > tmpout 2> tmperr> diff expout1 tmpout> diff experr1 tmperr
4מבוא לתכנות מערכות - 234122
sourceהרצת תסריט בעזרת
ניתן להריץ קובץ המכיל פקודותBash להלן( - תסריטscript על ידי )sourceהפקודה
-הפקודות יבוצעו בShell כאילו נכתבו בשורת הפקודה אחת אחרי הנוכחיהשניה
echo Running test 1mtm_rentals < test1.in > tmpout 2> tmperrdiff expout1 tmpoutdiff experr1 tmperrecho Running test 2mtm_rentals < test2.in > tmpout 2> tmperrdiff expout2 tmpoutdiff experr2 tmperrecho Running test 3mtm_rentals < test3.in > tmpout 2> tmperrdiff expout3 tmpoutdiff experr3 tmperr
run_tests> source run_testsRunning test 1Running test 2Running test 3
5מבוא לתכנות מערכות - 234122
תסריטי אתחול
בהתחברות של משתמש למערכת מורץ התסריט.login אשר בתיקית הבית של המשתמש
בפתיחתShell חדש של Bash מורץ התסריט .bashrc הרצות תסריטי האתחול מתבצעות באמצעותsource ולכן הן משפיעות ,
Shellעל מצב ה-
PATH=$PATH:.alias ll="ls -l"alias cdex2="cd ~mtm/public/1011a/ex2"alias GCC="gcc -std=c99 -Wall \
-pedantic-errors -Werror"
.bashrc# welcome messageecho ------ Welcome `whoami` !-------- echo You are in `pwd` directory of \ `hostname`echo OS is `uname -s`# echo disk usage is `du -sh | cut -f1`echo `who | wc -l` users are logged inecho Today is `date`
.login
6מבוא לתכנות מערכות - 234122
הרצת תסריט כקובץ הרצה
:ניתן להריץ תסריט כפקודה התסריט יש להוסיף את השורהבתחילת–
#!/bin/bash שהשורה הראשונה בקובץ מגדירה את התכנית לביצוע Unix מסמן ל-#!•
שאר הפקודות בקובץ
•/bin/bash הוא שם התכנית לביצוע הפקודות, במקרה שלנוBash
בנוסף יש להוסיף הרשאת ריצה לקובץ–
כעת ניתן להריץ את התסריט כמו תכנית רגילה–
בניגוד להרצה באמצעות פקודתsourceתהליך התסריט יבוצע בShell אשר יסתיים בסוף ריצת התסריטחדש
7מבוא לתכנות מערכות - 234122
הרצת תסריט כקובץ הרצה
:נמיר את תסריט הרצת הבדיקות שלנו לקובץ הרצה
מתחיל: התסריטבעיה חדשה להסתבך, הוספת בדיקות נוספות
משכפלת קוד בתסריט ולא נוחה )ייתכנו אלפי בדיקות(נשתמש במבני בקרה )תנאים ולולאות( בדומה לשפת פתרון :C
#!/bin/bashecho Running test 1mtm_rentals < test1.in > tmpout 2> tmperrdiff expout1 tmpoutdiff experr1 tmperrecho Running test 2mtm_rentals < test2.in > tmpout 2> tmperrdiff expout2 tmpoutdiff experr2 tmperrecho Running test 3mtm_rentals < test3.in > tmpout 2> tmperrdiff expout3 tmpoutdiff experr3 tmperr
run_tests> chmod a+x run_tests> ./run_testsRunning test 1Running test 2Running test 3
8מבוא לתכנות מערכות - 234122
מבני בקרה
Bash למשל במבני בקרה מאפשרת שימוש(while -וif בתסריטים )ובשורת הפקודה
בדומה למבני הבקרה שבשפת בתנאיםמבני הבקרה משתמשים Cהשוואת ערכי מספרים–
השוואת מחרוזות–
ועוד...–
נעבור על מספר מבני בקרהותנאים שימושיים
> for ((i = 1; $i < 10; i++ )); do> if (($i % 3 == 0)); then> echo 3 divides $i> fi> done3 divides 33 divides 63 divides 9
9מבוא לתכנות מערכות - 234122
while ניתן ליצור לולאותwhile -בbash:
while <expression>; do<command1><command2>...
done
< ממשיך להתקייםexpressionהפקודות בגוף הלולאה יבוצעו כל עוד >–
מהטרמינלישירות כמו שאר מבני הבקרה ניתנות לביצוע whileלולאות –
#!/bin/bashi=1while (( i <= 3)); do echo Running test $i mtm_rentals < test${i}.in \ > tmpout 2> tmperr diff expout${i} tmpout diff experr${i} tmperr let i++done
run_tests
> ./run_testsRunning test 1Running test 2Running test 3
> i=1> while (( i <= 3)); do> echo $i> let i++> done123
10מבוא לתכנות מערכות - 234122
for-שימוש נוסף בfor:הוא מעבר על על איברי המערך
for <varname> in <array> ; do<command1><command2>...
done
<varnameהוא שם המשתנה שיכיל בכל פעם איבר מהרשימה ><arrayהיא רשימה של מחרוזות >העדיפו להשתמש בשיטה זו על פני שימוש מפורש באינדקסים
11מבוא לתכנות מערכות - 234122
for לולאתfor משמשת בדומה לשפת Cלמעבר נוח יותר על תחום מספרים
#!/bin/bashfor ((i = 1; i <= 3; i++)); do echo Running test$i mtm_rentals < test${i}.in > tmpout 2> tmperr diff expout$i tmpout diff experr$i tmperrdone
run_tests
> ./run_testsRunning test1.inRunning test2.inRunning test3.in
12מבוא לתכנות מערכות - 234122
if-ניתן להגדיר בbashמשפטי תנאי בשתי גרסאות
if <expression>; then <command1> <command2> ...
fi
ניתן להוסיףelseופקודות אשר יתבצעו אם התנאי אינו מתקיים if <expression>; then
<commands>
else <commands>fi
> i=1> if (( $i > 0 )); then> echo POSITIVE> else> echo NEGATIVE > fiPOSITIVE
13מבוא לתכנות מערכות - 234122
while ו-if אפשריים ב-ביטוייםקיימות מספר אפשרויות לכתיבת התנאים בלולאות ומשפטי תנאי:]] [[ ניתן לרשום תנאים בתוך
האופרטורים < ו-> משווים מחרוזות )לפי סדר לקסיקוגרפי(–
האופרטור == מאפשר התאמת מחרוזת לתבנית•
eq, -gt, -le-ניתן לבצע השוואת על ערכי מספרים בעזרת דגלים כגון –חשוב להקפיד על תו הרווח בין הסוגריים לתוכן התנאי כדי למנוע שגיאות –
bash> str1=Helloב-> if [[ $str1 == Hello ]]; then echo true; fitrue> if [[ hello == Hello ]]; then echo true; fi> if [[ 11 < 7 ]]; then echo true; fitrue> if [[ 11 -le 7 ]]; then echo true; fi
> if [[ 11 -eq 11 ]]; then echo true; fitrue> if [[ 0 -eq Hello ]]; then echo true; fitrue
זו אינה השוואת ערכים מספריים
עבור ערך שאינו מייצג 0מספר משתמשים ב-
לחישוב
14מבוא לתכנות מערכות - 234122
התאמת מחרוזות
מאפשר התאמת מחרוזת ==בתוך תנאי מהצורה ]] [[, האופרטור לתבנית
הארגומנט השמאלי הוא מחרוזת רגילה–
כמו ] [ ו-?, *אשר יכולה לכלול את הסימנים תבנית הארגומנט הימני הוא –שתואר עבור תבניות של שמות קבצים
ניתן להשתמש בגרשיים כפולים "" על מנת לבטל את המשמעות •המיוחדת של התווים הללו
== האופרטור =! הוא השלילה של אופרטור ההתאמה"end_with_z="some string with z <המשמעות של = ו-== זהה–
> if [[ "$end_with_z" = *[zZ] ]]; then echo match; fimatch> if [[ "this string start with t" = t* ]]; then echo true; fitrue> if [[ "this string doesn't start with t" = [^t]* ]]; then echo true; fi> file=test4.in> if [[ $file = test*.in ]]; then echo test file; fitest file> if [[ "string doesn't start with t" != t* ]]; then echo true; fitrue
15מבוא לתכנות מערכות - 234122
while ו-if אפשריים ב-ביטויים:בתוך ]] [[ ניתן להשתמש בתנאים מועילים נוספים, למשל
<filename>< בודק האם קיים קובץ בשם f <filename-התנאי –
<dirname< בודק האם קיימת תיקייה בשם >d <dirnameהתנאי -–
:ניתן לבדוק תנאים מורכבים יותרCניתן להשתמש באופרטורים &&, ||, ו-! כמו בשפת –
הקפידו להשאיר רווח אחרי ! כדי להימנע משגיאות בגלל מנגנון ההיסטוריה•
ניתן להשתמש בסוגריים כדי לקבוע את הקדימויות–> if [[ -f a.txt ]]; then echo file exists; fi> cat > a.txtHello world!> if [[ -f a.txt ]]; then echo file exists; fifile exists> mkdir mtm> if [[ ! (-f b.txt && -d mtm) ]]; then echo yes; fiyes
16מבוא לתכנות מערכות - 234122
while ו-if אפשריים ב-ביטויים(( ניתן להגדיר תנאי בתוך))
בתוך )) (( האופרטורים ==, =!, < ו- > מתייחסים לערכים מספריים–
אין צורך לרשום $ לפני שם משתנה–
ניתן לבצע פעולות חשבוניות–
תנאים המוגדרים בעזרת )) (( מתנהגים כמו ביצוע פעולות חשבוניות בעזרת$)) ((
> if (( 11 < 7 )); then echo true; fi> i=5> if (( i >= 0 && i <= 10 )); then echo true; fitrue> if [[ 11 -eq 11 ]]; then echo true; fitrue> if (( 0 == Hello )); then echo true; fitrue> if (( ++i == 6 )); then echo true; fitrue> if (( ++i == 6 )); then echo true; fi
17מבוא לתכנות מערכות - 234122
-כמו בCניתן לגשת לפרמטרים המועברים בשורת הפקודה לתסריט -הפרמטר הn לתסריט נקרא פשוט n וניתן לקרוא אותו על ידי ,$n*$יוחלף ברשימת כל הארגומנטים לתסריט
אם ייתכנו רווחים בתוך הארגומנטים ניתן להשתמש ב-"$@" כדי לשמור על –מספר האגומנטים הנכון
$0יוחלף בשם התסריט #$יוחלף במספר הארגומנטים
> echo_script aaa bbb ccccommand: echo_script3 argumentsparameter 1 : aaaparameter 2 : bbbparameter 3 : ccc
העברת פרמטרים בשורת הפקודה
#!/bin/bashecho command: $0echo $# arguments let number=1for param in $*; do echo parameter $((number++)) : $paramdone
echo_script
18מבוא לתכנות מערכות - 234122
פונקציות
-ניתן להגדיר בbash:פונקציות בצורה כזו function <name> {
<commands>
}
פונקציה חייבת להכיל לפחות פקודה אחת–
השימוש בפונקציה יכול להתבצע רק אחרי הגדרתה–
אפשר להעביר לפונקציה ארגומנטים–
הפונקציה משתמשת בהם בדומה לשימוש•בארגומנטים המועברים לתסריט
הפונקציה אינה יכולה לגשת לארגומנטים•של התסריט שקרא לה
19מבוא לתכנות מערכות - 234122
פונקציות
כדי ליצור משתנה מקומי בפונקציה יש להכריז עליו תחילה עםlocal:
> using_localoriginal_a original_boriginal_a surprise_b
#!/bin/bashfunction surprise { local a=surprise_a b=surprise_b}a=original_ab=original_becho $a $bsurpriseecho $a $b
using_local
20מבוא לתכנות מערכות - 234122
פונקציות
ניתן "להחזיר" ערכים מפונקציה בעזרתcommand subsitution (backticks):
> sum_numbers 1 2 3 4 515
#!/bin/bashfunction sum { local result=0 for num in $*; do let result+=$num done echo $result}n=`sum $*`echo $n
sum_numbers
ביטוי זה יוחלף בסכום הרצוי
21מבוא לתכנות מערכות - 234122
קריאת קלט
ניתן לקרוא שורה מהקלט הסטנדרטי על ידיread <flags> <variable name>
השורה תיקלט לתוך שם המשתנה שהוגדר–
יחלק את השורה לפי מילים לתוך מערךaהדגל -–
הביטויread על ידי יוחלף bash בשורת קלט שתיקלט מהקלט הסטנדרטי
> read lineHello world> echo $lineHello world> read -a lineHello world> echo $lineHello> echo ${line[*]}Hello world
22מבוא לתכנות מערכות - 234122
עבודה עם קבצים
דרך פשוטה לקריאת קובץ היא על ידי שימוש בהפניית קלט ושימוש:readב-
:דרך פשוטה לקרוא קובץ שורה אחר שורה היא כך#!/bin/bashcounter=0while read line; do echo $line let counter++done < "$1"echo $counter
lines_counter
> cat hello.txtHello world!> read line < hello.txt> echo $lineHello world!
> cat lines.txtfirst linesecond line> lines_counter lines.txt first linesecond line2
23מבוא לתכנות מערכות - 234122
חלוקה פונקציונלית של תסריטים
-שימו לב שניתן להשתמש בbash כדי לערבב תסריטים עם תכניות בקלותבשפות שונות שנכתבו
scripting languagesמכאן מגיע כוחן של שפות תסריטים - –
ניתן להעביר פרמטרים לתסריטי עזרבעזרת פרמטרים בשרות הפקודה–
pipelineבעזרת –בעזרת קבצים זמניים–
ניתן לקבל ערכים חזרה מתסריטי עזרבעזרת פלט מתסריט העזר–
24מבוא לתכנות מערכות - 234122
העברת והחזרת ערכים
העברת פרמטרים לתסריטי עזריכולה להתבצע בדרכים הבאות
שורת הפקודהב–helper_script $arg1 $arg2
pipelineבעזרת –echo $arg1 $arg2 | helper_script
דרך קובץ זמני–echo $arg1 $arg2 > temp
helper_script < temp
החזרת ערכים מתסריטי העזריכולה להתבצע בעזרת
backticksשימוש ב-–result=`helper_script`
pipelineהעברה לתסריט אחר ב-–helper_script | another_script
דרך קובץ זמני–helper_script > temp
25מבוא לתכנות מערכות - 234122
exit ניתן להשתמש בפקודהexit-על מנת לצאת מה shell הנוכחי ולהחזיר
ערך יציאה נבחר:
exit [status] ומייצג "הצלחה" של התוכנית. כל ערך אחר 0ערך בררת המחדל הוא –
)מספר שלם( אמור לייצג כישלון.
בכל רגע נתון ערך היציאה האחרון שמור במשתנה?$
> ./example_scripthi> echo $?1> echo $?0
#!/bin/bashecho "hi"exit 1echo "bye"
example_script
26מבוא לתכנות מערכות - 234122
דוגמה
כתבו תסריט בשם search אשר מקבל מחרוזת ושמות קבצים ומדפיס את כל השורות המופיעות בקבצים הללו המכילות את המחרוזת המבוקשת
אם מתקבל שם תיקיה, ייבדקו כל הקבצים תחת התיקיה הזו רקורסיבית–
> search Blue scene35.txtscene35.txt : 37 : LAUNCELOT: Blue.scene35.txt : 55 : GALAHAD: Blue. No yel-- Auuuuuuuugh!> search swallow scene*.txtscene1.txt : 50 : GUARD #1: But then of course African swallows are not migratory.scene1.txt : 54 : GUARD #2: Wait a minute -- supposing two swallows carried it together?scene35.txt : 63 : BEDEMIR: How do know so much about swallows?> search cow farmsfarms/animals/animals.txt : 8 : cowfarms/farm1.txt : 2 : cow Betsyfarms/farm1.txt : 3 : slim cow Dazyfarms/farm1.txt : 4 : fat cow Burgerfarms/farm1.txt : 5 : two cows Dartsy & Teofarms/farm2.txt : 2 : cow Lenifarms/farm2.txt : 4 : cow Oreo
27מבוא לתכנות מערכות - 234122
פתרון נכתוב תסריט בשםsearch
התסריט ישתמש בפונקצית עזרהקוראת קובץ ומוצאת את השורות
המתאימות בעזרת התאמת מחרוזות
#!/bin/bashfunction search_file { n=1 while read line; do if [[ $line = *"$1"* ]]; then echo “${2} : ${n} : $line” fi let n++; done < "$2"}for file in ${*:2}; do if [[ -f "$file" ]]; then search_file "$1" $file fi if [[ -d "$file" ]]; then search "$1" $file/* fidone
search
28מבוא לתכנות מערכות - 234122
דוגמה נוספת נתון קובץ בשםfootball.txt המכיל
נתונים על שערים שהובקעו במשחקי כדורגל
כל שורה בקובץ מציינת שם שלשחקן, מספר השערים שהבקיע
במשחקשנערך בתאריך מסוים, שם הקבוצהבה הוא שיחק ושם הקבוצה היריבה
ברצוננו לכתוב תסריט בשםplayer אשר יקבל כפרמטר שם של שחקן
וידפיס את כל השורות עבורו ואת סכוםfootball.txtמהקובץ
מספר השערים שהבקיע
Alon Miz. 2 23/10/93 Macabi-Haifa Macabi-Tel-AvivIzak Zoh. 1 12/11/93 Macabi-Tel-Aviv Hapoel-Beer-ShevaRonen Ha. 3 27/12/93 Hapoel-Tel-Aviv Macabi-Tel-AvivReuven A. 2 12/11/93 Macabi-Haifa Hapoel-Tel-AvivEyal Ber. 1 20/11/93 Macabi-Haifa Macabi-Tel-Aviv Izak Zoh. 1 12/11/93 Macabi-Tel-Aviv Hapoel-HaifaAlon Miz. 2 26/10/93 Macabi-Haifa Beitar-JerusalemIzak Zoh. 2 12/12/93 Macabi-Tel-Aviv Macabi-HiafaAlon Miz. 2 23/12/93 Macabi-Haifa Macabi-Pet-TikvaRonen Ha.3 27/11/93 Hapoel-Tel-Aviv Macabi-Haifa
football.txt
> player "Alon Miz."Alon Miz. 2 23/10/93 Macabi-Haifa Macabi-Tel-AvivAlon Miz. 2 26/10/93 Macabi-Haifa Beitar-JerusalemAlon Miz. 2 23/12/93 Macabi-Haifa Macabi-Pet-TikvaTotal number of goals: 6
29מבוא לתכנות מערכות - 234122
פתרון
נשתמש בתסריטsearchשכתבנו מקודם כדי לקבל רק את השורות
הרלוונטיות
נכתוב פונקצית עזר בשםcalc_totalאשר תקרא את השורות מהקלט
הסטנדרטי שלה ותסכום את מספרהגולים של השחקן תוך כדי הדפסתן
#!/bin/bashfunction calc_total { sum=0 while read -a line; do let sum+=${line[6]} echo ${line[*]:4} done echo "total number of goals: $sum"}
search "$1" football.txt | calc_total
player
30מבוא לתכנות מערכות - 234122
דוגמה שלישית
כתבו תסריט לדירוג שחקנים בשםbest_player אשר יקבל רשימה של שמות שחקנים בשורת הפקודה וידפיס את שם השחקן שהבקיע את מרב
הגוליםאם קיימים מספר שחקנים שהבקיעו את מרב הגולים יודפסו שמות כל –
השחקנים
לכל שחקן יש להדפיס את שמו ומספר הגולים שהבקיע–
> best_player "Alon Miz." "Izak Zoh." "Ronen Ha." "Reuven A."Alon Miz. 6Ronen Ha. 6
פתרון
23412231מבוא לתכנות מערכות -
max_goals=0for player in "$@"; do goals=`sum_player_goals "$player"` if (( goals > max_goals )); then max_goals=$goals fidonefor player in "$@"; do goals=`sum_player_goals "$player"` if (( goals >= max_goals )); then echo "$player" $max_goals fidone
#!/bin/bash# Sums the goals from lines in# the correct formatfunction sum_goals { local sum=0 while read -a line; do let sum+=${line[6]} done echo $sum}
# Sums all the goals of target playerfunction sum_player_goals { ./search "$1" football.txt | sum_goals}
best_player
32מבוא לתכנות מערכות - 234122
C ל-bashהשוואה בין Bash שפת תסריטים היא -scripting language
.Perl, Tcl, Python, Rubyשפות תסריטים נוספות: –
C שפת תכנות מערכת היא -system programming language#.C++, Java, Cשפות מערכת נוספות: –
33מבוא לתכנות מערכות - 234122
C ל-bashהשוואה בין של יתרונות bash על C:
מחרוזות ומשתניםעבודה נוחה עם –
(7" תכניות קיימות )עוד על כך בתרגול להדביקנוח "–
משמעותית לחלק מהמשימותקצרקוד –
על דברים לא צריך להכריז אין קומפיילר -–
של חסרונות bash לעומת C:אין בדיקותאין קומפיילר - –
מאפשר באגים מסוכנים
)לעתים פי כמה מאות( איטית–
-נבחר בbash מטלות פשוטות וקצרות שזמן הביצוע שלהן לא עבורקריטי
read deposits account_balance=100for d in ${deposits[*]}; do acount_balance=$((account_balance + d))doneecho $account_balance
34מבוא לתכנות מערכות - 234122
bashסיכום -
כדי לחסוך ביצוע חוזר וידני של פעולות ניתן ליצור תסריטים המכילים או הפיכתם לקובץ הרצהsourceרצף פקודות שימושי ולהריצם בעזרת
-בbash קיימים מבני הבקרה while , for ו if המאפשרים כתיבת קוד מתקדם בתסריטים
-ניתן לגשת לפרמטרים לשרות הפקודה של תסריט בדומה לתכנית בC-כדי לקרוא מהקלט הסטנדרטי בbash נשתמש בפקודה read ניתן לחלק תסריטים לפונקציות ולהעביר מידע ביניהן ע"י קריאת טקסט
בפונקציה וכתיבתו לפלט נוח להדביק תסריטים ביחד בעזרתpipeline-ו command substitution כדי
לפתור בקלות בעיות-נשתמש בbash עבור מטלות פשוטות שאינן דורשות חישובים רבים, עבור
Cשאר המטלות נמשיך להשתמש ב-
35מבוא לתכנות מערכות - 234122
UNIXבקרת תהליכים ב-
הרצה בחזית וברקעפקודות לניהול תהליכים
36מבוא לתכנות מערכות - 234122
Unixריבוי תהליכים ב-Unix( היא מערכת הפעלה התומכת בריבוי תהליכים multi-tasking)
חובה עבור מערכת שנועדה לשירות מספר רב של משתמשים בו זמנית–
תהליך הוא הרצה של תכנית כלשהיניתן להריץ תכנית יחידה במספר תהליכים במקביל–
בניגוד למנשק גרפי בו השליטה במספר תהליכים אינטואיטיבית עבורעבודה בטרמינל יש להכיר מספר פקודות וקיצורים
37מבוא לתכנות מערכות - 234122
הרצה בחזית וברקעShellיחיד יכול להריץ מספר תהליכים בו זמנית
כל התהליכים מדפיסים את הפלט שלהם לערוצי הפלט הסטנדרטיים–
רק תהליך אחד יכול להשתמש בערוץ הקלט הסטנדרטי–
רץ בחזיתתהליך אשר מקושר לערוץ הקלט הסטנדרטיכדי להריץ תהליך בחזית יש להפעילו כרגיל–
> command ולא ניתן להכניס פקודות חדשותpromptכל עוד תהליך רץ בחזית אין גישה ל-–
רצים ברקעתהליכים שאינם מקושרים לקלט הסטנדרטיניתן להריץ תהליך ברקע על ידי הוספת & לסוף הפקודה–
> command &
במצב זה התהליך אינו רץ אך מצבו נשמר בזיכרון מושההתהליך יכול להיות גם ,ונוכל להמשיך את הרצתו כשנרצה
38מבוא לתכנות מערכות - 234122
בדיקת מצב תהליכים
הפקודהjobs-מדפיסה את רשימת התהליכים המורצים תחת ה Shell> jobs
לכל תהליך מוצג מספר מזהה, מצבו ושם הפקודה-מייצג את התהליך "הנוכחי"+סימן ה
תהליך זה יהווה את ברירת המחדל לפקודות טיפול בתהליכים–
-מייצג את התהליך הבא בתור להיות +-סימן ה
#!/bin/bashwhile [[ true ]]; do sleep 1 echo Loop $1!done
loop> ./loop 1 &[1] 3692> Loop 1!./loop 2 &[2] 3711Loop 2!Loop 1!
כאשר מספר תהליכים מוציאים פלט בו זמנית
הטרמינל מתבלגן במהירות
המספר בסוגריים המרובעים הוא מספר
Shellהתהליך תחת ה-
39מבוא לתכנות מערכות - 234122
שליחת אותות לתהליך בחזית
כדי לשנות את מצב הריצה של התהליך הרץ בחזית ניתן לשלוח אותותבעזרת קיצורים מהמקלדת
Ctrl+Cהורג )מפסיק( את התהליך אשר בחזית :
Ctrl+Zמשהה את התהליך אשר בחזית :התהליך מפסיק לרוץ אך מצבו נשמר–
40מבוא לתכנות מערכות - 234122
פקודות לניהול תהליכים
ניתן להחזיר תהליך לריצה בחזית בעזרתfg> fg [process]
ניתן להחזיר תהליך לריצה ברקע בעזרתbg> bg [process]
ניתן להשהות תהליך על ידיsuspend > suspend <process>
ניתן להרוג תהליך על ידי הפקודהkill> kill <process>
% ניתן לציין מספר תהליך ע"י –
<str%>< ע"י strניתן להריץ את התהליך ששמו מתחיל ב->–
אם קיימים שני תהליכים מתאימים הפקודה תיכשל•
+: אם לא צוין מספר תהליך יוחזר התהליך שמסומן ב-bg ו-fgעבור –
41מבוא לתכנות מערכות - 234122
- סיכוםUnixבקרת תהליכים ב-
ריצה בחזית מושהה
ריצה ברקע
מופסק
Ctrl+Z
fg
fg
kill
kill
Ctrl+C bg
suspend
הרצה רגילה
& הרצה עם
42מבוא לתכנות מערכות - 234122
שאלות ממבחנים - bash
שימוש בתכניות סטנדרטיות שלUnixבתסריטים
43מבוא לתכנות מערכות - 234122
(21.7.95 )1שאלה
-כתוב תכנית בbashששמה arrange אשר מעבירה קבצים מהתיקיהלתוך תתי-תיקיות לפי הכללים הבאים:)שאינם תיקיות( הנוכחית
:לכל קובץ שאינו תיקיה האותיות הראשונות 4אם קיימת תת-תיקיה לתיקיה הנוכחית ששמו זהה ל-1.
להעברתבשם הקובץ, הקובץ יועבר לתוך התיקיה. )שים לב שהכוונה הקובץ ולא להעתקתו(.
בתיקיה לפחות שני קבצים נוספים לא מתקיים, וקיימים 1אם תנאי 2. 4 האותיות הראשונות בשמם זהות ל-4הנוכחית שאינם תיקיות, כך ש-
האותיות הראשונות בשם הקובץ, התוכנית תיצור תת-תיקיה חדשה ששמה האותיות הראשונות בשם הקובץ, והקובץ יועבר לתוך תת-תיקיה זו. 4זהה ל-
44מבוא לתכנות מערכות - 234122
( - דוגמה21.7.95 )1שאלה :במדריך הנוכחי קיימים הקבצים הבאיםfile1 file2 file3 prog1 prog2 prog script1 script2 כאשר רק
הינו תיקיהprogהקובץ
לאחר הפעלת התוכניתarrange :בתיקיה הנוכחית, יהיו הקבצים הבאים בתיקיה זו file script1 script2 prog:כאשר
–file – ו progהינם תיקיות
יהיו הקבציםfileבתיקיה –file1 file2 file3
יהיו הקבציםprogבתיקיה –prog1 - ו prog2בנוסף(
לקבצים שהיו בתוכו לפני(. arrangeהפעלת התוכנית
file1 file2 file3 script1 script2 prog prog1 prog2
file1 file2 file3 prog1 prog2
file script1 script2 prog
45מבוא לתכנות מערכות - 234122
פתרון
#!/bin/bashfunction files { for f in `ls`; do if [[ -f $f ]]; then echo $f fi done}function fileCount { line=( `files | cut -c1-4 | sort | uniq -c | grep $1` ) echo ${line[0]}}
function makeDir { if [[ ! -d $1 ]] ; then mkdir $1 fi}
arrange
46מבוא לתכנות מערכות - 234122
פתרוןfor file in `ls` ;do if [[ ! -f $file ]] ; then continue fi dir="`echo $file | cut -c1-4`" dirsNum=`fileCount "$dir"` if (( dirsNum > 2 )) ; then makeDir $dir fi if [[ -d $dir ]] ; then mv $file $dir fidone
arrange
47מבוא לתכנות מערכות - 234122
)מועד ג', אביב 2שאלה 2006)
חברתMoogle שהחליטה זה מכבר לפתוח סניף בחיפה, הכריזה על יום ראיונות בפקולטה ,למדעי המחשב בטכניון )אשר בהם יכולים להשתתף רק בוגרי קורס מת"ם כמובן(.
במהלך הראיונות נוכחים מספר מראיינים ובינהם גם מנהלMoogle..100 ל-0כל מראיין נותן ציון למרואיין בין –
הציון הסופי יקבע ע"י שקלול כל הציונים.–
למנהל יש זכות וטו ולא יתכן כי יתקבל לעבודה מרואיין שהמנהל החליט לא לקבל.–
:בסיום הראיונות כל מראיין מכין קובץ בפורמט הבא על האנשים אותם הוא ראיין<ID> <FULL NAME> <GRADE>
.interviewer name>.gradesהשדות מופרדים זה מזה בטאבים. שם הקובץ הינו >–
דוגמה לקובץ בשםeyal.grades:
הקובץ של מנהלMoogle ייקרא Moogle.grades:ויכול להיראות כך
031243129 Moshe Levi 60444422267 Shimon Cohen 90555782311 David David 100
031243129 Moshe Levi 57555782311 David David -NO-444422267 Shimon Cohen 80
48מבוא לתכנות מערכות - 234122
)מועד ג', אביב 2שאלה 2006)
עליכם לכתוב תסריט בשםBestToWork אשר ינתח את הקבצים הללו ויחזיר את קבוצת המרואיינים הטובים ביותר. התסריט יקבל כפרמטר את מס'
מקומות העבודה הפנויים ויחזיר מס' שכזה של מרואיינים מצטיינים ממויינים לפי מידת ההצלחה.
במקרה שאין מספיק מרואיינים שהתראיינו / עברו את הראיון, תוחזר”not enough intervieweesההודעה: "
:לדוגמה, עבור שני הקבצים שבדוגמה
:הערותהניחו כי קבצי הקלט קיימים ותקינים–
ניתן להניח שאותם מראיינים ראיינו את כל האנשים–
אין להשתמש בקבצים זמניים–
ניתן להשתמש במספר לא מוגבל של תסריטים–
> BestToWork 21) 444422267 Shimon Cohen2) 031243129 Moshe Levi> BestToWork 3not enough interviewees
49מבוא לתכנות מערכות - 234122
פתרון
#!/bin/bashfunction PrintBest { local num=1 while read -a line; do echo "${num}) ${line[0]} ${line[1]} ${line[2]}" let num++ done}function CalcOneGrade { local total_grade=0 while read -a line; do let total_grade+=${line[3]} done echo $total_grade}
BestToWork
50מבוא לתכנות מערכות - 234122
פתרון
function CalcGrades { while read -a line; do grade=`cat *.grades | grep ${line[0]} | CalcOneGrade` # $line[0] is ID, $line[1] is the first # name, $line[2] is the last name echo ${line[0]} ${line[1]} ${line[2]} $grade done}
if (( `cat Moogle.grades | grep -v "\-NO\-" | wc -l` < $1 )) ; then echo "not enough interviewees"else cat Moogle.grades | grep -v "\-NO\-" | CalcGrades | \ sort -nrk3 | PrintBest | head -$1fi
BestToWork