====== מדריך ברמה 3 לתיכנות בבש ====== == <כרמית לוי> == [[karmimo@netvision.net.il]] ^ היסטוריית גירסאות ^^^ ^ גירסה 0.9 ^ 07-01-2005^ **<כרמית לוי>** ^ | טיוטא ראשונה ||| ==== תקציר ==== מדריך זה נוצר על מנת לעזור להתחיל לתכנת ברמה בינונית בבש. מדריך זה אינו תכנות של רמה מתקדמת ומכיל דוגמאות קוד. מדריך זה מתורגם ממדריך באתר הדוקמנטציה tldp. ==== זכויות יוצרים ורשיון ==== כל הזכויות שמורות (c) 2007, **<כרמית לוי>**, הרשות ניתנת להעתיק, לשנות ולהפיץ מדריך זה תחת התנאים של רשיון ה-GFDL \\ Linux הוא סימן מסחרי רשום של Linus Torvalds. ==== הסרת אחריות ==== הכותב אינו נושא באחריות עבור שימוש ברעיונות, דוגמאות ומידע שבמדריך. השימוש הוא באחריות הקורא בלבד. המדריך עשוי להחיל טעויות ופרטים לא נכונים, שהשימוש בהם עשוי להיות מזיק למחשבך. למרות הסבירות הנמוכה, הכותב אינו לוקח כל אחריות ==== תורמים למדריך \ תודות ==== הכותב מודה לאנשים הבאים על תרומתם למדריך * מייק ג. ==== משוב ==== תגובות, תלונות, הערות והארות לכתובת: . 2 ==== מבוא ==== == ידע קודם נדרש == מדריך זה דורש ידע קודם והכרות עם שורת בפקודה במערכת הפעלה גנו לינוקס וידע כללי בתכנות. מדריך זה לא בא להיות מבוא לתכנות אך הוא מציג גישות תיכנותיות לתכנות בבש והמון דוגמאות קוד. == למי מדריך זה טוב == * למי שיש לו קצת מושג בתכנות בבש ורוצה להתחיל לכתוב סקריפטים. * למי שצריך דוגמאות קוד כדי לכתוב משהו בעצמו. * למי שמהגר מחלונות ורוצה לעשות קבצים שדומים לקבצי BAT של חלונות. ==== 1. פרק ראשון - סקריפט דיי פשות ==== === 1.א סקריפט "שלום עולם" המסורתי === #!/bin/bash echo Hello World הסקריפט מכיל שתי שורות בלבד בשורה הראשונה של הסקריפט מגדירים לו עם איזה תכנה להריץ את הסקריפט בשורה השניה מורים לו לכתוב שלום עולם במסך המסוף כפלט. תוכנות מסוף ושורת פקודה לדוגמא טרמינל וקונסול. הרצת הקובץ הנ"ל אחרי שמירה שלו בשם ./hello.sh === 1.ב סקריפט גיבוי דיי פשות === #!/bin/bash tar -cZf /var/my-backup.tgz /home/me/ סקריפט זה מגבה את כל תקיית הבית לתוך קובץ מכווץ TGZ סקריפט גיבוי טוב יותר יהיה בהמשך. ==== 2. פרק שני - הכל על ניתוב ==== === 2.א תאוריה והתיחסות כללית === __ישנם 3 מאפיינים שאפשר לנתב : stdin, stdout, stderr__ std = standard stdin = standard input לנתב קלט stdout = standard output לנתב פלט stderr = standard error לנתב שגיאות ופלט השגיאה __בעיקרון ניתן לנתב:__ 1. stdout לקובץ 2. stderr לתוך קובץ 3. stderr לתוך stdout 4. stdout לתוך stderr 5. stderr עם stdout לתוך קובץ 6. stderr עם stdout לתוך stdout 7. stdout עם stderr לתוך stderr __מוסכמות__ המספר 0 מייצג את הקלט stdin המספר 1 מייצג את הפלט stdout מה שנכתב במסך המספר 2 מייצג את פלט השגיאה stderr שזה גם טקסט שנשמר בבפר אבל לא מוצג תמיד במסך ולכן הוא נפרד מהפלט הסטנדרטי והוא בבפר שכל פעם נמחק ומתחדש בהתאם לשגיאות הפקודה האחרונה אם יש כאלה. __האופרטורים שמנתבים הם__ > מנתב לקובץ חדש ומאפס אותו >> מנתב לקובץ ומוסיף את הנתונים בסופו >&1 מנתב לפלט 1 כלומר למסך >&2 מנתב לפלט השגיאה כלומר ל 2 stderr === 2.ב דוגמת קוד - ניתוב פלט מסך לקובץ === בדוגמא זו יראו איך לנתב את פלט המסך לתוך קובץ שנקרא לו ls-l.txt קובץ זה יכיל את הטקסט שרואים במסך כאשר מקישים את הפקודה ls -l ls -l > ls-l.txt === 2.ג דוגמת קוד - ניתוב פלט שגיאה לקובץ === בדוגמא זו רואים את פלט השגיאה של תכנית מסויימת שמריצים grep מנותב לקובץ שקראנו לו grep-errors.txt grep da * 2> grep-errors.txt === 2.ד דוגמת קוד - ניתוב פלט מסך לפלט השגיאה === כאן רואים שפלט המסך של הפקודה המורצת שמיוצג על ידי הסיפרה 1 מנותב עם אופרטור הניתוב <& ל 2 שהוא מציין את פלט השגיאות. grep da * 1>&2 === 2.ה דוגמת קוד - ניתוב פלט השגיאה לפלט מסך === grep * 2>&1 === 2.ו דוגמת קוד - ניתוב פלט שגיאה ופלט מסך לתוך קובץ === לשים לב לאופרטור &< שמנתב גם את הפלט של המסך וגם את פלט השגיאה לקובץ המרוקן שימוש זה נעשה אם רוצים שפקודה תרוץ ולא יראו שום פלט שלה גם כאשר יש שגיאה. rm -f $(find / -name core) &> /dev/null ==== 3. פרק שלישי - צינורות ==== === 3.א מהם צינורות ומדוע כדאי להשתמש בהם === צינורות זה דרך להעביר את פלט המסך של תכנית אחת כקלט לתכנית אחרת אופרטור הצינורה סימנו - "|" כאשר מימינו ומשמאלה יש את התכנית שפולטת והתכנית שמקבלת את הפלט של התכנית הקודמת משמאל לימין. === 3.ב דוגמת קוד - צינור פשות בשילוב עם sed === כאן דוגמא לפקודה ls שהפלט שלה אינו מודפס במסך ובמקום זאת מנותב לתכנית אחרת שמשתמשת בפלט ומוציאה פלט אחר שהוא זה שיודפס במסך. ls -l | sed -e "s/[aeio]/u/g" === 3.ג דוגמת קוד - אלטרנטיבה לפקודה ls -l *.txt === ls -l | grep "\.txt$" ==== 4. פרק רביעי - משתנים ==== ניתן להשתמש במשתנים כמו בכל שפת תכנות העניין הוא שאין טיפוסי משתנים. משתנה בבש יכול לקבל מספר תו טקסט. אין שום צורך בהצהרת טיפוס משתנה הטיפוס נקבע על פי הערך המוכנס. === 4.א דוגמא לסקריפט "שלום עולם" בשימוש עם משתנים === שורה 2 יוצרת משתנה בשם STR ומכניסה את הטקסט "Hello World" אליו. לאחר מכן הערך של משתנה זה נגיש באמצעות השמת הסימן דולר $ לפניו. שים לב שאלמלא השתמשנו בסימן דולר פלט התכנית היה שונה ובמקום שהתכנה תכתוב את הטקסט שלום עולם היא תכתוב STR כפלט טקסט. #!/bin/bash STR="Hello World!" echo $STR === 4.ב דוגמא לסקריפט גיבוי קצת יותר טוב מהקודם === #!/bin/bash OF=/var/my-backup-$(date +%Y%m%d).tgz tar -cZf $OF /home/me/ סקריפט זה מציג עניין נוסף. קודם כל אתה צריך לזהות את יצירת המשתנה והסימן שלו בשורה 2. שים לב לביטוי $(date +%Y%m%d).tgz. אם אתה מריץ את הסקריפט תוכל לשים לב שהוא מריץ את הפקודה קודם ומשתמש בפלט שלה כערך למשתנה. תוכל לבחון זאת באמצעות הדוגמאות הבאות שימחישו את ההבדלים: echo ls בדוגמא הנ"ל הפלט הוא ls echo $(ls) בדוגמא הנ"ל הפלט הוא הטקסט של הפקודה ls כפי שמקישים אותה במסוף. === 4.ג משתנים מקומיים === משתנים מקומיים יוצרים על ידי מילת המפתח local לפני שם המשתנה... דוגמא זו מדגימה זאת: #!/bin/bash HELLO=Hello function hello { local HELLO=World echo $HELLO } echo $HELLO hello echo $HELLO ==== 5. פרק חמישי - משפטי תנאי - התניות ==== התניות מאפשרות להחליט אם לבצע פעולה או לא באמצעות הצבת תנאים. === 5.א תאוריה כללית === התניות בעלות הרבה צורות. הצורה הבסיסית ביותר היא: אם [ תנאי שמתקיים ] אז [ פעולות שיתבצעו בהתאם לתנאי ]. תנאים או התניות יכולים להיות גם בעלי מבנה משפט התניה אחר כמו אם [ תנאי שמתקיים ] אז [פעולות שיבוצעו ] אחרת [ פעולות אחרות שיבוצעו ] אפשרות נוספת היא שרשור של כל מיני התניות לביצוע פעולה שנבדקות בסדר מסויים כגון: אם [ תנאי שמתקיים ] אז [פעולות שיבוצעו ] אחרת אם [ תנאי אחר שמתקיים ] אז [ פעולות אחרות שיבוצעו ] אחרת אם [ תנאי אחר שמתקיים ] אז [ פעולות אחרות שיבוצעו ] אחרת [ פעולות אחרות שיבוצעו ] בבש תחביר הפקודה יראה בצורה זו: #example 1: if [ התנייה ]; then doSomthing; fi; #example2: if [ התניה ] then doSomthing else doSomethingElse fi ככלי התחביר כאשר כותבים את משפט ההתניה בשורה אחת יש להפריד מילות מפתח ופקודות עם נקודה פסיק כמו בדוגמא הראשונה. אם רוצים לכתוב את משפט ההתניה שלא בשורה אחת אז לא צריך נקודה פסיק בכלל. === 5.ב דוגמת קוד למשפט תנאי: if...then === #!/bin/bash if [ "foo" = "foo" ]; then echo expression evaluated as true fi אם ההתניה בתוך הסוגריים המרובעים היא אמת אז יודפס הביטוי. הפקודה להדפסה צריכה להימצא תמיד אחרי המילה then ולפני המילה fi שהיא finish מסמנת את הסוף של ההתניה. === 5.ג דוגמת קוד למשפט תנאי: if...then...else === #!/bin/bash if [ "foo" = "foo" ]; then echo expression evaluated as true else echo expression evaluated as false fi === 5.ד דוגמת קוד למשפט תנאי עם משתנים === #!/bin/bash T1="foo" T2="bar" if [ "$T1" = "$T2" ]; then echo expression evaluated as true else echo expression evaluated as false fi ==== 6. פרק שישי - לולאות for, while, until ==== בפרק זה נדון בלולאות for, while, until לולאת FOR שונה במקצת מאשר בשפות תכנות אחרות. בעיקרון לולאה זו מאפשרת להריץ מספר פעולות בצורה מחזורית. לולאת ה WHILE מבצעת קוד אם מתקיימת התנייה כלשהי ועוצרת כאשר ההתניה לא מתקיימת עוד או שאחת הפקודות בתוך הלולאה היא break שזו פקודה ליציאה לחלוטין ממחזוריות הפקודות הרצות של הלולאה. לולאת UNTIL כמעט זהה ל WHILE בהבדל שסדרת הפקודות בתוכה מתבצעת פעם אחת בטרם נבדק התנאי להמשך מחזוריות ביצוע סדרת הפקודות שבתוך הלולאה. === 6.א דוגמת קוד ללולאת for === #!/bin/bash for i in $( ls ); do echo item: $i done בשורה השניה הגדרנו את "i" למשתנה שלוקח ערכים שונים הקיימים בתוך פלט הפקודה ls. השורה השלשית יכולה להיות ארוכה יותר ואפשר גם להכניס פקודות נוספות אחריה ולפני ה done אם צריך. === 6.ב דוגמת קוד ללולאת for בסטייל של שפת C === #!/bin/bash for i in `seq 1 10`; do echo $i done === 6.ג דוגמת קוד ללולאת while === #!/bin/bash COUNTER=0 while [ $COUNTER -lt 10 ]; do echo The counter is $COUNTER let COUNTER=COUNTER+1 done === 6.ד דוגמת קוד ללולאת until === #!/bin/bash COUNTER=20 until [ $COUNTER -lt 10 ]; do echo COUNTER $COUNTER let COUNTER-=1 done ==== 7. פרק שביעי - פונקציות ==== כמעט בכל שפות התיכנות ניתן להשתמש בפונקציות לאגד קבוצת פקודות קוד תחת שם אחד ולהשתמש ברקורסיות. הצהרה על פונקציה נעשית בצורה של function my_func {my code קריאה לפונקציה נעשית באמצעות קריאה בשמה. === 7.א דוגמת קוד לפונקציות === #!/bin/bash function quit { exit } function hello { echo Hello! } hello quit echo foo שורות 2-4 מכילות את הפונקציה "quit". שורות 5-7 מכילות את הפונקציה "hello". אם אינך בטוח מה הפונקציות עושות נא לנסות! שים לב שסדר הצהרת הפוקציות לא משמעותי בתכנית שקודם קוראת לפונקציה השניה ואז לראשונה. === 7.ב דוגמת קוד לפונקציות עם פרמטרים === #!/bin/bash function quit { exit } function e { echo $1 } e Hello e World quit echo foo סקריפט זה כמעט וזהה לקודם. ההבדל בפוקציה זו שהיא מדפיסה את הערך הראשון שהיא מקבלת $1 (ארגומנט). ארגומנטים בפונקציות מתנהגים כמו ארגומנטים שניתנים לסקריפט. ==== 8. פרק שמיני - ממשק משתמש ==== === 8.א שימוש בפקודה select כדי ליצור תפריט בחירה === #!/bin/bash OPTIONS="Hello Quit" select opt in $OPTIONS; do if [ "$opt" = "Quit" ]; then echo done exit elif [ "$opt" = "Hello" ]; then echo Hello World else clear echo bad option fi done אם תריץ סקריפט זה תראה שזה חלום של כל מתכנת לתפריטים מבוססי טקסט. תוכל כנראה להבחין שזה מאוד דומה למבנה לולאת FOR. === 8.ב שימוש בשורת הפקודה === #!/bin/bash if [ -z "$1" ]; then echo usage: $0 directory exit fi SRCD=$1 TGTD="/var/backups/" OF=home-$(date +%Y%m%d).tgz tar -cZf $TGTD$OF $SRCD הביטוי במשפט התניה הראשון בוחן אם התכנית מקבלת איזה שהם ארגומנטים או ערכים ויוצאת כשאין ערכים תוך כדי שהיא מראה למשתמש הודעה איך להשתמש בסקריפט. שאר הסקריפט אמור להיות ברור. ==== 9. פרק תשיעי - שונות ==== === 9.א קריאת פלט מהמשתמש עם הפקודה read === בהרבה מקרים תרצה לקבל קלט מהמשתמש וישנם מספר דרכים להשיג זאת. זו אחת הדרכים: #!/bin/bash echo Please, enter your name read NAME echo "Hi $NAME! אפשרות נוספת היא לקבל מספר ערכים באמצעות read דוגמא זאת תמחיש את הכוונה: #!/bin/bash echo Please, enter your firstname and lastname read FN LN echo "Hi! $LN, $FN !" === 9.ב פעולות אריטמתיות === נסה זאת בשורת הפקודה: echo 1 + 1 אם ציפית לראות 2 אז אתה תתאכזב. מה אם אתה רוצה לבצע פעולות עם מספרים בבש? הפתרון הוא כזה: echo $((1+1)) זה יבצע פלט קצת יותר הגיוני. הינך יכול להשיג זאת גם בצורה זאת: echo $[1+1] אם אתה צריך להשתמש ביותר פעולות חשבוניות תצטרך להשתמש ב bc לבצע ביטויים חשבוניים. למשל אם תריץ echo $[3/4] t בשורת הפקודה תקבל 0 ולא 0.75 משום שהבש משתמש רק במספרים שלמים. על מנת לקבל תוצאה של 0.75 תצטרך לעשות זאת בצורה זאת: echo 3/4|bc -l === 9.ג מציאת bash === בדרך כלל תמיד תשתמש ב #!/bin/bash להלן דוגמאות איך למצוא היכן בש ממוקם אצלך. locate bash לא בכל המכונות יש את הפקודה הנ"ל. find ./ -name bash את הפקודה הנ"ל לבצע מספריית השורש / אפשרויות מיקום נוספים שאפשר לבדוק: ls -l /bin/bash ls -l /sbin/bash ls -l /usr/local/bin/bash ls -l /usr/bin/bash ls -l /usr/sbin/bash ls -l /usr/local/sbin/bash אפשר גם לנסות עם הפקודה which which bash === 9.ד קבלת הערך המוחזר מתכנית === בבש, הערך המוחזר מתכנית מאוחסן במשתנה מיוחד ששמו דולר סימן שאלה $?... דוגמא זו תמחיש כיצד לתפוס ערך מוחזר מתכנית בנניח שהספריה dada לא קיימת: #!/bin/bash cd /dada &> /dev/null echo rv: $? cd $(pwd) &> /dev/null echo rv: $? === 9.ה תפיסת פלט של פקודה === סקריפט זה מראה את כל הטבלאות מכל בסיסי הנתונים בהנחה שיש לך mySQL מותקן. בכל אופן לקחת בחשבון לתת שם משתמש וסיסמא תקפים. #!/bin/bash DBS=`mysql -uroot -e"show databases"` for b in $DBS ; do mysql -uroot -e"show tables from $b" done === 9.ו קוד מבוזר במספר קבצים === ניתן להשתמש במספר קבצים בתוך קוד הפקודות. ==== 10. פרק עשירי - טבלאות ==== === 10.א אופרטורים להשוואת מילים === (1) s1 = s2 זהה ושווה (2) s1 != s2 שונה (3) s1 < s2 קטן גדול (4) s1 > s2 קטן גדול (5) -n s1 לא ערך ריק (6) -z s1 ערך ריק מתוכן === 10.ב דוגמאות קוד להשוואת מילים === השוואת שתי מחרוזות טקסט #!/bin/bash S1='string' S2='String' if [ $S1=$S2 ]; then echo "S1('$S1') is not equal to S2('$S2')" fi if [ $S1=$S1 ]; then echo "S1('$S1') is equal to S1('$S1')" fi הערה: כדאי מאוד בקוד לשים מרכאות סביב המשתנים ולכתוב "$S1"="$S2" משום שאם המשתנים לא מכילים ערך תתקבל שגיאת תחביר ולכן שימוש במרכאות סביב שמות המשתנים בהתניות הינו דבר כדאי. === 10.ג אופרטורים לפעולות חשבוניות === חיבור + חיסור - כפל * חילוק ומתקבלת תוצאה ללא השארית / חילוק כאשר רוצים כתוצאה את השארית בלבד % === 10.ד אופרטורי התיחסות לפעולות חשבוניות === -lt (<) -gt (>) -le (<=) -ge (>=) -eq (==) -ne (!=) === 10.ה פקודות שימושיות === חלק מפקודות אלה כוללים כללי תחביר ברמה של שפת תיכנות. מפקודות אלה רק הדברים הבסיסיים יוסברו. להסבר מעמיק יותר תוכל להסתכל בדפי ה man של פקודות אלה. == עורך טקסט sed == ניתן להשתמש בו לעריכת קבצים לבצע בהם שינויים וגם כפילטר למציאת נתונים בתוך קובץ או לבצע שינויים בעלי כללי תחביר בתוך קובץ על פי קריטריונים מסויימים. $sed 's/to_be_replaced/replaced/g' /tmp/dummy העורך sed בדוגמא הנ"ל מחליף את הטקסט to be replaced בטקסט replaced כאשר טקסט זה מופיע מהקובץ הנקרא tmp/dummy ופולט את התוצאה. כמו כן ניתן לנתב את הפלט לקובץ אחר. $sed 12, 18d /tmp/dummy כאן הוא פולט את כל תוכן הקובץ מלבד שורות 12 עד 18. הקובץ המקורי לא נפגע או משתנה באמצעות פקודה זו. == מניפולציות של נתונים באמצעות awk == העיקרון כאן הוא דומה: נניח שיש לנו קובץ שזה תוכנו "test123 test tteesstt" תתבצע הפקודה $awk '/test/ {print}' /tmp/dummy test123 test בנ"ל התבנית ש awk מחפש היא "test" והפקודה שמתבצעת כאשר הוא מוצא שורה בקובץ עם המחרוזת הזאת זה print. $awk '/test/ {i=i+1} END {print i}' /tmp/dummy 3 כאשר אתה מחפש תבניות טקסט בקובץ אתה צריך להכניס את הטקסט לקובץ בין המרכאות עם כדי שתוכל להניח את כל התבניות והפעולות לקובץ. == כתיבת שורות בהתאם לתבנית שעל פיה מחפשים באמצעות grep == $grep "look for this" /var/log/messages -c 12 המחרוזת "look for this" נמצאה למשל 12 פעמים בקובץ /var/log/messages. == ספירת שורות מילים ו bytes באמצעות wc שזה word count == בדוגמא הבאה נראה שהפלט לא כפי שציפינו. קובץ הדמה שנשתמש לדוגמא זו מכיל את הטקסט הבא: "bash introduction hoto test file" $wc --words --lines --bytes /tmp/dummy 2 5 34 /tmp/dummy הכלי wc פולט את הנתונים שלו בצורה סטנדרטית והפרמטרים מציגים את הסדר בהתאמה של הפלט. == מיון שורות טקסט באמצעות sort == נניח שיש לנו קובץ שזה תוכנו: " ב ג א" $sort /tmp/dummy וזה יהיה הפלט א ב ג == מחשבון שורת הפקודה bc == $bc -q 1 == 5 0 0.05 == 0.05 1 5 != 5 0 2 ^ 8 256 sqrt(9) 3 while (i != 9) { i = i + 1; print i } 123456789 quit == אתחול המסוף או הכנסת נתוני שאילתת מסוף עם tput == דוגמא: $tput cup 10 4 שורת הפקודה מופיעה במיקום (y10,x4) דוגמא נוספת: $tput reset מנקה את המסך דוגמא נוספת: $tput cols 80 מראה את מספר התוים שניתן לשים בכיוון x. מאוד רצוי להכיר את התכניות האלה. ישנם המון תוכנות כאלה שיכולות לעזור לעשות ניסים בשורת הפקודה בבש. ==== 11. פרק אחד עשר - עוד סקריפטים ==== === 11.1 דוגמא: סקריפט גיבוי פשות (וקצת יותר טוב) === #!/bin/bash SRCD="/home/" TGTD="/var/backups/" OF=home-$(date +%Y%m%d).tgz tar -cZf $TGTD$OF $SRCD ===11.2 משנה שמות קבצים === #!/bin/sh # renna: rename multiple files according to several rules # written by felix hudson Jan - 2000 #first check for the various 'modes' that this program has #if the first ($1) condition matches then we execute that portion of the #program and then exit # check for the prefix condition if [ $1 = p ]; then #we now get rid of the mode ($1) variable and prefix ($2) prefix=$2 ; shift ; shift # a quick check to see if any files were given # if none then its better not to do anything than rename some non-existent # files!! if [$1 = ]; then echo "no files given" exit 0 fi # this for loop iterates through all of the files that we gave the program # it does one rename per file given for file in $* do mv ${file} $prefix$file done #we now exit the program exit 0 fi # check for a suffix rename # the rest of this part is virtually identical to the previous section # please see those notes if [ $1 = s ]; then suffix=$2 ; shift ; shift if [$1 = ]; then echo "no files given" exit 0 fi for file in $* do mv ${file} $file$suffix done exit 0 fi # check for the replacement rename if [ $1 = r ]; then shift # i included this bit as to not damage any files if the user does not specify # anything to be done # just a safety measure if [ $# -lt 3 ] ; then echo "usage: renna r [expression] [replacement] files... " exit 0 fi # remove other information OLD=$1 ; NEW=$2 ; shift ; shift # this for loop iterates through all of the files that we give the program # it does one rename per file given using the program 'sed' # this is a sinple command line program that parses standard input and # replaces a set expression with a give string # here we pass it the file name ( as standard input) and replace the nessesary # text for file in $* do new=`echo ${file} | sed s/${OLD}/${NEW}/g` mv ${file} $new done exit 0 fi # if we have reached here then nothing proper was passed to the program # so we tell the user how to use it echo "usage;" echo " renna p [prefix] files.." echo " renna s [suffix] files.." echo " renna r [expression] [replacement] files.." exit 0 # done! === 11.3 משנה שמות קבצים פשות יותר === #!/bin/bash # renames.sh # basic file renamer criteria=$1 re_match=$2 replace=$3 for i in $( ls *$criteria* ); do src=$i tgt=$(echo $i | sed -e "s/$re_match/$replace/") mv $src $tgt done ==== 12. פרק שנים עשר - מציאת שגיאות ודיבאגינג ==== כדאי להוסיף בתחילת הקוד את השורה #!/bin/bash -x דבר זה יכול להציג מידע חשוב על הפלט ולעזור בדיבאגינג