1 / 61

תרגול 7

תרגול 7. תסריטים ניהול תהליכים ב- UNIX. לי-טל משיח litalma@cs.technion.ac.il נערך והורחב ע'' ודים אייזנברג. תסריטים (קבצי script ). קבצים אשר מכילים סדרה של פקודות shell מהווים מעין תוכניות הכתובות ב שפת ה- shell נכתבים ב קובץ טקסט רגיל ניתן להריץ אותם מספר פעמים אין צורך בהידור

carina
Download Presentation

תרגול 7

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. תרגול 7 תסריטים ניהול תהליכים ב-UNIX לי-טל משיח litalma@cs.technion.ac.il נערך והורחב ע'' ודים אייזנברג

  2. תסריטים (קבצי script) • קבציםאשר מכילים סדרה של פקודות shell • מהווים מעין תוכניותהכתובות בשפת ה-shell • נכתבים בקובץ טקסט רגיל • ניתן להריץ אותם מספר פעמים • אין צורך בהידור • לדוגמא, קובץ טקסט בשם clean echo “Cleaning !” rm *.o mv ex1 ex1.old

  3. הרצת תסריטים • דרך אחת - הפקודה source > source clean • תריץ את התסריט clean • במידה וקובץ clean מכיל את הפקודות מהשקף הקודם: • תודפס הודעה “Cleaning !” • יימחקו כל קבצי אובייקט בתיקייה הנוכחית • שם הקובץ ex1 ישונה לקובץ ex1.old

  4. שפת התסריטים C-shell • שפת התסריטים C-shell היא שפת תכנות לכל דבר • משתנים • כולם מאותו טיפוס - מחרוזת או רשימה של מחרוזות • פעולות אריתמטיות • רק בשלמים • לולאות(while ואחרות) • משפטי תנאי (if else) • הערות: מסימן # ועד סוף השורה • ,goto, switch ודברים אחרים בדומה לשפת C בשביל מה צריך עוד שפת תכנות ??? התשובה בסוף התרגול

  5. ניצול יכולות של C-shell • בכתיבת תסריטים ניתן להיעזר בכל היכולות שלC-shell שלמדנו : • משתנים • Alias Substitution • File name expansion • Command Substitution • backticks `` • I/O redirection • pipelining

  6. לולאות ב- C-shell: repeat • cshell מבצע את הפקודה command בדיוק count פעמים : • שימו לב שכל לולאה של C-shell ניתן להריץ גם ב- command line repeat <count> <cshell command> <repeat 3 echo Congratulations, Shifra ! Congratulations, Shifra ! Congratulations, Shifra ! Congratulations, Shifra ! >

  7. לולאות ב- C-shell: while while (<expression>) <cshell commands> end > source count10 0 1 2 3 4 5 6 7 8 9 # count10 script: @ i = 0 while ($i<10) echo $i @ i++ end

  8. לולאות ב- C-shell: foreach foreach <variable> (<list>) <cshell commands> end • הלולאה מתבצעת מספר פעמים השווה לגודל הרשימה list • בכל איטרציהשל הלולאה, המשתנה variableמקבל ערך אחד מהרשימה לפי הסדר

  9. foreach : דוגמאות # final_vote script set number = 1 foreach name (Itai Yossi Leon EinavShifra) echo for $name send the number $number @ number++ end > source final_vote for Itai send the number 1 for Yossi send the number 2 for Leon send the number 3 for Einav send the number 4 for Shifra send the number 5

  10. foreach : דוגמאות • יצירת העתק של כל קבצי c בתיקייה הנוכחית: foreach FILE (*.c) cp $FILE $FILE.back end

  11. משפטי תנאי (if ... else) • שתי גרסאות: • if עם פקודה אחת, בלי else if (<expression>) <one cshell command> • if עם כמה פקודות ועם אופציה ל-else if (<expression>) then <cshell commands> [else <cshell commands>] endif בגרסה הזאת חייבים then בגרסה הזאת חייבים then וגם endif

  12. דוגמא של if if ($votes_for_yossi > $votes_for_shifra) then echo Yossi won ! else echo Shifra won ! endif

  13. תנאים בתוך משפטי if • השוואת מחרוזות: if ($winner == "Yossi") … • השוואת מספרים: if ($votes > 1000000) … • תנאים מיוחדים ל-C-shell if (-d aaa) ... • משוערך ל-true אם התיקייהבשם aaa קיימת בתוך התיקייה הנוכחית if (-f aaa) ... • משוערך ל-true אם הקובץ בשם aaa קיים בתיקייה הנוכחית (והוא לא תיקייה)

  14. תנאים בתוך משפטי if- התאמת מחרוזות • אופרטור ~= • משוערך ל-true אם המחרוזת בצד שמאל מתאימה לתבנית בצד ימין • התבנית יכולה לכלול סימנים מיוחדים כגון: *,? או[] שמשמעותם תוארה בתרגול הקודם • השלילהשל האופרטור ~= היא ~!

  15. תנאים בתוך משפטי if:התאמה בין מחרוזות • אופרטורים =~, !~ > if (end_with_z =~ *[zZ]) echo match match > if ("no point in string" !~ *.*) echo "no point" no point > if ("point - . - in string" !~ *.*) echo "no point" >

  16. סיכום:אופרטורים בתוך משפטי if • אופרטורים של השוואה • <, >, =<, =>משווים בין מספרים • ==, =!, ~=, ~! משווים בין מחרוזות • ניתן להשתמש באופרטורים ==, =! גם להשוואה בין מספרים אך ההשוואה תתבצע בין המחרוזות שמייצגות את המספרים • למה ישוערכו הביטויים הבאים ? • 8 <= 08 • 8 >= 08 • 8 == 08 • 8 == 8 • 8 != 08 • 8 !~ 08 • 8 =~ 08

  17. סיכום:אופרטורים בתוך משפטי if • אופרטוריםלעבודה עם קבצים ותיקיות : -f,-d • אופרטורים לוגיים להרכבת תנאים • !, &&, || כמו ב-C • ניתן להשתמש בסוגריים כמו ב-C if (($winner == "Yossi") || ($winner == "Einav")) then echo the Bublil family won ! endif

  18. משפטי switch switch (<variable or string>) case <pattern1>: <cshell commands> [breaksw] case <pattern2>: <cshell commands> [breaksw] ... case <pattern_n>: <cshell commands> [breaksw] [default: <cshell commands>] endsw התאמת מחרוזות כמו באופרטור =~

  19. משפטי 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 digit endsw

  20. משפטי goto goto <label> • מבצע קפיצה למקום המסומן ב- <label>: • כמו ב-C goto error ... error: ... גם ב C-Shell וגם ב-C שימוש ב-goto נחשב לתכנות רע ! משתמשים במנגנון goto רק כשכל האלטרנטיבות האחרות יותר גרועות

  21. הפקודהprintf printf format strings • מדפיסהאת המחרוזות stringsלפי הפורמט format • הפורמט דומה לפורמט של הפקודה printf ב-C. • הפורמט יכול להכיל תווים רגילים או תווי עריכה • דוגמאות של תווי עריכה: • %s- מדפיסה את המחרוזת המתאימה מתוך הרשימה strings. • - %[-]m[.n]sמדפיסה את המחרוזת המתאימה מרשימת המחרוזות כך שהתוצאה תהיה באורך של mתווים, עם אפשרות להגבלת מספר התווים המודפסים (מתוך המחרוזת הספציפית) ל - n. המחרוזת מיושרת לימין אלא אם משתמשים באופרטור -.

  22. הפקודה printf - דוגמאות > echo $HOME /home/rotics > > printf “My files are in %s\n“ $HOME My files are in /home/rotics > > printf “number is : %10.5s” 123456789a number is: 12345 > > printf “number is : #%-10.3s# %s\n” "123456789a“ xxx number is: #123 # xxx > > printf “My files are in %s\n“ $HOME “my PC” My files are in /home/rotics My files are in my PC שימו לב מה קורה כאשר ישנן יותר מחרוזות ברשימה strings מאשר תווי עריכה(%s)

  23. הרצת תסריטים • ניתן להריץתסריטים בשתי דרכים: • ע''יהפקודה source • התסריט מתבצע בסביבה הנוכחית (ב-shell הנוכחי) • יכול לשנות את משתני הסביבה הנוכחית • ישירות • התסריט מתבצע בסביבה חדשה משלו (ב-shell חדש) • לא יכול לשנות את משתני הסביבה הנוכחית • נהוגלהריץ את התסריטים בדרך השנייה, אלא אם רוצים לשנות את משתני הסביבה הנוכחית

  24. הרצת תסריטים ישירות • לפני שמריצים תסריט בפעם הראשונה חייבים לתת לו הרשאת הרצה > chmodu+xmyscript • אחרי שיש לקובץ הרשאת הרצה, ניתן להריץ אותו בצורה ישירה: > myscript • כמובן המשתנה path צריך להכיל את התיקיה הנוכחית, אחרת צריך להריץ בצורה הבאה: > ./myscript

  25. הרצת קבצי סקריפט • כדי שהshell- הנוכחי יידע איזה shell חדש להפעיל לצורך ביצוע התסריט, יש להוסיף לתסריט שורה ראשונה • במחשבים שונים כתובת ה-shell המריץ יכולה להיות שונה • ניתן לברר מהי באמצעות הפקודה which > which tcsh /bin/tcsh #! /bin/tcsh -f אומר ל-shell לא לבצע תסריטי אתחול ולהתחיל יותר מהר כתובת ה-shell שיריץ את התסריט

  26. תסריטי אתחול • תסריטי אתחול ((setup הם תסריטים מיוחדים אשר מורצים אוטומטית ע"י המערכת בזמנים מסוימים. • .loginמבוצע עם כניסה לחשבון • .cshrcמבוצע בהתחלת הרצה של כל shell(מסוג C-Shell) • נהוג להשתמש בהם • להתאמה אישית של סביבת העבודה. למשל, • אתחול משתני סביבה נחוצים לעבודה • נתינת כינויים לפקודות (alias) • לביצוע משימותשנרצה שיבוצעו בצורה אוטומטית בזמנים של כניסה לחשבון/פתיחת shell חדש

  27. דוגמא לתסריט .cshrc set path = ($path .) alias cdex2 cd ~mtm/public/0809b/ex2 alias gccgcc -Wall -pedantic-errors -Werror set savehist=1000

  28. דוגמא לתסריט .login # welcome message echo -------------- 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 in # print a warning about Matam assignment set today = `date +%j` set assignment_day = 151 set days_in_this_year = 365 if( $today > $assignment_day) then @ remaining_days = $assignment_day + ($days_in_this_year - $today) else @ remaining_days = $assignment_day - $today endif date echo $remaining_days days until the submission of Matam assignment 2 !

  29. העברת פרמטרים לתסריטים • ניתן להעביר פרמטרים לתסריטים בדומה להעברת פרמטרים לתוכנית C • ב-C ניתן להתייחס לפרמטרים ע''י מערך argv • בתסריט C-Shellניתן להתייחס לפרמטרים בצורה הבאה: • $0- הפקודה עצמה • ${n}או ${argv[n]}- הפרמטר ה-n • $* - רשימת כל הפרמטרים • ${#argv}- מספר הפרמטרים

  30. דוגמא: echo_script #! /bin/tcsh -f echo command: $0 set number = 1 foreachparam ( $* ) echo parameter $number : $param @ number++ end > echo_scriptaaabbbccc command: ./echo_script parameter 1 : aaa parameter 2 : bbb parameter 3 : ccc

  31. קלט בשפת C-Shell : אופרטור $< • אופרטור $< • גורם לשורה שלמה להיקרא מערוץ הקלט הסטנדרטי set line = “$<“ • שורה שלמה אחת תיקרא מערוץ הקלט הסטנדרטי ותושם למשתנה line בתור מחרוזת (כולל רווחים) • נהוג לבצע ישר המרה לרשימה על ידי שימוש ב-() set line = ($<) • השורהמהקלט הסטנדרטי תופרד למילים ותושם למשתנה line בתור רשימה • אחרי הביצוע של השורה הזאת ניתן לבצע פעולות רגילות של C-Shell על רשימות : $line[1], shift, ${#line}, $line[3-]וכו' • אין דרך טבעית וישירה לקרוא מקבצים ב-C-Shell • רק מהקלט הסטנדרטי

  32. חלוקה פונקציונאלית של תסריטים • בשפת C למדנו לחלקתוכניות למודולים ופונקציות • לשיפור קריאות, שימוש חוזר בקוד וכו' • בשפת C-Shellאין פונקציות • מחלקים תסריט ל"התסריט הראשי" שמשתמש ב"תסריטי עזר" • כל "תסריט עזר" הוא תסריט בפני עצמו • ניתן להריץ אותו בנפרד • הוא יכול להשתמש בתסריטים ותוכנות אחרות

  33. תסריטים: העברת פרמטרים • בשורת הארגומנטים helper_scriptaaabbb 17 • ב-pipelineלתוך הערוץ הקלט הסטנדרטי echo aaabbb 17 | helper_script • דרך קובץ זמני echo aaabbb 17 > tmp helper_script < tmp

  34. תסריטים: ערכי חזרה • על ידי backticks set result = `helper_scriptaaabbb 17` • העברה לתסריט אחר ב-pipeline helper_scriptaaabbb 17 | another_script • דרך קובץ זמני helper_scriptaaabbb 17 > tmp

  35. קלט מקבצים • כאמור, איןב-C-shellדרך טבעית וישירה לקרוא קלט מקבצים • הדרך הטבעית היא לקרוא שורות מערוץ הקלט הסטנדרטי על ידי אופרטור $< • לכן משתמשים בשיטה הבאה : • מחלקיםאת משימת קריאת הקלט לשני תסריטים: • "התסריט הראשי" • "תסריט העזר" • התסריט הראשי ישפוך את תוכן הקובץ ב-pipelineלתסריט העזר: cat file | helper_script • או יחבר את הקובץ ישירות לערוץ הקלט הסטנדרטי: helper_script < file • תוכן הקובץ יועבר לערוץ הקלט הסטנדרטי של תסריט העזר • תסריט העזר יקרא מהקלט הסטנדרטי על ידי אופרטור $<

  36. דוגמא • נתון קובץ footballהמכיל נתונים על שערים שהובקעו במשחקי כדורגל. • כל שורה בקובץ מציינת שם של שחקן, מספר השערים שהבקיע במשחק שנערך בתאריך מסוים, שם הקבוצה בה הוא שיחק ושם הקבוצה היריבה. >cat football AlonMiz. 2 23/10/93 Macabi-Haifa Macabi-Tel-Aviv IzakZoh. 1 12/11/93 Macabi-Tel-Aviv Hapoel-Beer-Sheva Ronen Ha. 3 27/12/93 Hapoel-Tel-Aviv Macabi-Tel-Aviv Reuven A. 2 12/11/93 Macabi-Haifa Hapoel-Tel-Aviv Eyal Ber. 1 20/11/93 Macabi-Haifa Macabi-Tel-Aviv IzakZoh. 1 12/11/93 Macabi-Tel-Aviv Hapoel-Haifa AlonMiz. 2 26/10/93 Macabi-Haifa Beitar-Jerusalem IzakZoh. 2 12/12/93 Macabi-Tel-Aviv Macabi-Hiafa AlonMiz. 2 23/12/93 Macabi-Haifa Macabi-Pet-Tikva Ronen Ha. 3 27/11/93 Hapoel-Tel-Aviv Macabi-Haifa

  37. דוגמא • ברצוננו לכתוב תסריט בשם player. התסריט • יקבל כפרמטר שם מלא של שחקן • ידפיסאת כל השורותשל הקובץ football בהן מופיע שם השחקן • ובנוסף ידפיס את סכום מספר השערים שהוא הבקיע. • לדוגמא, הפלט עבור שורת הקלט AlonMiz. יהיה: > player “AlonMiz.” AlonMiz. 2 23/10/93 Macabi-Haifa Macabi-Tel-Aviv AlonMiz. 2 26/10/93 Macabi-Haifa Beitar-Jerusalem AlonMiz. 2 23/12/93 Macabi-Haifa Macabi-Pet-Tikva total number of goals: 6

  38. פתרון • בתסריט player לא נוכל לבצע קריאת קלט מהקובץ football • ולכן ניעזר בתסריט אחר בשם calc_total • התסריט playerישפוך את השורות שבהם מופיע השחקן ב-pipeline ל-calc_total • calc_totalיקרא את שורות שבהם מופיע השחקן מערוץ הקלט הסטנדרטי על ידי אופרטור $<

  39. פתרון > cat player #! /bin/tcsh-f grep "$1" football | calc-total בפונט מודגש: התבנית הכללית של עיבוד הקלט > cat calc-total #! /bin/tcsh-f set line = ($<) set sum = 0 while (${#line} != 0) @ sum = $sum + $line[3] echo $line set line = ($<) end echo "total number of goals: $sum"

  40. דוגמא נוספת • עלינו לכתוב תסריט לדירוג שחקנים בשם scores • השמות המלאים של השחקנים מועברים כפרמטרים בשורת הפקודה • הדירוג של כל שחקן ייקבע על פי מספר השערים שהוא הבקיע לפי הנתונים המוכלים בקובץ football • שני שחקנים שהבקיעו מספר זהה של שערים יקבלו דירוג זהה. • התסריט ידפיסעבור כל שחקן את דירוגו,את שמו המלא ואת מספר השערים שהבקיע

  41. תזכורת: קובץ football >cat football AlonMiz. 2 23/10/93 Macabi-Haifa Macabi-Tel-Aviv IzakZoh. 1 12/11/93 Macabi-Tel-Aviv Hapoel-Beer-Sheva Ronen Ha. 3 27/12/93 Hapoel-Tel-Aviv Macabi-Tel-Aviv Reuven A. 2 12/11/93 Macabi-Haifa Hapoel-Tel-Aviv Eyal Ber. 1 20/11/93 Macabi-Haifa Macabi-Tel-Aviv IzakZoh. 1 12/11/93 Macabi-Tel-Aviv Hapoel-Haifa AlonMiz. 2 26/10/93 Macabi-Haifa Beitar-Jerusalem IzakZoh. 2 12/12/93 Macabi-Tel-Aviv Macabi-Hiafa AlonMiz. 2 23/12/93 Macabi-Haifa Macabi-Pet-Tikva Ronen Ha. 3 27/11/93 Hapoel-Tel-Aviv Macabi-Haifa

  42. דוגמא להפעלת התסריט > scores "AlonMiz." "IzakZoh." "Ronen Ha." "Reuven A." 1 AlonMiz. 6 1 Ronen Ha. 6 2 IzakZoh. 4 3 Reuven A. 2

  43. פתרון > cat scores #! /bin/tcsh-f @ i = 1 while ( $i <= ${#argv} ) grep "${argv[$i]}" football | calc_score >>! temp @ i++ end sort -n -k 3 -r temp | calc_place if (-f temp) then rm -f temp endif

  44. פתרון > cat calc_score #! /bin/tcsh-f set line = ($<) set sum = 0 set player_name = ($line[1-2]) while (${#line} != 0) @ sum = $sum + $line[3] set line = ($<) end echo "$player_name $sum" > cat calc_place #! /bin/tcsh-f set 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

  45. C-shell לעומת C • שפת C-shell היא שפת תסריטים(scripting language) • קיימות שפות תסריטים מתקדמות יותר:Perl, Tcl, PHP, JavaScript, Python, Ruby • מזל טוב! למדתם שפת התסריטים הראשונה שלכם!

  46. C-shell לעומת C • שפת C היא שפת תכנות מערכת(system language) • קיימות שפות תכנות מערכת מתקדמות יותר:C++, Java, C#

  47. יתרונות של C-shell לעומת C • קל להריץ תוכניות אחרות • להעביר פרמטרים • לשלב פלט של תוכניות • לשלב בין תוכניות • יתרון גדול בסביבת Unix שבה יש הרבה תוכניות סטנדרטיות(sort, grep,cut) • עבודה נוחה עם קבצים • עבודה נוחה עם מחרוזות • עבודה נוחה עם משתנים ותסריטי עזר • לא צריך להגדיר טיפוסים, להכריז על משתנים ופונקציות • ניתן לפתחתוכניות בזמן קצר יותר ! • תוכנית שכתובה בשפת תסריטים יכולה להיות פי 5 קצרה יותר מאותה התוכנית שכתובה בשפת C

  48. חסרונות של C-shell לעומת C • השפה פחות בטיחותית - קל להכניס באגים • אין בדיקות טיפוסים • לא חייבים להגדיר משתנים לפני השימוש בהם • לדוגמא, איפה הבאג בקוד הבא ? • מה יודפס בסוף הריצה שלו ? set deposits = ($*) set account_balance = 100 foreach d ($deposits) @ acount_balance = $account_balance + $d end echo $account_balance

  49. חסרונות של C-shell לעומת C • זמן ביצוע של תוכנית שכתובה ב-C-shell יכול להיות פי כמה מאות ארוך יותר לעומת אותה התוכנית שכתובה ב-C

  50. שימוש ב-C-shell לעומת C • משתמשים ב-C-shell כאשר • זמן ביצוע לא קריטי • למשל כאשר המשימה מספיק קטנה כך שזמן הביצוע לא מורגש • איכות התוכנה לא קריטית • או שהתכנית מספיק קטנה כדי שיהיה אפשר למצוא בה את כל הבאגים בצורה קלה • משתמשים ב-C כאשר • זמן ביצוע חשוב • איכות התוכנה היא קריטית

More Related