340 likes | 534 Views
תרגול מס' 7. כתיבת תסריטים ב- bash שאלות ממבחנים בקרת תהליכים ב- UNIX. תכניות סטנדרטיות ב- UNIX. grep cut wc tee. head tail sort uniq. echo printf. תכניות סטנדרטיות ב- UNIX. אופי העבודה בטרמינל וקיום כלים נוחים להרכבת פקודות מעודדים יצירת תכניות בסיסיות הניתנות להרכבה
E N D
תרגול מס' 7 כתיבת תסריטים ב-bash שאלות ממבחנים בקרת תהליכים ב-UNIX
תכניות סטנדרטיות ב-UNIX grep cut wc tee • head • tail • sort • uniq • echo • printf מבוא לתכנות מערכות - 234122
תכניות סטנדרטיות ב-UNIX • אופי העבודה בטרמינל וקיום כלים נוחים להרכבת פקודות מעודדים יצירת תכניות בסיסיות הניתנות להרכבה • קיים מגוון בסיסי של תכניות הזמינות בכל מערכת הפעלה ממשפחת UNIX • צורת ההפעלה של התכניות היא בד"כ מהצורה הבאה: > <command> [options] [input file] • לרוב הפקודות, אם לא יצוין קובץ קלט, הקלט ילקח מהקלט הסטנדרטי (למה?) • בד"כ ניתן להחליף את הסדר בין שם קובץ הקלט לדגלים • זכרו כי מלבד הדגלים שילמדו כאן ניתן למצוא רשימה מפורטת שלהם ע"י שימוש בפקודה man מבוא לתכנות מערכות - 234122
תזכורת • הפקודה lsמדפיסה את הקבצים המבוקשים > ls [options] [files] • אם פלט הפקודה מופנה לקובץ כל קובץ יופיע בשורה נפרדת • אם מצוינים שמות קבצים ותיקיות כפרמטרים: • כל קובץ יודפס למסך • לכל תיקיה יודפס תוכנה • אם לא מצוינים פרמטרים מלבד דגלים הפקודה פועלת על התיקיה נוכחית • הפקודה catמדפיסה את תוכנם של קבצים למסך > cat [files] • אם לא מצוין שם קובץ הקלט נלקח מהקלט הסטנדרטי • אם מצוינים מספר קבצים הם מודפסים אחד אחרי השני לפלט מבוא לתכנות מערכות - 234122
הפקודה head • הפקודה head מדפיסה רק את תחילת הקלט: > head [-n#] [files] • מדפיסה את # השורות הראשונות בקלט • אם לא מוגדר מספר יודפסו 10 שורות • אם המספר שהוגדר שלילייודפסו כלהשורות מלבד # השורות האחרונות • עבור מספר חיובי ניתן לרשום גם -# > head –n+2 a_file a line 1 a line 2 > head –n+1 < b_file b line 1 > head –n-2 a_fileb_file ==> a_file <== a line 1 a line 2 a line 3 ==> b_file <== b line 1 a_file b_file a line 1 a line 2 a line 3 a line 4 a line 5 b line 1 b line 2 b line 3 מבוא לתכנות מערכות - 234122
הפקודה tail • הפקודה tail מדפיסה רק את סוף הקלט: > tail [-/+#] [files] • עבור -# מדפיסה את # השורות האחרונות בקלט • עבור +# מדפיסה החל מהשורה ה-# • ברירת המחדל היא הדפסת 10 השורות האחרונות • כיצד נדפיס את שורות2-3 מקובץ מסוים? > tail -2 a_file a line 4 a line 5 > tail +2 a_file a line 2 a line 3 a line 4 a line 5 > tail -1 a_fileb_file ==> a_file <== a line 5 ==> b_file <== b line 3 a_file b_file a line 1 a line 2 a line 3 a line 4 a line 5 b line 1 b line 2 b line 3 > head -3 a_file | tail -2 a line 2 a line 3 מבוא לתכנות מערכות - 234122
הפקודה sort • הפקודה sort מדפיסה את הקלט ממוין (לפי שורות) > sort [options] [files] • -n: ממיינת מספרים לפי ערכם • -r: מדפיסה את התוצאות בסדר יורד (ברירת המחדל היא סדר עולה) • -k#: מתייחס לכל שורה החל מהמילה ה-# • המילים ממסופרות החל מ-1 • -f: מתעלם מהבדלי uppercase/lowercase • -b: מתעלם מרווחים בתחילת השורה • -s: מבצע מיון יציב - שומר על הסדר המקורי בין שורות שערכן שווה מבוא לתכנות מערכות - 234122
sort - דוגמאות > sort data Father World for who > sort -f data Father for who World > sort -r data who for World Father sort -rf data World who for Father > sort numbers 11 2 > sort -n numbers 2 11 > ls-l total 4 -rw------- 1 romanoroot 520 Nov 8 23:09 data -rw------- 1 romano 368 43 Nov 8 23:12 ex1 -rw------- 1 romano 368 428 Nov 8 23:22 ex2 -rw------- 1 romano 368 322 Nov 10 13:30 ex3 > ls-l | sort -rnk5 -rw------- 1 romano root 520 Nov 8 23:09 data -rw------- 1 romano 368 428 Nov 8 23:22 ex2 -rw------- 1 romano 368 322 Nov 10 13:30 ex3 -rw------- 1 romano 368 43 Nov 8 23:12 ex1 total 4 data numbers World who for Father 2 11 מבוא לתכנות מערכות - 234122
הפקודה uniq • הפקודה uniq מדפיסה עותק יחיד של שורות זהות סמוכות > uniq [options] [input [output]] • עבור קובץ ממוין שורות זהות לא יודפסו יותר מפעם אחת • הפקודה אינה במבנה הסטנדרטי - היא מקבלת את הקלט מקובץ יחיד והארגומנט הנוסף ישמש לקובץ הפלט • -c: מדפיס כל שורה פעם אחת ואת מספר העותקים שלה • -d: מדפיס רק שורות המופיעות יותר מפעם אחת • -u: מדפיס רק שורות המופיעות פעם אחת בלבד • ניתן להשתמש רק באחת האפשרויות מבין -c/-d/-u בבת אחת • -#: התעלם מ-# המילים הראשונות (בקבלת ההחלטה האם שורות זהות) מבוא לתכנות מערכות - 234122
uniq - דוגמאות > sort names | uniqAlex Dan Elena Ofra Uri > sort names | uniq -u Alex Dan Elena > sort names | uniq-d Ofra Uri > sort names | uniq-c 1 Alex 1 Dan 1 Elena 2 Ofra 3 Uri > uniqfile3one two three one > uniq file3 list > cat list one two three one > uniq sentences This is sparta! It is sparta! Bye bye sparta! > uniq -1 sentences This is sparta! Bye bye sparta! > uniq -2 sentences This is sparta! names file3 sentences Uri Dan Uri Elena Alex Ofra Uri Ofra one two two three three three one one This is sparta! It is sparta! Bye byesparta! מבוא לתכנות מערכות - 234122
הפקודה grep • הפקודה grep מחפשת ביטויים בתוך קבצים > grep [options] <expression> [files] • ניתן לחפש מילים מסוימות או ביטויים מורכבים • מדפיסה את כל השורות בקובץ המכילות את הביטוי שהוגדר • -v: מדפיסה את השורות בהן לא מופיע הביטוי • -i: מתעלם מהבדלי uppercase/lowercase • :-w מדפיסה את כל השורות בהן <expression> מופיע בדיוק (לא כתת מחרוזת) • -n: הדפס את השורות ואת מספרן בקבצים • -l: הדפס רק את שמות הקבצים בהן נמצאו שורות מתאימות • -c: הדפס רק את כמות השורות שנמצאו בכל קובץ ללא הדפסת השורות עצמן • הביטוי לחיפוש יכול להיות מורכב יותר ממילה פשוטה: • כדי לחפש מחרוזת עם רווחים יש להוסיף גרשיים • התו ^ מייצג תחילת שורה והתו $ את סוף השורה • ניתן לחפש ביטויים מורכבים יותר, לשם כך הסתכלו בקובץ ה-man של grep מבוא לתכנות מערכות - 234122
grep - דוגמאות > grep cow farm1 cow Betsy slim cow Dazy two cows Dartsy & Teo > grep -v cow farm1 goat Upton Fat Cow Burger horse Admiral > grep -i cow farm1 cow Betsy slim cow Dazy Fat Cow Burger two cows Dartsy & Teo > grep -w cow farm1 cow Betsy slim cow Dazy > grep "slim cow" farm1 slim cow Dazy > grep ^cow farm1 cow Betsy > grep cow farm1 farm2 farm1:cow Betsy farm1:slim cow Dazy farm1:two cows Dartsy & Teo farm2:cow Leni farm2:cow Oreo > grep -n cow farm1 farm2 farm1:2:cow Betsy farm1:3:slim cow Dazy farm1:5:two cows Dartsy & Teo farm2:2:cow Leni farm2:4:cow Oreo > grep -l cow farm1 farm2 farm1 farm2 > grep -c cow farm1 farm2 farm1:3 farm2:2 > grep o$ farm1 two cows Dartsy & Teo farm1 farm2 goat Upton cow Betsy slim cow Dazy Fat Cow Burger two cows Dartsy & Teo horse Admiral sheep Brook cow Leni goat Aster cow Oreo מבוא לתכנות מערכות - 234122
הפקודה cut • הפקודה cutמשמשת להפרדת עמודות מתוך הקלט > cut <options> [files] • -c<list>: הדפס רק את התוויםבשורה המתאימים לאינדקסים המבוקשים • -f<list>: הדפס רק את השדותבשורה המתאימים לאינדקסים המפורטים • השדות בשורה מופרדים כברירת מחדל ע"י Tab • אם התו המפריד אינו קיים בשורה תודפס כל השורה • -d"?": השתמש בתו שהוגדר כתו המפריד (עבור שימוש באפשרות -f) • רשימת האינדקסים המבוקשים מורכבת ממספר אינדקסים מופרדים בפסיק, כאשר בנוסף ניתן לבקש טווח אינדקסים ע"י שימוש בתו - (מקף) • למשל: -c1,2,5-6,10- ידפיס את התווים, 1, 2, 5, 6, ו-10 ומעלה • אם האינדקסים המבוקשים מחוץ לתחום תודפס שורה ריקה מבוא לתכנות מערכות - 234122
cut - דוגמאות > cut -c1-3,5,8-10 file1 a11a a1 b21b b2 c31c c3 > cut -d" " -f2,4 file1 a12 a14 b22 b24 c32 c34 > cut -d":" –f1 file2 a11 b21 c31 c32 c33 > cut -d":" –f3 file2 a13 c31 c32 c33 > cut -d" " -f-2,4- file1 a11 a12 a14 a15 b21 b22 b24 b25 c31 c32 c34 c35 file1 file2 a11 a12 a13 a14 a15 b21 b22 b23 b24 b25 c31 c32 c33 c34 c35 a11:a12:a13 b21:b22 c31 c32 c33 מבוא לתכנות מערכות - 234122
הפקודה wc • הפקודה wcמשמשת לספירת תווים, מילים או שורת בקלט > wc [options] [files] • -c: מדפיסה את מספר התווים בלבד • -l: מדפיסה את מספר השורות בלבד • -w: מדפיסה את מספר המילים בלבד • אם לא צוין דגל מסוים wc מדפיסה אתכל שלושת המספרים • אם הפקודה מופעלת על מספר קבציםמודפסת גם שורת סיכום > wc -w war_and_peace 590234 war_and_peace > wc -l war_and_peace 55480 war_and_peace > wc -c war_and_peace 3348543 war_and_peace > wc mtm_ex1.h 120 641 4161 mtm_ex2.h > wc mtm_ex1.h parsing_example.c 120 641 4161 mtm_ex2.h 136 692 4543 parsing_example.c 256 1333 8704 total מבוא לתכנות מערכות - 234122
הפקודה tee • הפקודה tee משמשת לשכפול הפלט > tee [options] [files] • משכפלת את הקלט הסטנדרטי ומדפיסה אותו לפלט הסטנדרטי ולכל אחד מהקבצים ברשימה [files] • -a: משרשרת לקבצים במקום לכתוב אותם מחדש • מבנה הפקודה אינו סטנדרטי, היא מקבלתקלט רק מהקלט הסטנדרטי > head -3 a_file | tee file1 file2 | tail -2 a line 2 a line 3 > cat file1 a line 1 a line 2 a line 3 מבוא לתכנות מערכות - 234122
הפקודה printf • הפקודה printfמאפשרת הדפסה מעוצבת של טקסט בדומה לפונקציה ב-C > printf <format> [arguments] • %s: מציין במחרוזת הפורמט שיש להכניס כאן את ערך הארגומנט הבא • %[-]m[.n]s: מדפיסה את המחרוזת המתאימה מרשימת המחרוזות כך שהתוצאה תהיה באורך m תווים ותכיל לכל היותר n תווים מהמחרוזת. המחרוזת תהיה מיושרת לימין אלא אם מופיע - (מקף). > printf "%s %s! \n" Hello world Hello world! > printf "%-10s %.5s!\n" Hello world. Hello world! מבוא לתכנות מערכות - 234122
תכניות סטנדרטיות ב-UNIX - סיכום • ניתן להשתמש במגוון תכניות סטנדרטיות ב-Unix הפועלות משורת הפקודה ומבצעות פעולות בסיסיות • ניתן להדפיס את תחילת או סוף הקלט ע"י head ו-tail • ניתן למיין את הקלט לפי שורות בעזרת sort • ניתן להשמיט שורות זהות בעזרת uniq • ניתן לחפש שורות מסוימות בקבצים בעזרת grep • ניתן להפריד עמודות ספציפיות מהקלט בעזרת cut • ניתן לספור את מספר המילים והשורות בקלט בעזרת wc • ניתן לשכפל את ערוץ הפלט בעזרת הפקודה tee • ניתן להדפיס מחרוזות בעזרת printf (וecho בתרגול קודם) מבוא לתכנות מערכות - 234122
שאלות ממבחנים - bash שימוש בתכניות סטנדרטיות של Unix בתסריטים מבוא לתכנות מערכות - 234122
שאלה 1 (21.7.95) • כתוב תוכניתב-bash ששמהarrangeאשר מעבירה קבצים מהתיקיה הנוכחית (שאינם תיקיות) לתוך תתי-תיקיות לפי הכללים הבאים: • לכל קובץ שאינו תיקיה: • אם קיימת תת-תיקיה לתיקיה הנוכחית ששמו זהה ל-4 האותיות הראשונות בשם הקובץ, הקובץ יועבר לתוך התיקיה. (שים לב שהכוונה להעברתהקובץ ולא להעתקתו). • אם תנאי 1 לא מתקיים, וקיימים לפחות שני קבצים נוספים בתיקיה הנוכחית שאינם תיקיות, כך ש-4 האותיות הראשונות בשמם זהות ל-4 האותיות הראשונות בשם הקובץ, התוכנית תיצור תת-תיקיה חדשה ששמה זהה ל-4 האותיות הראשונות בשם הקובץ, והקובץ יועבר לתוך תת-תיקיה זו. מבוא לתכנות מערכות - 234122
שאלה 1 (21.7.95) - דוגמה • במדריך הנוכחי קיימים הקבצים הבאים: file1 file2 file3 prog1 prog2 prog script1 script2 כאשר רק הקובץ prog הינו תיקיה • לאחר הפעלת התוכנית arrangeבתיקיה הנוכחית, יהיו הקבצים הבאים בתיקיה זו: file script1 script2 prog כאשר: • file ו – prog הינם תיקיות • בתיקיה fileיהיו הקבציםfile1 file2 file3 • בתיקיה progיהיו הקבציםprog1ו - prog2 (בנוסףלקבצים שהיו בתוכו לפניהפעלת התוכנית arrange). file script1 script2 prog file1 file2 file3 prog1 prog2 file1 file2 file3 script1 script2 prog prog1 prog2 מבוא לתכנות מערכות - 234122
פתרון #!/bin/bash functionfiles { forf in `ls`; do if[[ -f $f]]; then echo $f fi done } functionfileCount { line=( `files | cut -c1-4 | sort | uniq -c | grep $1` ) echo ${line[0]} } functionmakeDir { if[[ ! -d $1 ]] ; then mkdir $1 fi } arrange מבוא לתכנות מערכות - 234122
פתרון arrange forfile 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 fi done מבוא לתכנות מערכות - 234122
שאלה 2 (מועד ג', אביב 2006) • חברת Moogle, שהחליטה זה מכבר לפתוח סניף בחיפה, הכריזה על יום ראיונות בפקולטהלמדעי המחשב בטכניון (אשר בהם יכולים להשתתף רק בוגרי קורס מת"ם כמובן). • במהלך הראיונות נוכחים מספר מראיינים ובינהם גם מנהל Moogle. • כל מראיין נותן ציון למרואיין בין 0 ל-100. • הציון הסופי יקבע ע"י שקלול כל הציונים. • למנהל יש זכות וטו ולא יתכן כי יתקבל לעבודה מרואיין שהמנהל החליט לא לקבל. • בסיום הראיונות כל מראיין מכין קובץ בפורמט הבא על האנשים אותם הוא ראיין: <ID> <FULL NAME> <GRADE> • השדות מופרדים זה מזה בטאבים. שם הקובץ הינו <interviewer name>.grades. • דוגמה לקובץ בשם eyal.grades: • הקובץ של מנהל Moogle ייקראMoogle.grades ויכול להיראות כך: 031243129 Moshe Levi 60 444422267 Shimon Cohen 90 555782311 David David 100 031243129 Moshe Levi 57 555782311 David David -NO- 444422267 Shimon Cohen 80 מבוא לתכנות מערכות - 234122
שאלה 2 (מועד ג', אביב 2006) • עליכם לכתוב תסריט בשם BestToWork אשר ינתח את הקבצים הללו ויחזיראת קבוצת המרואיינים הטובים ביותר. התסריט יקבל כפרמטר את מס' מקומות העבודה הפנויים ויחזיר מס' שכזה של מרואיינים מצטיינים ממויינים לפי מידת ההצלחה. • במקרה שאין מספיק מרואיינים שהתראיינו / עברו את הראיון, תוחזר ההודעה: "not enough interviewees” • לדוגמה, עבור שני הקבצים שבדוגמה: • הערות: • הניחו כי קבצי הקלט קיימים ותקינים • ניתן להניח שאותם מראיינים ראיינו את כל האנשים • אין להשתמש בקבצים זמניים • ניתן להשתמש במספר לא מוגבל של תסריטים > BestToWork 2 1) 444422267 Shimon Cohen 2) 031243129 Moshe Levi > BestToWork 3 not enough interviewees מבוא לתכנות מערכות - 234122
פתרון BestToWork #!/bin/bash functionPrintBest { local num=1 whileread-aline; do echo"${num}) ${line[0]} ${line[1]} ${line[2]}" letnum++ done } functionCalcOneGrade { local total_grade=0 whileread-a line; do lettotal_grade+=${line[3]} done echo$total_grade } מבוא לתכנות מערכות - 234122
פתרון functionCalcGrades { whileread-aline; 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 (( `catMoogle.grades | grep -v"\-NO\-" | wc -l` < $1 )) ; then echo"not enough interviewees" else catMoogle.grades | grep -v"\-NO\-" | CalcGrades | \ sort -nrk3 | PrintBest | head -$1 fi BestToWork מבוא לתכנות מערכות - 234122
בקרת תהליכים ב-UNIX הרצה בחזית וברקע פקודות לניהול תהליכים מבוא לתכנות מערכות - 234122
ריבוי תהליכים ב-Unix • Unix היא מערכת הפעלה התומכת בריבוי תהליכים (multi-tasking) • חובה עבור מערכת שנועדה לשירות מספר רב של משתמשים בו זמנית • תהליך הוא הרצה של תכנית כלשהי • ניתן להריץ תכנית יחידה במספר תהליכים במקביל • בניגוד למנשק גרפי בו השליטה במספר תהליכים אינטואיטיבית עבור עבודה בטרמינל יש להכיר מספר פקודות וקיצורים מבוא לתכנות מערכות - 234122
הרצה בחזית וברקע • Shell יחיד יכול להריץ מספר תהליכים בו זמנית • כל התהליכים מדפיסים את הפלט שלהם לערוצי הפלט הסטנדרטיים • רק תהליך אחד יכול להשתמש בערוץ הקלט הסטנדרטי • תהליך אשר מקושר לערוץ הקלט הסטנדרטי רץ בחזית • כדי להריץ תהליך בחזית יש להפעילו כרגיל > command • כל עוד תהליך רץ בחזית אין גישה ל-prompt ולא ניתן להכניס פקודות חדשות • תהליכים שאינם מקושרים לקלט הסטנדרטי רצים ברקע • ניתן להריץ תהליך ברקע על ידי הוספת & לסוף הפקודה > command & • תהליך יכול להיות גם מושהה, במצב זה התהליך אינו רץ אך מצבו נשמר בזיכרון ונוכל להמשיך את הרצתו כשנרצה מבוא לתכנות מערכות - 234122
בדיקת מצב תהליכים • הפקודה jobs מדפיסה את רשימת התהליכים המורצים תחת ה-Shell > jobs • לכל תהליך מוצג מספר מזהה, מצבו ושם הפקודה • סימן ה-+ מייצג את התהליך "הנוכחי" • תהליך זה יהווה את ברירת המחדל לפקודות טיפול בתהליכים • סימן ה-- מייצג את התהליך הבא בתור להיות + כאשר מספר תהליכים מוציאים פלט בו זמנית הטרמינל מתבלגן במהירות > ./loop 1 & [1] 3692 > Loop 1! ./loop 2 & [2] 3711 Loop 2! Loop 1! loop #!/bin/bash while [[ true ]]; do sleep 1 echo Loop $1! done המספר בסוגריים המרובעים הוא מספר התהליך תחת ה-Shell מבוא לתכנות מערכות - 234122
שליחת אותות לתהליך בחזית • כדי לשנות את מצב הריצה של התהליך הרץ בחזית ניתן לשלוח אותות בעזרת קיצורים מהמקלדת • Ctrl+C: הורג (מפסיק) את התהליך אשר בחזית • Ctrl+Z: משהה את התהליך אשר בחזית • התהליך מפסיק לרוץ אך מצבו נשמר מבוא לתכנות מערכות - 234122
פקודות לניהול תהליכים • ניתן להחזיר תהליך לריצה בחזית בעזרת fg > fg [process] • ניתן להחזיר תהליך לריצה ברקע בעזרת bg > bg [process] • ניתן להשהות תהליך על ידי suspend > suspend <process> • ניתן להרוג תהליך על ידי הפקודה kill > kill <process> • ניתן לציין מספר תהליך ע"י % • ניתן להריץ את התהליך ששמו מתחיל ב-<str> ע"י %<str> • אם קיימים שני תהליכים מתאימים הפקודה תיכשל • עבור fg ו-bg: אם לא צוין מספר תהליך יוחזר התהליך שמסומן ב-+ מבוא לתכנות מערכות - 234122
בקרת תהליכים ב-Unix - סיכום Ctrl+Z ריצה בחזית מושהה הרצה רגילה fg Ctrl+C bg kill suspend fg ריצה ברקע מופסק הרצה עם & kill מבוא לתכנות מערכות - 234122