תרגול מס' 7

33
ססססס סס'7 - בבבבב בבבבבבב בC-Shell - בבבב בבבבבבב בUnix

description

תרגול מס' 7. כתיבת תסריטים ב- C-Shell בקרת תהליכים ב- Unix. תסריטים. הרצת תסריטים מבני בקרה ב- C-Shell דוגמאות השוואה בין C ו- C-Shell. אוטומטיזציה. נניח (מקרה היפותטי לחלוטין) שברשותנו קבצי בדיקה ופלט לתכנית שלנו וברצוננו לבדוק את נכונות התכנית מול קבצים אלו - PowerPoint PPT Presentation

Transcript of תרגול מס' 7

Page 1: תרגול מס'  7

7תרגול מס' -כתיבת תסריטים בC-Shell-בקרת תהליכים בUnix

Page 2: תרגול מס'  7

2מבוא לתכנות מערכות - 234122

תסריטיםהרצת תסריטים-מבני בקרה בC-Shellדוגמאות השוואה ביןC-ו C-Shell

Page 3: תרגול מס'  7

3מבוא לתכנות מערכות - 234122

אוטומטיזציה נניח )מקרה היפותטי לחלוטין( שברשותנו קבצי בדיקה ופלט לתכנית שלנו

וברצוננו לבדוק את נכונות התכנית מול קבצים אלו

פקודות לכל בדיקה3צריך לכתוב

גם עם שימוש במנגנון ההיסטוריה הרצת הבדיקותמעיקה ולוקחת הרבה זמן מיותר

:תסריט של הרצת הפקודות. ניצור קובץ אשר יכיל "אוטומטיזציההפתרון "לפיו יורצו כל הפקודות לפי הסדר

> (mtm_checkout < test1.in >! tmpout) >&! tmperr> diff expout1 tmpout> diff experr1 tmperr

Page 4: תרגול מס'  7

4מבוא לתכנות מערכות - 234122

sourceהרצת תסריט בעזרת ניתן להריץ קובץ המכיל פקודותC-Shell להלן( - תסריטscript על ידי )

sourceהפקודה -הפקודות יבוצעו בShell כאילו נכתבו בשורת הפקודה אחת אחרי הנוכחי

השניהecho Running test 1(mtm_checkout < test1.in >! tmpout) >&! tmperrdiff expout1 tmpoutdiff experr1 tmperrecho Running test 2(mtm_checkout < test2.in >! tmpout) >&! tmperrdiff expout1 tmpoutdiff experr1 tmperrecho Running test 3(mtm_checkout < test3.in >! tmpout) >&! tmperrdiff expout1 tmpoutdiff experr1 tmperr

run_tests> source run_testsRunning test 1Running test 2Running test 3

Page 5: תרגול מס'  7

5מבוא לתכנות מערכות - 234122

תסריטי אתחול בהתחברות של משתמש למערכת מורץ התסריט.login אשר בתיקית

הבית של המשתמש בפתיחתC-Shell חדש מורץ התסריט .cshrc הרצות תסריטי האתחול מתבצעות באמצעותsource ולכן הן משפיעות ,

Shellעל מצב ה-

set path = ($path .)set savehist=1000alias ll ls -lalias cdex2 cd ~mtm/public/1011a/ex2alias GCC gcc-std=c99 -Wall \

-pedantic-errors -Werror

.cshrc# 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

Page 6: תרגול מס'  7

6מבוא לתכנות מערכות - 234122

הרצת תסריט כקובץ הרצה:ניתן להריץ תסריט כפקודה

התסריט יש להוסיף את השורהבתחילת–#!/bin/tcsh -f

שהשורה הראשונה בקובץ מגדירה את התכנית לביצוע Unix מסמן ל-#!•שאר הפקודות בקובץ

•/bin/tcsh הוא שם התכנית לביצוע הפקודות, במקרה שלנוC-Shell•-f -מונע מהShellלהריץ תסריטי אתחול

בנוסף יש להוסיף הרשאת ריצה לקובץ–כעת ניתן להריץ את התסריט כמו תכנית רגילה–

בניגוד להרצה באמצעות פקודתsourceתהליך התסריט יבוצע בShell אשר יסתיים בסוף ריצת התסריטחדש

Page 7: תרגול מס'  7

7מבוא לתכנות מערכות - 234122

הרצת תסריט כקובץ הרצה:נמיר את תסריט הרצת הבדיקות שלנו לקובץ הרצה

התסריטבעיה חדשה :מתחיל להסתבך, הוספתבדיקות נוספות משכפלת

קוד בתסריט ולא נוחה )ייתכנו אלפי בדיקות(נשתמש במבני בקרה )תנאים ולולאות( בדומה לשפת פתרון :C

#!/bin/tcsh -fecho Running test 1(mtm_checkout < test1.in >! tmpout) >&! tmperrdiff expout1 tmpoutdiff experr1 tmperrecho Running test 2(mtm_checkout < test2.in >! tmpout) >&! tmperrdiff expout1 tmpoutdiff experr1 tmperrecho Running test 3(mtm_checkout < test3.in >! tmpout) >&! tmperrdiff expout1 tmpoutdiff experr1 tmperr

run_tests> chmod a+x run_tests> ./run_testsRunning test 1Running test 2Running test 3

Page 8: תרגול מס'  7

8מבוא לתכנות מערכות - 234122

while ניתן ליצור לולאותwhile -בC-Shell:

while (<expression>)<command1><command2>...

end< ממשיך להתקייםexpressionהפקודות בגוף הלולאה יבוצעו כל עוד >– מהטרמינלישירות כמו שאר מבני הבקרה ניתנות לביצוע whileלולאות –

#!/bin/tcsh -fset i=1while ($i <= 3) echo Running test $i (mtm_checkout < test$i.in \ >! tmpout) >&! tmperr diff expout$i tmpout diff experr$i tmperrend

run_tests> ./run_testsRunning test 1Running test 2Running test 3

> set i=1> while ($i <= 3)while? echo $iwhile? @ i++while? end123

Page 9: תרגול מס'  7

9מבוא לתכנות מערכות - 234122

foreach לולאתforeachמשמשת למעבר על רשימה בצורה נוחה

foreach <varname> (<list>)<command1><command2>...

end<varnameהוא שם המשתנה שיכיל בכל פעם איבר מהרשימה ><listהיא רשימה של מחרוזות >

#!/bin/tcsh -fforeach test (test*.in) echo Running $test (mtm_checkout < $test >! tmpout) >&! tmperr diff expout_$test tmpout diff experr_$test tmperrend

run_tests

> ./run_testsRunning test1.inRunning test2.inRunning test3.in

Page 10: תרגול מס'  7

10מבוא לתכנות מערכות - 234122

if-ניתן להגדיר בC-Shellמשפטי תנאי בשתי גרסאות בשורה יחידה ללאelse:

if (<expression>) <command>-עם אפשרות ל( עבור בלוקים של פקודותelse:)

if (<expression>) then[commands]

[else[more commands] ]

endif

Page 11: תרגול מס'  7

11מבוא לתכנות מערכות - 234122

while ו-if אפשריים ב-ביטויים ו-== על ידי מחרוזותהשוואת != על ידי ערכים מספריים השוואת>= ,<= ,> ,<

אם אחד הפרמטרים לאופרטור אינו ערך מספרי תתקבל שגיאה– התנאי-f <filename >בודק האם

<filenameקיים קובץ בשם > התנאי-d <filename >בודק האם

<filenameקיימת תיקיה בשם >עבור קדימויותסוגרייםניתן להשתמש ב ניתן להשתמש בפעולות חשבוניות על

/ ו-*, -, +ערכים מספריים כמו ניתן להשתמש באופרטורים לוגיים

! ו-&&, ||להרכבת תנאים

> set str1=Hello> if ($str1 == Hello) echo yes yes> if (7 < 20) echo yesyes> if (0 == 00) echo yes> if (0 <= 00) echo yesyes>if (-f a.txt) echo file exists> cat > a.txtHello world!> if (-f a.txt) echo file existsyes> mkdir mtm> if ( !(-f b.txt && -d mtm) ) echo yesyes

Page 12: תרגול מס'  7

12מבוא לתכנות מערכות - 234122

התאמת מחרוזות מאפשר התאמת מחרוזת לתבנית~=האופרטור

הארגומנט השמאלי הוא מחרוזת רגילה–כמו ] [ ו-?, *אשר יכולה לכלול את הסימנים תבנית הארגומנט הימני הוא –

שתואר עבור תבניות של שמות קבצים

הוא השלילה של ~=~!האופרטור > if (ends_with_z =~ *[zZ]) echo matchmatch> if ("no point in string" !~ *.*) echo no pointno point> if ("point - . - in string" !~ *.*) echo no point> set file = test4.in> if ($file =~ test*.in) echo test filetest file

Page 13: תרגול מס'  7

13מבוא לתכנות מערכות - 234122

switch ניתן ליצור מבנהswitch -בC-Shell:

switch (<string>) case <pattern1>: <cshell commands> [breaksw] ... case <pattern_n>: <cshell commands> [breaksw] [default: <cshell commands>]endsw

-הכללים בswitch תבניות מקבלים וההתאמה מתבצעת כמו עבור אופרטור ~=

אם כמה כללים מתאימים ייבחר הכלל שמתאיםהראשון

switch($c) case "[a-z]": echo small letter breaksw case "[A-Z]": echo big letter breaksw case "[0-9]": echo digit breaksw case '$': echo dollar sign breaksw default: echo neither letter nor digitendsw

Page 14: תרגול מס'  7

14מבוא לתכנות מערכות - 234122

goto ניתן להשתמש במשפטיgoto-כמו ב C

goto <label>...<label>:...

שימוש במשפטיgoto ( ולא ללא קשר לשפת התכנות) הוא תכנות רענהוג להשתמש בהם

-השימוש בgoto "קשה להבנה יוצר קוד "ספגטי

Page 15: תרגול מס'  7

15מבוא לתכנות מערכות - 234122

-כמו בCניתן לגשת לפרמטרים המועברים בשורת הפקודה לתסריט המשתנהargv מכיל את רשימת הפרמטרים לתסריט

–argv[1])הוא הפרמטר הראשון )ולא שם התסריט -דרך נוחה יותר לגשת לפרמטר הn

n$היא על ידי *$תוחלף ברשימת כל הפרמטרים

לתסריט$0תוחלף בשם התסריט

> echo_script aaa bbb ccccommand: echo_scriptparameter 1 : aaaparameter 2 : bbbparameter 3 : ccc

העברת פרמטרים בשורת הפקודה

#!/bin/tcsh -fecho command: $0set number = 1foreach param ( $* ) echo parameter $number : $param @ number++end

echo_script

איך ניתן לדעת את מספר הפרמטרים

שהתקבלו?

Page 16: תרגול מס'  7

16מבוא לתכנות מערכות - 234122

קריאת קלט ניתן לקרוא שורה מהקלט הסטנדרטי על ידי<$ <$ על ידי יוחלףהביטוי C-Shell בשורת קלט שתיקלט מהקלט

הסטנדרטי

בד"כ נשתמש בסוגריים כדי לשמור את כל שורת הקלט< set line=$<Hello world> echo $lineHello< set line=($<)Hello world> echo $lineHello world

> set input=$<Hello> echo $inputHello

Page 17: תרגול מס'  7

17מבוא לתכנות מערכות - 234122

עבודה עם קבצים-לא ניתן בC-Shell-לכתוב ולקרוא מקבצים בצורה ישירה כמו ב Cכדי לאפשר עבודה עם קבצים נשתמש בהפניות קלט/פלט ותסריטי עזר

> cat > file.txtThe dingo ate your baby> main_scriptThe first line is:The dingo ate your baby

#!/bin/tcsh -fcat file.txt | auxiliary_script

main_script

#!/bin/tcsh -fset line=($<)echo "The first line is:"echo "$line"

auxiliary_script

Page 18: תרגול מס'  7

18מבוא לתכנות מערכות - 234122

חלוקה פונקציונלית של תסריטים

-מאחר ולא ניתן להגדיר פונקציות בC-Shell נחלק את הקוד שלנו בקבצים נפרדיםלתסריטים שונים

-שימו לב שניתן להשתמש בC-Shell כדי לערבב תסריטים עם תכניות בקלות - מכאן מגיע כוחן של שפות תסריטים - בשפות שונות שנכתבו

scripting languagesניתן להעביר פרמטרים לתסריטי עזר

בעזרת פרמטרים בשרות הפקודה–pipelineבעזרת –בעזרת קבצים זמניים–

ניתן לקבל ערכים חזרה מתסריטי עזרבעזרת פלט מתסריט העזר–

Page 19: תרגול מס'  7

19מבוא לתכנות מערכות - 234122

העברת והחזרת ערכים העברת פרמטרים לתסריטי עזר

יכולה להתבצע בדרכים הבאותשורת הפקודהב–

helper_script $arg1 $arg2

pipelineבעזרת –echo $arg1 $arg2 | helper_script

דרך קובץ זמני–echo $arg1 $arg2 > temphelper_script < temp

החזרת ערכים מתסריטי העזריכולה להתבצע בעזרת

backticksשימוש ב-–set result = `helper_script`

pipelineהעברה לתסריט אחר ב-–helper_script | another_script

דרך קובץ זמני–helper_script > temp

Page 20: תרגול מס'  7

20מבוא לתכנות מערכות - 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

Page 21: תרגול מס'  7

21מבוא לתכנות מערכות - 234122

פתרון לא נוכל לקרוא את הקובץfootball.txt

ולכן ניעזר בתסריט עזרplayerישירות מתוך

ניצור את התסריטcalc_totalאשר יקבל את השורות הרלוונטיות לשחקן וידפיס את

השורות וסכום השערים

#!/bin/tcsh -fgrep "$1" football | calc_total

player

#!/bin/tcsh -fset line = ($<)set sum = 0while ($#line != 0) @ sum = $sum + $line[3] echo $line set line = ($<)endecho "total number of goals: $sum"

calc_total

התבנית הכללית של עיבוד קלט

התבנית הכללית של עיבוד קלט

התבנית הכללית של עיבוד קלט

Page 22: תרגול מס'  7

22מבוא לתכנות מערכות - 234122

דוגמה נוספת כתבו תסריט לדירוג שחקנים בשםscores אשר יקבל רשימה של שמות

שחקנים בשורת הפקודה וידפיס את דירוג השחקנים לפי מספר הגולים שהבקיעו

לכל שחקן יש להדפיס את דירוגו, שמו ומספר הגולים שהבקיע–שני שחקנים שהבקיעו מספר זהה של גולים יקבל דירוג זהה–יש להדפיס את השחקנים ממוינים בדר יורד לפי מספר הגולים שהבקיעו–

> scores "Alon Miz." "Izak Zoh." "Ronen Ha." "Reuven A."1 Alon Miz. 61 Ronen Ha. 62 Izak Zoh. 43 Reuven A. 2

Page 23: תרגול מס'  7

23מבוא לתכנות מערכות - 234122

פתרון#!/bin/tcsh -f@ i = 1while ( $i <= $#argv ) grep "$argv[$i]" football.txt | calc_score >>! temp @ i++endsort -nrk3 temp | add_ranksif (-f temp) rm -f temp

scores

#!/bin/tcsh -fset line = ($<)set sum = 0set player_name = ($line[1-2])while ($#line != 0) @ sum += $line[3] set line = ($<)endecho $player_name $sum

calc_score#!/bin/tcsh -fset line = ($<)set place = 1@ goals = $line[3]while ($#line != 0) if ($goals != $line[3]) then @ place++ @ goals = $line[3] endif echo $place $line set line = ($<)end

add_ranks

Page 24: תרגול מס'  7

24מבוא לתכנות מערכות - 234122

C ל-C-Shellהשוואה בין C-Shell שפת תסריטים היא -scripting language

.Perl, Tcl, Python, Rubyשפות תסריטים נוספות: –

C שפת תכנות מערכת היא -system programming language#.C++, Java, Cשפות מערכת נוספות: –

Page 25: תרגול מס'  7

25מבוא לתכנות מערכות - 234122

C ל-C-Shellהשוואה בין של יתרונות C-Shell על C:

מחרוזות ומשתניםעבודה נוחה עם –" תכניות קיימותלהדביקנוח "– משמעותית לחלק מהמשימותקצרקוד –על דברים לא צריך להכריז אין קומפיילר -–

של חסרונות C-Shell לעומת C:אין בדיקותאין קומפיילר - –

מאפשר באגים מסוכנים)לעתם פי כמה מאות( איטית–

-נבחר בC-Shell מטלות פשוטות וקצרות שזמן הביצוע שלהן לא עבורקריטי

set deposits = ($*)set account_balance = 100foreach d ($deposits) @ acount_balance=$account_balance + $dendecho $account_balance

Page 26: תרגול מס'  7

26מבוא לתכנות מערכות - 234122

C-Shellסיכום - כדי לחסוך ביצוע חוזר וידני של פעולות ניתן ליצור תסריטים המכילים

או הפיכתם לקובץ הרצהsourceרצף פקודות שימושי ולהריצם בעזרת -בC-Shell קיימים מבני הבקרה while, foreach, if-ו switch המאפשרים

כתיבת קוד מתקדם בתסריטים-ניתן לגשת לפרמטרים לשרות הפקודה של תסריט בדומה לתכנית בC-כדי לקרוא מהקלט הסטנדרטי בC-Shell<$-נשתמש ב -כדי לקרוא מקובץ בC-Shell-נשתמש בתסריטי עזר ו pipelineכתיבת תסריטים מסתמכת על הדבקת תסריטים ופקודות שונות-נשתמש בC-Shell ,עבור מטלות פשוטות שאינן דורשות חישובים רבים

Cעבור שאר המטלות נמשיך להשתמש ב-

Page 27: תרגול מס'  7

27מבוא לתכנות מערכות - 234122

Unixבקרת תהליכים ב-הרצה בחזית וברקע

Page 28: תרגול מס'  7

28מבוא לתכנות מערכות - 234122

Unixריבוי תהליכים ב-Unix( היא מערכת הפעלה התומכת בריבוי תהליכים multi-tasking)

חובה עבור מערכת שנועדה לשירות מספר רב של משתמשים בו זמנית–

תהליך הוא הרצה של תכנית כלשהיניתן להריץ תכנית יחידה במספר תהליכים במקביל–

בניגוד למנשק גרפי בו השליטה במספר תהליכים אינטואיטיבית עבורעבודה בטרמינל יש להכיר מספר פקודות וקיצורים

Page 29: תרגול מס'  7

29מבוא לתכנות מערכות - 234122

הרצה בחזית וברקעShellיחיד יכול להריץ מספר תהליכים בו זמנית

כל התהליכים מדפיסים את הפלט שלהם לערוצי הפלט הסטנדרטיים–רק תהליך אחד יכול להשתמש בערוץ הקלט הסטנדרטי–

רץ בחזיתתהליך אשר מקושר לערוץ הקלט הסטנדרטיכדי להריץ תהליך בחזית יש להפעילו כרגיל–

> command ולא ניתן להכניס פקודות חדשותpromptכל עוד תהליך רץ בחזית אין גישה ל-–

רצים ברקעתהליכים שאינם מקושרים לקלט הסטנדרטיניתן להריץ תהליך ברקע על ידי הוספת & לסוף הפקודה–

> command & במצב זה התהליך אינו רץ אך מצבו נשמר בזיכרון ונוכל מושההתהליך יכול להיות גם ,

להמשיך את הרצתו כשנרצה

Page 30: תרגול מס'  7

30מבוא לתכנות מערכות - 234122

בדיקת מצב תהליכים הפקודהjobs-מדפיסה את רשימת התהליכים המורצים תחת ה Shell

> jobsלכל תהליך מוצג מספר מזהה, מצבו ושם הפקודה-מייצג את התהליך "הנוכחי"+סימן ה

תהליך זה יהווה את ברירת המחדל לפקודות טיפול בתהליכים–-מייצג את התהליך הבא בתור להיות +-סימן ה

#!/bin/tcsh -fwhile ( 1 ) sleep 1 echo Loop $1!end

loop> ./loop 1 &[1] 3692> Loop 1!./loop 2 &[2] 3711Loop 2!Loop 1!

כאשר מספר תהליכים מוציאים פלט בו זמנית

הטרמינל מתבלגן במהירות

המספר בסוגריים המרובעים הוא מספר

Shellהתהליך תחת ה-

Page 31: תרגול מס'  7

31מבוא לתכנות מערכות - 234122

שליחת אותות לתהליך בחזית כדי לשנות את מצב הריצה של התהליך הרץ בחזית ניתן לשלוח אותות

בעזרת קיצורים מהמקלדת

Ctrl+Cהורג )מפסיק( את התהליך אשר בחזית :

Ctrl+Zמשהה את התהליך אשר בחזית :התהליך מפסיק לרוץ אך מצבו נשמר–

Page 32: תרגול מס'  7

32מבוא לתכנות מערכות - 234122

פקודות לניהול תהליכים ניתן להחזיר תהליך לריצה בחזית בעזרתfg

> fg [process] ניתן להחזיר תהליך לריצה ברקע בעזרתbg

> bg [process] ניתן להשהות תהליך על ידיstop

> stop <process> ניתן להרוג תהליך על ידי הפקודהkill

> kill <process>% ניתן לציין מספר תהליך ע"י –<str%>< ע"י strניתן להריץ את התהליך ששמו מתחיל ב->–

אם קיימים שני תהליכים מתאימים הפקודה תיכשל•+: אם לא צוין מספר תהליך יוחזר התהליך שמסומן ב-bg ו-fgעבור –

Page 33: תרגול מס'  7

33מבוא לתכנות מערכות - 234122

- סיכוםUnixבקרת תהליכים ב-

ריצה בחזית מושהה

ריצה ברקע מופסק

Ctrl+Z

fg

fg

kill

kill

Ctrl+C bg

stop

הרצה רגילה

& הרצה עם