טיפים למשתמש הביתי

שגיב ברהום
09.06.2005
היסטוריית גירסאות
גירסה 0.2 21/11/2005 xx
גירסא רשמית שניה - המדריך הועבר לוויקי
הורחב הפרק על רשתות
הסבר קצר על הפקודה bc
גירסה 0.1 08/06/2005 xx
גירסא רישמית ראשונה

הסרת אחריות

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

למה לקרוא בכלל את המדריך הזה?

לינוקס מתקדמת במהירות, נקודה. דברים שלא יכולתי לעשות בעזרת הממשק הגרפי לפני שנה, היום נראים טריוויאליים.
לדעתי, משתמש ביתי יכול היום לתפעל את מכונת הדסקטופ שלו מבלי להתעסק כמעט עם שורת הפקודה.
כך זה לפחות בגרסאת המנדריבה שעליה אני עובד (גרסא 2005LE עם מספר שדרוגים קטנים; גרסא 2006 יצאה לפני שבועות נכון לכתיבת שורות אלו).

אז למה בכלל, לקרוא את המדריך הזה?

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

  • אני רוצה לגבות את כל הקבצים ולכן עלי לדחוס אותם, לצרוב אותם ולתת את העותק לחבר שישמור אותו אצלו.
  • יש לי קבצים עם השמות:

file1 file10 file11 file2 file3 . . file9

אבל אני רוצה לסדר אותם בסדר עולה, כך: file01 file02 file03 . . file09 file10 file11

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

למי מיועד מדריך זה?

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

איך לקרוא את המדריך?

בניגוד למדריכים אחרים שסביר שקראתם בעבר, אני לא ממליץ לקרוא את המדריך הזה ברצף.
ללא כל מה שכתוב בו רלוונטי אליכם. המדריך מתחיל בנושאים קלים יותר ומסיים בנושאים כבדים יותר אבל הקצב לאו דווקא אחיד.
במקומות רבים אני מפנה למדריכים אחרים ברשת, אין לי כל רצון להמציא את הגלגל מחדש – ניסיתי לוודא שרובם יהיו בעברית.
רובו של המדריך אופורטיבי כלומר ברמה של אני רוצה לעשות * ופתרון. לכן, אם אתם קוראים את המדריך בעזרת firefox, אני מזכיר לכם כי קיימת דרך קצרה ונוחה לחפש טקסט:
הקישו על התו '/' ואחר כך על מחרוזת שאתם מחפשים. המופע הראשון של הטקסט יודגש. כדי לעבור למופע הבא, הקישו F3. אם הגעתם בצורה זו לקישור שאתם רוצים לפתוח בtab חדש הקישו ctrl+enter.
במקומות שראיתי לנכון הרחבתי מעט בנושאים תאורטיים, במיוחד אם לא מצאתי מדריך שמסביר זאת בצורה טובה בעברית.

עזרו לי לפתח את המדריך הזה.

את המדריך הזה כתבתי מכל מיני טיפים ודברים שלמדתי במשך השימוש שלי בלינוקס, במהלך הזמן תיעדתי את הפתרונות שמצאתי לבעיות שנתקלתי בהן ולא ידעתי לפתור מיד.
שכחתי משהו? סביר להניח….
נתקלתם בפקודה/סקריפט שימושיים במיוחד שאתם מעוניינים “להשוויץ” בהם?
מצאתם שגיאה או הסבר לא ברור במדריך?

אנא שילחו אליי: sagivba _*at*_nanamail.co.il

מה אני מניח לגביכם

כמה הנחות יסוד לגבי הקורא הממוצע:
אתם מכירים באופן בסיסי מאוד, או יותר מכך, את שורת הפקודה בלינוקס. רמה זו מספיקה בכדי להפיק תועלת ממדריך זה.
סקרנות בסיסית היא תכונה חשובה שתעזור לכם להפיק מהמדריך הזה תועלת רבה יותר.
נתקלתם בפקודה שאתם לא מכירים ומצאתם אותה שימושית - חיקרו אותה. בסוף המדריך קיים נספח שמרחיב בנושא.

תודות

ברצוני להודות ל:
אילי פישמן ושלומי פיש על ההגהה של מדריך זה.
כתריאל על העידוד לכתוב את המדריך.

משימות תחזוקה:

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

עבודה עם קבצים

ls

אני רוצה לדעת איזה קבצים יש לי בתיקייה (= directory) הנוכחית

  [sagivba@sagivba tmp]$ ls dir1a/
  dir2a/  dir2b/  dir2c/  dir2d/  file1  file2
אני רוצה לדעת יותר פרטים על הקבצים
  [sagivba@sagivba tmp]$ ls -l  dir1a/
  total 16
  drwxr-xr-x    3 sagivba  sagivba      4096 ינו  4 21:16 dir2a/
  drwxr-xr-x    3 sagivba  sagivba      4096 ינו  4 21:18 dir2b/
  drwxr-xr-x    2 sagivba  sagivba      4096 ינו  4 21:16 dir2c/
  drwxr-xr-x    2 sagivba  sagivba      4096 ינו  4 21:17 dir2d/
  -rw-r--r--    1 sagivba  sagivba         0 ינו  4 21:19 file1
  -rw-r--r--    1 sagivba  sagivba         0 ינו  4 21:19 file2

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

http://www.penguin.org.il/guides/premissions/

אבל אני רוצה לראות גם קבצים חבויים

  [sagivba@sagivba tmp]$ ls -a  dir1a/
  ./  ../  dir2a/  dir2b/  dir2c/  dir2d/  file1  file2  .hid_file1

אני רוצה לראות את תוכן התיקיות שבתוך התיקייה הנוכחית:
  [sagivba@sagivba tmp]$ ls -R  dir1a/
  dir1a/:
  dir2a/  dir2b/  dir2c/  dir2d/  file1  file2

  dir1a/dir2a:
  dir3a/
  dir1a/dir2a/dir3a:

  dir1a/dir2b:
  dir3b/  file1  file2

  dir1a/dir2b/dir3b:
  file1

  dir1a/dir2c:

  dir1a/dir2d:
  file1  file2  file3

אבל אני רוצה לראות את זה בצורה של עץ… (פקודה זו אינה מופיעה בד”כ ויתכן כי תצטרכו להתקין אותה בנפרד – אבל היא עושה חיים כל כך קלים, ולכן כללתי אותה)
[sagivba@sagivba tmp]$ tree -a  dir1a/
  dir1a/
  |-- .hid_file1
  |-- dir2a
  |   `-- dir3a
  |-- dir2b
  |   |-- dir3b
  |   |   `-- file1
  |   |-- file1
  |   `-- file2
  |-- dir2c
  |-- dir2d
  |   |-- file1
  |   |-- file2
  |   `-- file3
  |-- file1
  `-- file2

du

אני רוצה לדעת מה גודל התיקייה הנוכחית:

  [sagivba@sagivba tmp]$ du ~/tmp
  8.0K    /home/sagivba/tmp/orbit-sagivba
  20K     /home/sagivba/tmp/svc0o.tmp
  4.0K    /home/sagivba/tmp/dir1a/dir2a/dir3a
  8.0K    /home/sagivba/tmp/dir1a/dir2a
  4.0K    /home/sagivba/tmp/dir1a/dir2b/dir3b
  8.0K    /home/sagivba/tmp/dir1a/dir2b
  4.0K    /home/sagivba/tmp/dir1a/dir2c
  4.0K    /home/sagivba/tmp/dir1a/dir2d
  28K     /home/sagivba/tmp/dir1a
  80K     /home/sagivba/tmp

לא! התכוונתי רק של התיקייה הנוכחית, אבל עד עץ בעומק 1:
  [sagivba@sagivba tmp]$ du --max-depth=1 ~/tmp
  8.0K    /home/sagivba/tmp/orbit-sagivba
  20K     /home/sagivba/tmp/svc0o.tmp
  28K     /home/sagivba/tmp/dir1a
  80K     /home/sagivba/tmp

cd

אני רוצה לעבור לתיקיית הבית שלי:

  cd ~
אני רוצה לעבור למדריך הבית של moshe:
  cd ~mosshe

אני רוצה לחזור לתיקייה האחרונה שבה הייתי:
  cd -

cp

אני רוצה להעתיק את dir1 על כל תוכנו לתוך dir2:

  cp -r dir1 dir2

rename / mv

אני רוצה לשנות את השם של הקובץ file1 להיות file7:

  [sagivba@sagivba dir1a]$ ls file*
  file1
  [sagivba@sagivba dir1a]$ mv file1 file7
  [sagivba@sagivba dir1a]$ ls file*
  file7

יש לי את הקבצים:

  file1 file2  file3 . . file9 file10  file11


אבל אני רוצה לסדר אותם:
  file01 file02  file03 . . file09 file10  file11

  rename file file0 file?
הערה - לפקודה rename יש יותר מגרסא אחת = ולכן יתכן שהדוגמא האחרונה לא תעבוד אצלכם - אפשר להשתמש גם בלולאת for - אני בטוח שתסתדרו, נכון ?

rm

נו, טוב כאן יש שלושה דגלים שאני חושב שכל אחד מכיר:
אני רוצה למחוק את כל הקבצים שמסתיימים בtxt מבלי שאדרש לאשר בכל פעם.

  [sagivba@sagivba dir1a]$ rm -f *.txt
אני רוצה למחוק את כל הקבצים שמתחילים בfile ואחריו סיפרה, אבל לאשר לפני כל מחיקה.
  [sagivba@sagivba dir1a]$ rm -i file[0-9]
אני רוצה למחוק את dir1 עם כל מה שבפנים.
  [sagivba@sagivba dir1a]$ rm -rf dir1
אזהרה וטיפ קטן בצידה, rm יכולה לגרום לתוצאות הרסניות – מרגע שמחקתם קובץ לא ניתן לשחזרו.
לכן, אם אינכם בוטחים בעצמכם ואתם רוצים שתהיה לכם אפשרות לשחזר מידע שמחקתם, אולי כדאי שתוסיפו alias שמחליף את rm בהעברה לתיקיית אשפה, כך אם תרצו לשחזר קובץ שמחקתם תוכנו פשוט להעבירו בחזרה.
בכדי לקבל מושג איך לעשות זאת, קיראו את הסעיף העוסק בקובץ bashrc.

mkdir

אני רוצה ליצור את תיקייה בתוך תיקייה - פשוט קיראו את הקוד ותבינו:

  [sagivba@sagivba tmp]$ mkdir -p dir_root/dir_branch/dir_leave/
  [sagivba@sagivba tmp]$ tree dir_root/
  dir_root/
  `-- dir_branch
      `-- dir_leave

zip

אני רוצה לכווץ את dir1a ואת כל מה שבפנים:

  [sagivba@sagivba tmp]$ zip -r my_dir.zip dir1a/
הדגל r גורם לכיווץ רקורסיבי.
בכדי לפתוח קובץ zip השמשו בunzip

tail

אני רוצה לעקוב אחרי קובץ תוך כדי שהוא נכתב.
בדרך כלל משתמשים בפקודה הזו בכדי לעקוב אחר קובץ log בזמן שמערכת כותבת אותו.
תכף נראה דוגמא… חכו רגע.

  [sagivba@sagivba dir1a]$ tail -f file1
על מנת להבין מה אמרתי כאן, נסו:
  [sagivba@sagivba dir1a]$ for I in  1 2 3 4 5 6 7 8 9 10 ;\
  >do echo $I >> file1 ; sleep 1;\
  > done &
  [1] 12699
  [sagivba@sagivba dir1a]$ tail -f file1

הסבר למי שלא הבין: השורה הראשונה מריצה לולאה ברקע, שכותבת במחזוריות (אחת לשניה) משתנה לתוך הקובץ file1. לאחר הכתיבה, הלולאה נעצרת לשנייה אחת וממשיכה בכתיבה. כל התהליך הזה מתקיים ברקע בגלל התו '&'.
כלומר, אנו יכולים להמשיך לתת פקודות.
לאחר מכן אנו מריצים בשורת הפקודה השנייה את tail וכך אנו יכולים לעקוב אחר הקובץ.

עיון בקבצים, עריכת קבצים וחיות אחרות

file

נתקלתי בקובץ: anonymous_file_neme ואני לא יודע מאיזה סוג הוא:

  file anonymous_file_neme
בלינוקס סוג הקובץ מוגדר לפי ר הנשמר בתחילת הקובץ (magic number ) ולא לפי הסיומת שלו , לא כמו בחלונות.

less

אני רוצה לקרוא קובץ טקסט מבלי לערוך אותו:

  less filename
מילים אחדות על less יהיו במקום. הפקודה man נעזרת ב-less כדי להציג את דפי התיעוד של לינוקס, ולכן שווה להקדיש קצת זמן כדי להכיר את הפקודה הזאת.
הדרך הקלה והמהירה, לדעתי, היא לפתוח קובץ כלשהו בעזרת less ואז להקיש h - ייפתח לכם חלון עם כל קיצורי המקשים החשובים.
מומלץ במיוחד להכיר את כל אופציות החיפוש, מכיוון שכשתראו דפי תיעוד ארוכים, לא תרצו לבזבז זמן. חיפוש מילות המפתח יכול לקצר באופן משמעותי את זמן הקריאה שלכם.

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

vim

אני רוצה לערוך קובץ טקסט באנגלית.
קצרה היריעה מלתאר את נפלאות העורך המעולה הזה. הוא יודע בין השאר להשלים מילים , לצבוע טקסט של קוד בכל שפות התכנות שאני יכול להעלות על דעתי, להשלים מילים להריץ פקודות מעטפת (למשל לקמפל תוך כדי כתיבת הקוד) ועוד המון.
יש לvim גרסא בשם(gvim) עם ממשק גרפי (GUI) מאוד נוח, שאני מעדיף להשתמש בה. כדי לקבל הצגה בסיסית של העורך קיראו את המדריך לvi של אבירם נוטירקה:

http://www.penguin.org.il/guides/vi-intro/

להכרה מעמיקה יותר יתכן שתהיו מעוניינים לקרוא את המדריך לעבודה בvi-Improved/עידו קנר :

http://www.penguin.org.il/guides/vim-intro/

וכמובן שיש את האתר של vim שמכיל כמות בלתי נדלית של טיפים וה-help המובנה בתוך התוכנה עצמה.

חיפוש

בחלק זה אסקור מספר כלים שעוזרים בחיפוש, הכלי grep עוזר לנו בחיפוש בתוך מסמכי טקסט או בסינון של פלט טקסט ארוך של פקודות. הפקודה find עוזרת לחפש בעיקר על פי מאפיינים של הקובץ כמו שם הקובץ, התאריך האחרון ששונה, גודלו וכו'. הפקודה slocate או locate עוזרת למצוא קבצים על פי שמם ונעזרת לשם כך במאגר מידע שהיא מכינה מראש ולכן גם יותר מהירה מfind בד”כ. והפקודה which עוזרת לנו למצוא את המיקום של כלי שורת פקודה אחרים.

grep

אחת הפקודות השימושיות ביותר משורת הפקודה. הנה כמה דוגמאות בסיסיות לשימוש בה. איזה שורות מכילות את המילה : zeldabelda בקובץ my_file?

  grep 'zeldabelda' my_file
אופס ! התכוונתי לכל השורות שלא מכילות zeldabelda
  grep -v 'zeldabelda' my_file
אני רוצה לדעת בתיקייה הנוכחית אילו מבין קבצי ב-c במדריך הנוכחי מכילים את מחרוזת string.h :
  grep -l 'string.h' ./*.c
אם אינכם יודעים מה משמעות הכוכבית, אולי כדאי שתקראו קצת על wildcards. משמעות הדגל l היא להדפיס את שמות הקבצים עם ההתאמה.
חפש לי כמו מקודם – אבל בתיקייה ובתתי התיקייות שבתוכה באופן רקורסיבי.
 grep -r 'string.h' ./ | grep '.c' 

טוב – אז אתם יודעים איך עובדים עם wildcards. אז הנה דוגמא לחיפוש … הפקודה הבאה מחפשת שורות שמתחילות בkookoo

  $ grep -w '\
הפקודה הבאה מחפשת שורות שמסתיימות בrikoo
  $ grep -w 'rikoo\>' *
תעזבו אותי מwildcards – זה לילדים… גברים אמיתיים מתעסקים עם ביטויים רגולריים, אני רוצה שורות שמכילות מספרי טלפון
  grep -P "0(\d|5\d)-\d{7}" std.vcf
לא מבינים ביטויים רגולריים? לשלומי לובטון יש יופי של מדריך בנושא.

http://www.guides.co.il/download.php?guide=161

רוצים לדעת עוד? נסו את דפי התיעוד של perl.

grep+pipe

רק כמה דוגמאות נפוצות להכוונת פלט עם grep, לגרות לכם את הדמיון מכאן תמשיכו הלאה לבד…
אני רוצה לקרוא רק את השורות שמכילות ההערות בלבד בסקריפט הbash המדהים cool.sh

  grep -P '^\s*#' ./cool.sh|less
תן לי רמז אם מותקנות אצלי חבילות המטפלות בקבצי midi
  rpm -qa |grep 'midi'
אני רוצה לדעת באיזה קובץ ובאיזו שורה השתמשתי בפונקציה fork:
  grep  -n 'fork()' `ls *.c`

find

מצא לי את הקובץ ECLIPSE.ogg בתיקייה pink_floyd ובתתי התיקיות שלה.

  find pink_floyd -name  ECLIPSE.ogg
רגע, אני לא בטוח אם כתבתי אותו עם אתיות גדולות או קטנות:
  find pink_floyd -iname  ECLIPSE.ogg
אבל אני גם לא בטוח באיזה פורמט שמרתי אותו (כקובץ ogg או mp3 או בשד יודע איך):
  find pink_floyd -iname  ECLIPSE.*
(רוצה לומר, find אוכלת wildcards).
אפשר גם עם ביטויים רגולריים למשל למצוא בתיקייה הנוכחית את כל הקבצים ששמם מכיל pink או floyd אוmoon:אוmoon:
  find . -regex '.*\(pink\|floyd\|moon\).*'
מצא לי בתיקיית הבית קבצים הגדולים מ 1000KB
  find ~/ -size +1000k

אותו הדבר אבל עבור קבצים הקטנים מ 100KB

  find ~/ -size -100k

הנה משהו שימושי למשתמשי vim שרוצים לעשות ניקיון למשל, אני רוצה למחוק בתיקייה הנוכחית באופן רקורסיבי את כל הקבצים שמסתיימים ב ”~”

[sagivba@black find_example]$ tree
.
|-- a.txt
|-- a.txt~
`-- dir1
    |-- b.txt
    `-- b.txt~

1 directory, 4 files
[sagivba@black find_example]$ rm -f `find -name '*~'`
[sagivba@black find_example]$ tree
.
|-- a.txt
`-- dir1
    `-- b.txt

1 directory, 2 files
[sagivba@black find_example]$ 
העירו את תשומת ליבי כי בפקודה זאת עלולה להיות בעייה אם שמות הקבצים מכילים תווי רווח. עדיף להשתמש ב
-find -name '*~' -print0 | xargs -0 rm -f

יש עוד המון אופציות שימושיות, אני אעצור כרגע כאן.

slocate

במערכות רבות קיימת הפקודה locate, או הגרסה המאובטחת שלה slocate. הרעיון בכלי הנהדר הזה הוא לאפשר חיפוש מאוד מהיר של קבצים על פי שמם. הסיבה שהכלי הזה מהיר מחיפושים אחרים הוא שהוא מבצע עיבוד מקדים ומאנדקס את הקבצים. בד”כ אחת ליום בעזרת cron.
מצא לי את הקובץ hosts

  locate hosts

which

היכן ממוקם האינטרפטר perl ?

  which perl
לא, אני מחזיק כמה גרסאות של perl . אני רוצה לדעת לגבי כולן:
  which -a perl

החלפה

perl

אני רוצה להחליף בקובץ הטקסט dark_side.txt את כל המופעים של המילה pink במילה floyd:

  perl -pi -e "s/pink/floyd/g;" dark_side.txt
האם כבר ציינתי שPerl מאוד שימושית? בוא נבין מה כתוב כאן, המטרה שלי היא לא ללמד אתכם Perl, אלא רק לתת לכם מושג כללי לגבי העוצמה הטמונה בשפה זו' אפילו ככלי לשורת פקודה ולא כשפת תכנות או סקריפטינג…
טוב אז הנה ההסבר:
האופציה גורמת לכך שהקוד שנכתוב ירוץ בלולאה הנראית כך:
  while (<>) {
      s/pink/floyd/g;
  } continue {
      print;
  }
האופציה i גורמת לכך שהפלט יכתב לתוך הקובץ dark_side.txt
האופציה e מסמנת לperl שמיד יגיע קוד בperl והקוד :s/pink/floyd/g הוא בעצם הוראה לבצע החלפה של pink בfloyd.

awk

קורא חביב בשם רומן ביקש שאוסיף פרק על awk - אז הנה זה בא (למרות שאני נוטה להשתשמש יותר בperl) היתרון של awk על perl הוא בעיקר בסקריפטינג אני חושב, מאחר והיא קלה יותר מבחינת ביצועים. כאמור אני עצלן ולא נוטה להשתמש בה לכן יתכן ואני טועה.

אז בואו נתחיל קצת להבין את התחביר של הפקודה ובעיקר שימושים נפוצים בה.

לצורך הדוגמאות נשתמש בקובץ הבא:

$ cat -n tst_awk.txt
     1  gold
     2
     3  golden dolphin
     4  golden:dolphin:blue:sea
     5  iron:dolphin:blue:sea

ראשית הסבר קצה על מבנה הפקודה:

awk  'awk commnds' input_file


למשל אם אנחנו רוצים להדפיס את כל השורות בקובץ שמכילות את מחרוזת gold:

$ awk '/gold/ { print $0}' tst_awk.txt
gold
golden dolphin
golden:dolphin:blue:sea

שימו לב לשני דברים מעניינים, האחד awk יודעת לטפל בביטויים רגולריים. והשני $0 משמעותו כל השורה הנוכחית.

הפקודה awk מאד שימושית לטיפול בשורות המכילות שדות המופרדים על ידי דפוס מסויים למשל שורות 4 ו- 5 המופרדות על ידי ”:” למשל הפקודה הבאה :

X="A:B:C:D:E" ; echo $X | awk -F":" '{print $2 $4 $5}'
BDE
נראה מסובך ? האמת שזה די פשוט ותכף תראו את זה , תהיו איתי. בחלק הראשון הכנסנו למשתנה X את המחרוזת המופרדת ב”:” , בחלק השני השתמשנו ב echo בכדי לשפוך את תוכן השדה המופרד לתוך awk ואז הגענו לחלק המעניין הדגל F- משמעותו שעכישיו אנו הולכים להצהיר על מפריד (במקרה שלנו “:”) ברגע שמשתמשים בו awk מכניסה את הערך של כל שדה בשורה למשתנה $1 $2 … ואנו ביקשנו להדפיס את הערכים של המשתנים השני הרביעי והחמישי.

באו נראה עוד דוגמא הפעם מהקובץ שלנו:

$ awk -F":" '/gold/ { print $2}' tst_awk.txt


dolphin

הפעם הדפסנו בכל שורה בקובץ שיש בה את המחרוזת gold את המשתנה השני ולכן קיבלנו שורות ריקות פרט לאחרונה. בואו נשפר את זה כך שקודם נבדוק אם בשורה הנוכחית יש את הסימן ”:” ורק אח”כ נדפיס:

$ awk -F":" '/gold/ {if (/:/)   print $2}' tst_awk.txt
dolphin

טוב – זאת התחלה נחמדה לנושא וזה גם שימושי במיוחד לטפל בקבצים כמו etc/passswd או במשתנים סביבתיים כמו PATH$. ולסיום דוגמא שמחזירה כפלט רק את השורות שבהם מופיעה המחרוזת gold ומחליפה בהן את gold בbronze:

$ awk 'sub(/gold/,"bronze") { print $0}' tst_awk.txt
bronze
bronzeen dolphin
bronzeen:dolphin:blue:sea
לצערי לא התחלתי אפילו למצות את השימושים שבפקודה הזו, אבל נראה לי שזה מספיק בתור התחלה.

תהליכים ויישומים

אני מרגיש שהסבר קצר נדרש לפני שנתחיל בדוגמאות, הנושא הזה גם נראה לי מעניין, אבל תרגישו חופשי לדלג עליו.
כאשר אנו מריצים פקודה או מפעילים תוכנית, מערכת ההפעלה מעלה אותה לזיכרון לתוך טבלה שנקראת טבלת התהליכים. בטבלה זו נשמרים נתונים שונים על התהליך, וביניהם מספר תהליך יחודי (PID).
לתהליכים יש יכולת לשכפל את עצמם או לתת את המקום שלהם לטובת תהליכים אחרים. מרגע שתהליך שכפל את עצמו לשכפול אנו קוראים “תהליך בן”.
תהליך אחד מיוחד שאתם רוצים להכיר הוא התהליך init כל התהליכים שאתם יוצרים הם בנים של init. כך ניתן לדמיין עץ תהליכים שבשורשו יש את init וממנו מסתעפים שאר התהליכים.
כדי לקבל מושג על מה שכתבתי לעיל העתיקו את הסקריפט הזה:

  #!/bin/bash
  #this script print on screen it PID and current index
  for I in $(seq 1 3)
  do
  # $$ is an envaromental variable consists
  # the PID of this script
  echo “$$ says hey, got to $I”
  sleep 1
  done
לתוך קובץ, שימרו אותו בשם test.sh בתיקיית הבית שלכם, תנו לו הרשאות ריצה. ואז, בטרמינל:
  [sagivba@sagivba sagivba]$ cd ~
  [sagivba@sagivba sagivba]$ ./test.sh  >> out.txt &
  [1] 13810
  [sagivba@sagivba sagivba]$ ./test.sh  >> out.txt &
  [2] 13813
  [sagivba@sagivba sagivba]$ ps >>out.txt
מה היה לנו כאן? שורה ראשונה “~ cd” עברנו לתיקיית הבית. בשלוש השורות הבאות הרצנו את הסקריפט ברקע (בעזרת הסימן &) ואת הפלט שירשרנו לקובץ out.txt (זו המשמעות של הסימן « . ובשורה האחרונה הצגנו את התהליכים. וככה נראת דוגמה לקובץ הפלט out.txt
  [sagivba@sagivba sagivba]$ cat out.txt
  “13797 says hey, got to 1”
  “13800 says hey, got to 1”
  “13797 says hey, got to 2”
  “13800 says hey, got to 2”
  “13797 says hey, got to 3”
  “13800 says hey, got to 3”
    PID TTY          TIME CMD
  15648 pts/3    00:00:00 bash
  13800 pts/3    00:00:00 test.sh
  13806 pts/3    00:00:00 sleep
  13807 pts/3    00:00:00 ps
  “13810 says hey, got to 1”
  “13813 says hey, got to 1”
  “13810 says hey, got to 2”
  “13813 says hey, got to 2”
  “13810 says hey, got to 3”
    PID TTY          TIME CMD
  15648 pts/3    00:00:00 bash
  13810 pts/3    00:00:00 test.sh
  13813 pts/3    00:00:00 test.sh
  13817 pts/3    00:00:00 sleep
  13818 pts/3    00:00:00 sleep
  13819 pts/3    00:00:00 ps
  “13813 says hey, got to 3”
  [1]-  Done                    ./test.sh >>out.txt
  [2]+  Done                    ./test.sh >>out.txt

top

אני רוצה לעקוב אחר התהליכים שרצים לי במערכת באופן דינאמי:

  top
אני רוצה לעקוב רק אחרי התהליכים שמספריהם (הPID שלהם) : 31002 31003 31004
  top -p31002 -p31003 -p31004
אני רוצה להרוג תהליך שאני רואה בtop: כשאתם בtop הקישו k ואחריו את מספר התהליך ו - מאוד שימושי כשרוצים להרוג מספר תהליכים בעלי מכנה משותף.

ps / pstree

אבל רגע! איך אני יכול לדעת מה מספר התהליך (PID של כל תהליך)?

  pstree -p
או לחלופין
  ps
ואם אתם באמת רוצים לקבל מידע רב יותר :
  ps -auxw
טיפ קטן: שימוש מושכל בgrep יכול לעזור לכם כאן מאוד.

kill

תהליך מסויים נתקע /אני רוצה להרוג תהליך:
אפשר, יש אם אתם יודעים את מספר התהליך :

  kill
ואם אתם רוצים לשלוח סיגנל ספציפי, פשוט תנו את המספר שלו אחרי מינוס.
  kill -9
  killall
הנה מגיע עוד קטע תיאורטי ( כבר אמרתי שאתם יכולים לדלג אם זה משעמם אתכם?)
למעשה מה שהפקודות הללו עושות הוא לשלוח סיגנלים לתהליכים.
אני אסביר:
לתהליכים יש דרך לתקשר עם תהליכים אחרים בעזרת שליחת מספרים מיוחדים אל התהליכים. דמיינו לעצמכם צוות טבחים של מסעדה שעסוקים כל אחד בעבודה שלו, כל טבח אחראי על תחום אחר: רטבים, סלטים וכו', לכל טבח יש שם ייחודי. כאשר אחד המלצרים צריך לבצע הזמנה הוא צועק את שם הטבח ואת מספר המנה. הטבח, השקוע בעבודתו, שומע את הצעקה, נחרד קלות לרגע, עיניו מפלבלות בבעתה אנה ואנה , הוא מחליט מה לעשות בהתאם להזמנת המלצר ופועל.
תהליכים, כמו הטבחים, עסוקים בעבודתם עד שתהליך אחר, כמו המלצר באנלוגיה שלנו, מפריע להם. התהליך האחר זורק להם מספר (כמו מספר מנה) והם בודקים מה הם אמורים לעשות כשאירוע כזה מתרחש.
המספרים הללו נקראים סיגנלים. נהוג לומר כי תהליך א' זורק סיגנל ותהליך ב' תופס סיגנל.
דוגמא נפוצה לזריקת סיגנל היא הקשת ctrl+c בזמן ריצה של תוכנית.
דוגמא נוספת היא שליחת הסיגנל 9 (SIGKILL) בדוגמא השנייה.
בואו נעזוב רגע את הפואטיקה ונדבר קצת יותר לעומק.
אם החלטתם לתכנת קצת או לכתוב סקריפטים שידעו לתפוס סיגנלים ולטפל בהם יתכן ויעניין אתכם לקרוא מעט יותר בנושא., נתתי דוגמא קטנה כחלק מהסקריפט zip_n_mail.sh שבהמשך. כאשר משתמש יקיש ctrl+c בזמן ריצה של הסקריפט הסקריפט לא יעצר מיד, אלא ינקה קבצים זמניים שיצר ואז יצא.
טוב, זה היה אולי קצת כבד, בואו נעבור לכמה דברים קצת יותר קלילים.

אינטרנט ורשתות:

טוב אחרי החלק הקודם שהיה די כבד בואונתחיל עם משהו קליל ומאד שימושי

wget

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

  [sagivba@sagivba tmp]$ wget -q http://penguin.org.il/
הדגל q מסמן לwget שלא להפיק מידע על ההורדה.
אני רוצה להוריד את כל הקישורים שבקובץ links.txt
  [sagivba@sagivba tmp]$ wget -i links.txt
ההורדה נתקעה ולא הסתיימה אני רוצה לנסות להוריד מהנקודה האחרונה.
  [sagivba@sagivba tmp]$ wget -c http://penguin.org.il/
אני רוצה להוריד את כל הקבצים בסידרה:
  img1.gif img2.gif...img999.gif
  wget \
  `for i in $(seq 1 999) ;\
  do\
   echo "http://server/path/to/img$i.gif”;\
  done`
כמובן שאם אתם מתעתדים להשתמש בפקודה הזו יותר מפעם אחת עדיך לכם לשמור אותה כפונקציה בbashrc. שלכם.
לפרטים נוספים – קראו את הסעיף: “העשירו את bashrc. שלכם” בהמשך.
אני רוצה להוריד אתר שלם אלי למחשב
  wget -mirror http://www.the.site.U.want.org

בחלק הבא אני מניח כי יש לכם ידע בסיסי ביותר ברשתות. // אנסה להציג את הדברים שאני מוצא כשימושיים ביותר.

איתחול שרות הרשת

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

http://www.penguin.org.il/guides/init/ ) בכדי לאתחל את שרות הרשת עליכם להקליד כמשתמש העל:

service networking restart

או ברוב המערכות

/etc/init.d/network restart

ping

פקודה זו עוזרת לנו לבדוק האם יש מענה ממחשב כלשהו המחובר לרשת.
מה שהיא עושה בגדול זה שולחת ECHO_REQUEST וממתינה לתגובה. למשל:

[sagivba@black test]$ ping -b 192.168.2.109
PING 192.168.2.109 (192.168.2.109) 56(84) bytes of data.
64 bytes from 192.168.2.109: icmp_seq=1 ttl=64 time=0.057 ms
64 bytes from 192.168.2.109: icmp_seq=2 ttl=64 time=0.052 ms
64 bytes from 192.168.2.109: icmp_seq=3 ttl=64 time=0.053 ms
.
.
.
# HERE I PRESSED +c ...

--- 192.168.2.109 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2051ms
rtt min/avg/max/mdev = 0.052/0.054/0.057/0.002 ms
ימשיך לשלוח בקשות כל זמן שלא הפסקנו אותו.
ping -c 3 192.168.2.1
ישלח שלוש פעמים פקטות ל192.168.2.1.
ping -W 3 192.168.2.1
ימתין לכל היותר שלוש שניות ואז ייצא.

nmap

פקודה זו עוזרת לנו לסרוק כתובת או טווח של כתובות ולגלות דברים “מעניינים” שאולי מהווים חורי אבטחה ברשת שלנו או לחלופין מעידים על בעיות בהגדרתה. למשל אם אני מעוניין לדעת האם השרת שלי שכתובתו 192.168.2.100 מאזין לפורט 22:

# nmap -P0 sagivba |grep 22
22/tcp   open   ssh
עוד שימוש שאני מוצא מעניין בפקודה הזו הוא לסרוק את כל הרשת הפנימית שלי:
nmap -O 192.168.2.0-200

ifconfig

פקודה זו מאפשרת לנו לקבל מידע על ממשקי הרשת ולהגדיר אותם באופן זמני (למשל עד הreboot הבא). כאשר מקישים את הפקודה הזו ללא ארגומנטים נקבל מידע על ממשקי הרשת הפעילים. לעיתים נרצה לשנות הגדרה של ip או דברים אחרים. הדרך הפשוטה ביותר לכך היא:

ifconfig eth0 192.168.2.101 netmask 255.255.255.0 broadcast 192.168.2.255

עכשיו הגדרנו את eth0 שיקבל את הIP הזה: 192.168.2.101, ה netmask מוגדר להיות 255.255.255.0 וכו'.

קבצים רלוונטיים

/etc/resolv.conf

$cat /etc/resolv.conf
nameserver 192.168.2.1

/etc/sysconfig/network

קובץ כללי של הגדרות הרשת של המחשב התיעוד מספיק טוב בכדי שתוכלו להבין בעצמכם. יש להבחין בין הגדרה עבור IP סטאטי ועבור דינאמי:

$cat  /etc/sysconfig/network
# this is what you need using DHCP
NETWORKING=yes

$cat  /etc/sysconfig/network
# this file is for static IP network configuration
NETWORKING=yes
HOSTNAME=sagivba.ath.cx  # Hostname is defined here and by command hostname
FORWARD_IPV4=false       # True for NAT firewall gateways and linux routers.
                         # False for everyone else(desktops and servers)
GATEWAY="192.168.2.1"    # Used if your network is connected to another
                         # network or the internet.
                         # Static IP configuration. 
                         # Gateway not defined here for DHCP client.

הקובץ ifcfg-eth0 מגדיר את הממשק של eth0 אם קיימים במחשב מספר כרטיסי רשת – סביר להניח כי יופיעו גם הקבצים ifcfg-eth1 וכו' הנה דוגמאות שהגדרת DHCP ולהגדרת IP סטאטי:

# cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=dhcp
NETMASK=255.255.255.0
ONBOOT=yes
METRIC=10

$ cat /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=static
BROADCAST=192.168.2.255
IPADDR=192.168.2.100
NETMASK=255.255.255.0
ONBOOT=yes

/etc/hosts

הקובץ הזה מגדיר שמות מחשבים ברשת לדוגמא:

$ cat /etc/hosts
127.0.0.1               localhost
192.168.2.2             sagivba.ath.cx  sagivba
192.168.2.1             edmax

מולטימדיה

mplayer

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

[sagivba@sagivba my_sounds]$ mplayer *

מקשים שימושיים לשליטה בmplayer:

  • עצירת ההקרנה/המשך: p
  • מסך מלא f
  • עצירה – יציאה: q
  • שינוי עוצמת קול:הגברה 0, הקטנה 9, השתקה m
  • עבור 10 שניות קדימה/אחורה:חץ ימינה, חץ שמאלה
  • עבור דקה קדימה/אחורה: חץ למעלה, חץ למטה
  • עבור 10 דקות קדימה/אחורה: <,>


הורדת דיסק מוזיקה שלם למחשב בקבצי wav:

cdparanoia -sB
==== המרה בין סוגי קבצים ==== === mpg123 === המרה בין קבצי מוזיקה מmp3 לwav
  mpg123 --wav file.wav file.mp3
מmp3 לcdr
  mpg123 --cdr file.cdr file.mp3
מwav לmp3
  notlame file.wav file.mp3
שימו לב! mp3 הינו פורמט מוגן בפטנט, לכן תוכנות שממירות לפורמט זה צריכות לשלם עבור השימוש בפורמט, אם אתם מעוניינים בפורמט פתוח, השתמשו בogg במקום.

convert

המרה בין קבצי תמונה.
מbmp לjpeg

  convert file.bmp file.jpg
מbmp לpng, מjpeg לgif, מgif לpng…. נו טוב, אני מניח שהבנתם את הרעיון.

צריבה

צריבה משורת פקודה יכולה להוות כלי מאוד נוח לגיבוי קבצים חשובים, נדב מבור כתב מדריך בנושא:

http://www.penguin.org.il/guides/cdrecord/

cdrecord

תקציר של המדריך:
בפעם הראשונה שאתם מעוניינים לצרוב:

  cdrecord -scanbus
בעזרת הפרמטר scanbus תוכלו לדעת את השלשה x,y,z שתידרשו להקליד.
למשל אצלי זה הפלט:
  [sagivba@80 tools]$ cdrecord -scanbus
  Cdrecord-Clone 2.01a18-dvd (i686-pc-linux-gnu) Copyright (C) 1995-2003 Jrg Schilling
  Note: This version is an unofficial (modified) version with DVD support
  Note: and therefore may have bugs that are not present in the original.
  Note: Please send bug reports or support requests to .
  Note: The author of cdrecord is not to be bothered with problems in this version.
  Linux sg driver version: 3.1.25
  Using libscg version 'schily-0.7'
  scsibus0:
          0,0,0     0) 'SONY    ' 'CD-RW  CRX230E  ' 'QYS1' Removable CD-ROM
          0,1,0     1) *
          0,2,0     2) *
          0,3,0     3) *
          0,4,0     4) *
          0,5,0     5) *
          0,6,0     6) *
          0,7,0     7) *
סימנתי באדום את השלשה x,y,z
כאשר אתם רוצים לצרוב מידע:
* שלב ראשון, הכניסו את הקבצים הרצויים לספריה אחת אם אתם מעוניינים להמיר את הקבצים לפני הצריבה לפורמט אחר, זה הזמן.
* שלב שני, הכינו קובץ iso: מהספריה:
  mkisofs -r -J -o burn_baby_burn.iso ~/dir_to_burn
אם אתם מעוניינים להוסיף לדיסק שם ע”מ שיוצג באופן נאה יותר במערכות הפעלה אחרות:
  mkisofs -V "MyBelovedFiles" -r -J -o burn_baby_burn.iso ~/dir_to_burn
* שלב שלישי צירבו את הספריה:
  cdrecord -v -eject speed=40 dev=x,y,z burn_baby_burn.iso
שימו לב כי במקום dev=x,y,z צריכים להופיע המספרים שמצאנו בעזרת scanbus. לאחר הצריבה אתם יכולים לבצע :
אפשר גם לבצע את שני השלבים האחרונים בבת אחת בעזרת פונקציה בbashrc./~

cdrdao

בכדי לצרוב cd מוזיקה שלם עליכם לבצע פעם אחת:

  cdrdao scanbus
את התוצאות אתם יכולים לשמור בקובץ cdrdao./~ כך:
  write_device: "0,1,0"
  write_driver: "generic-mmc"
עתה כל שעליכם לעשות:
  cdrdao copy

חישובים

bc

לאחרונה “גיליתי” מחדש ישום שעוזר לי מאד בחישוב מהיר של דברים משורת הפקודה.
קצרה היריעה מלתאר את היכולות של הפקודה BC, אולם אני אנסה להדגים כמה דברים שימושיים.
בכדי להפעיל את הפקודה במצב אינרטאקטיבי (כמו מחשבון למעשה) נקליד:

[sagivba@black ~]$ bc -i
bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
1+1
2

לאחר שקיבלנו את הממשק של BC אנו יכולים לקבוע את רמת הדיוק שאחרי הנקודה:

[[sagivba@black ~]$ bc -i
bc 1.06
Copyright 1991-1994, 1997, 1998, 2000 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
1/3
0
scale=1
1/3
.3
scale=2
1/3
.33
scale=20
1/3
.33333333333333333333
quit
יש לנו אפשרות לקבוע משתנים:

[sagivba@black ~]$ bc -iq
scale=10
x=3
x^2+3*x+1
19
ואפילו פונקציות:

[sagivba@black ~]$ bc -iq
define f(n) {return n^2+3*n+1}
f(3)
19

וגם יש פונקציות מובנות - נשתמש באופציה l בכדי להעלותן, מכאן השמיים הם הגבול: למשל נשתמש ב arctang בכדי לחשב את PI:

[sagivba@black ~]$ bc -ilq
scale=50
a(1)*4
3.14159265358979323846264338327950288419716939937508
quit

העשירו את bashrc. שלכם

במקרים רבים אנו משתמשים ברצף פקודות קבוע שוב ושוב למשל clear ואחרי ls -l. במקום להקליד אותם שוב ושוב אתם יכולים להכניס אותם לalias:

  alias clsl='clear ; ls -l'
עתה בכל פעם שנקליד clsl יתבצעו שתי הפקודות שלעיל עד שנסגור את הקונסול.
כאשר מדובר בפעולות מורכבות יותר או כאלו שאמורות לקבל פרמטרים יותר נוח לכתוב פונקציה. למשל במקום ליצור ספריה ואז להכנס אליה אפשר לכתוב:
  function mdcd ()
  {
  	mkdir $1
  	cd $1
  }
אם לא ברור לכם מה כתבתי כאן אולי כדאי שתקראו את המדריך של ברק בלוך לתכנות בbash.
וכך למשל :
  [sagivba@Knoppix dir1a]$ function mdcd () { mkdir "$1"; cd "$1"; }
  [sagivba@Knoppix dir1a]$ mdcd test
  [sagivba@Knoppix test]$ pwd
  /home/sagivba/tmp/dir1a/test
על מנת שנוכל לקבוע alias קבוע או פונקציה באופן קבוע עלינו להכיר קובץ חביב בשם “basrc.” החבוי בתיקיית הבית - הכנסת alias או פונקציית bash לתוך קובץ זה תגרום להן להיות מוגדרות בכל פעם שנכנס לקונסול.

הערה: הגרשיים נועדו על מנת להתמודד עם שמות קבצים המכילים רווחים ושאר מריעין בישין. אישית, אני לא נותן לקבצים שמות בעברית או עם רווחים, ומשתדל שהקבצים יהיו עם אותיות קטנות - סתם הרגל שרכשתי עם הזמן, חוסך הרבה בלאגן מיותר.
עוד דבר שימושי שאפשר להוסיף לקובץ זה, הוא הגדרת משתני סביבה משלכם. למשל:

  export EDITOR='vim';
יגרום לכך שכתיבת השורה:
  $EDITOR
בתוך סקריפט תפעיל את עורך הטקסט vim.

אני למשל משתמש ברעיון הזה בכדי להגדיר צבע שונה בפרומפט של כל מכונה אצלי ברשת הביתית בעזרת שינוי המשתנה הסביבתי PS1 – כך שאני מתחבר ב SSH אני מונע מצב שאתבלבל חלילה בין המכונות.

כתיבת סקריפטים:

אם אינכם יודעים לכתוב סקריפטים בbash אני ממליץ בחום כי תקראו את המדריך של ברק בלוך בנושא. הוא קצר ותמציתי. ידע בתחום הזה יכול לחסוך לכם המון טרחה ועבודה בעתיד:

http://www.penguin.org.il/guides/bash-scripting/

מתי כדאי לשקול כתיבת סקריפט:

כל פעם שאתם מבצעים פעולה שחוזרת על עצמה, אני מציע שתשקלו להוסיף סקריפט למדריך הבית שלכם.
למשל, לעיתים קרובות אני מכווץ קובץ ושולח אותו כzip לחברים.
לשם כך כתבתי סקריפט קטן שמשתמש בmutt ובzip:

  #!/bin/bash

  #===  FUNCTION ===================================================
  #
  #         NAME: error_exit
  #
  #  DESCRIPTION:  Function for exit due to fatal program error
  #
  #---- PARAMETER -------------------------------------------------
  #        Number  Description
  #           1 :  string containing descriptive error message
  #================================================================
  function error_exit
  {

          echo "${PROGNAME}: ${1:-"Unknown Error"}" >&2
          exit 1
  }
  Main
  {

  zip -rq  $1.zip $1 || error_exit "problam: ziping the flie - program exit"

  echo "This mail sent by the zip_n_send.sh written by Sagiv Barhoom"\
  	|mutt  -s "$1.zip" -a "$1.zip"   $2 \
  			|| error_exit "mailing thr file has faild"
  }
יתכן כי לא ברור לכם מה עשיתי כאן, אני אנסה להבהיר:
את השורה הראשונה אין צורך להסביר – אם לא הבנתם אותה, סביר להניח שלא קראתם את המדריך של ברק בלוך.
את תחילת השורה הראשונה בMain הסברתי בחלק שמציג את zip:
כווץ את הספריה/קובץ הבאים באופן רקורסיבי לתוך קובץ ששמו זהה עם סיומת zip .
החלק השני של השורה עוסק במצב שבו zip נכשלה הכתיבה:

first_command || second_command

משמעותה: בצע את first_command ואם היא מצליחה - עצור, אחרת בצע את second_command.
במקרה שלנו יש קריאה לפונקציה error_exit שמדפיסה הודעת שגיאה ויוצאת עם הערך 1.

כמה נקודות שימושיות שכדאי לקרוא

הנה עוד כמה נקודות שימושיות בסקריפינג בbash :
לולאות for שונות :
הדפס מספרים מ1 עד 7

  for I in  1 2 3 4 5 6 7  ;do echo $I; done
מה אם אני רוצה בין 1 ל999? אני צריך את כולם?
  for I in $(seq 1 999) ;do echo $I; done
אני רוצה לעבור על כל הקבצים בdir
  for file in $( ls dir ); do  echo $file; done
אני רוצה לעבור על כל הקבצים בספרייה הנוכחית שמסתיימים ב”pl.”
  for file in *.pl; do echo $file; done
פעולות אריתמטיות בסגנון תכנות בC/JAVA:

C bash
int num=0; declare -i num;
num++; (( num++ ));
num–; (( num-- ));
–num; (( --num ));
++num; (( ++num ));
result = num<2?3:7; (( result = num<1?3:7 ))

איך לדבג סקריפטים ולהישאר בחיים.

טוב, אז כתבתם סקריפט מדהים: my_coolest_script.sh, שגורם למחשב לעשות שפגאט, פליק פלאק באוויר, ותוך כדי כך פותר אם NP == P , נתתם לו הרשאות ריצה, לקחתם נשימה והקלדתם:

  $./my_coolest_script.sh
…לא עובד ;-( .
אז הנה כמה טיפים שיעזרו לכם לדבג:
כדי לבדוק את הסקריפט מבלי להריץ אותו:
  bash -n ./my_coolest_script.sh
או לחלופין הוסיפו את השורה :set -n לתוך הסקריפט מהנקודה שאתם רוצים לבדוק.
בכדי לקבל מידע לגבי איזו פקודה הורצה מתי:

set -v

כל אלו נחמדים - אבל אני נעזר בדרך כלל ב:

set -x

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

שיוף הפינות של הסקריפט.

החלק הזה מכיל נושאים מעט יותר מורכבים, שאותם אדגים בעל ידי סקריפט שלם שכתבתי – סימנתי באדום את הקטעים המעניינים:
תפיסת סיגנלים
יציאה מסודרת
שימוש בפונקציות שיהוו שבלונה לסקריפטים העתידים לבוא.
שימוש בכלי bash.vim - סקריפט של vim שיעזור לכם לתכנת מהר סקריפטים. פרטים נוספים פנו למדריך לכתיבת קוד במהירות בעזרת vim
בדיקות קלט אם החלטתם להכנס לזה, וללמוד לכתוב סקריפטים אינטראקטיביים מלוטשים סביר להניח שתרצו לבצע בדיקות קלט. אני ממליץ לכם פשוט ללמוד קצת Perl – אולי זה לא הפתרון האידאלי לבדיקת קלט אבל גיליתי שהידע שאני צובר אט אט ב - Perl שימושי בכל כך הרבה מקרים… המדריך הטוב ביותר שנתקלתי בו בעברית עד היום הוא ללא ספק המדריך של שמואל פומברג :

http://code.semuel.co.il/perlhebtut/index.html

אני לא אסביר את הכתוב בסקריפט מעבר לתעוד ( והתעוד מאד מפורט) אם זה מעניין אתכם, אני בטוח שתשברו קצת את הראש ותסתדרו. ועכשיו בלי שהות מיותרת:

  #!/bin/bash
  #===============================================================================
  #
  #         FILE:  zip_n_mail_tutorial.sh
  #
  #
  #         Copyright 2004, Sagiv Barhoom .
  #
  #         This program is free software; you can redistribute it and/or
  #         modify it under the terms of the GNU General Public License as
  #         published by the Free Software Foundation; either version 2 of the
  #         License, or (at your option) any later version.
  #
  #         This program is distributed in the hope that it will be useful, but
  #         WITHOUT ANY WARRANTY; without even the implied warranty of
  #         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  #         General Public License for more details.
  #
  #        USAGE:  ./zip_n_mail.sh [ -h | --help ] [-t EmailAddress] [-f FileName]
  #
  #     SYNOPSIS:
  #
  #  DESCRIPTION:  zip an input file and mail it
  #      OPTIONS:
  #           -h, --help      Display this help message and exit.
  #           -t  EmailAddressto: the mail address of the recipient
  #           -f  FileName    path of the file to zip
  # REQUIREMENTS:  mutt and zip
  #         BUGS:  ---
  #        NOTES:  ---
  #       AUTHOR:  Sagiv Barhoom (),
  #      VERSION:  1.2
  #      CREATED:  11/30/2004      File created by new_script ver. 0.1
  #     REVISION:
  #       01/12/2004      Things I added to this version:
  #             * graceful exit - cleaning all temp files
  #             * catching traps so that on ctrl+c the  will exit  gracefully
  #             * input validation
  #             * aliass for names
  #
  #===============================================================================

  ################################################################################
  #       Constants
  ################################################################################

      PROGNAME=$(basename $0)
      VERSION="0.1"

  ###############################################################################
  #       Functions
  ###############################################################################

  #===  FUNCTION  ===============================================================
  #
  #     NAME:  clean_up
  #
  #  DESCRIPTION: removing temporary files
  #
  #==============================================================================
  function clean_up
  {
      rm -f ${TEMP_FILE1} "${TEMP_FILE1}.zip"

  }

  #===  FUNCTION  ===============================================================
  #
  #     NAME:
  #
  #  DESCRIPTION:  Function for exit due to fatal program error
  #
  #---- PARAMETER  -------------------------------------------------------------
  #    Number  Description
  #       1 :  string containing descriptive error message
  #===============================================================================
  function error_exit
  {

      echo "${PROGNAME}: ${1:-"Unknown Error"}" >&2
      clean_up
      exit 1
  }

  #===  FUNCTION  ================================================================
  #
  #     NAME:  graceful_exit
  #
  #  DESCRIPTION:  Function called for a graceful exit
  #        this is a very nice idea, one can use it in other languages
  #
  #===============================================================================

  function graceful_exit
  {
      clean_up
      exit
  }

  #===  FUNCTION  ================================================================
  #     NAME:  signal_exit
  #
  #  DESCRIPTION:  Function to handle termination signals
  #           Wow,  - A way cool idea: how to handle those times, when the
  #           user is not patience  and hit ctrl + c before the script was
  #           proparly terminated;
  #---- PARAMETER  --------------------------------------------------------------
  #    Number  Description
  #       1 :  the signai that was trapped
  #===============================================================================
  function signal_exit
  {
      case $1 in
          INT)    echo "$PROGNAME: Program aborted by user" >&2
              clean_up
              exit
              ;;
          TERM)   echo "$PROGNAME: Program terminated" >&2
              clean_up
              exit
              ;;
          *)      error_exit "$PROGNAME: Terminating on unknown signal"
              ;;
      esac
  }

  #===  FUNCTION  ================================================================
  #
  #     NAME:   make_temp_files
  #
  #  DESCRIPTION:  Function to create temporary files
  #
  #===============================================================================
  function make_temp_files
  {
      # Temp file for this script, using paranoid method of creation to
      # insure that file name is not predictable.  This is for security to
      # avoid "tmp race" attacks.  If more files are needed, create using
      # the same form.

       TEMP_FILE1=$(mktemp  "tmp.XXXXXX") || error_exit "cannot create temp file!"
  }

  #===  FUNCTION  ===============================================================
  #
  #     NAME: usage
  #
  #  DESCRIPTION:  Function to display usage message (does not exit)
  #
  #===============================================================================
  function usage
  {
      echo "Usage: ${PROGNAME} [-h | --help] [-t EmailAddress] [-f FileName]"
  }

  #===  FUNCTION  ================================================================
  #
  #     NAME:  helptext
  #
  #  DESCRIPTION:  Function to display help message for program
  #
  #===============================================================================
  function helptext
  {

      local tab=$(echo -en "\t\t")

      cat <<- -EOF-

      ${PROGNAME} ver. ${VERSION}
      This is a program to zip file and send it as mail.

      $(usage)

      Options:

      -h, --help      Display this help message and exit.
      -t  EmailAddressto:
      -f  FileName    path of the file to zip

  -EOF-
  }

  #===  FUNCTION  ================================================================
  #
  #     NAME:  check_mail
  #
  #  DESCRIPTION:  check email address and exit if not valid
  #           here I used perl, one of my favoriete programing languages.
  #           I use it were others use sed and awk - TMTOWTDI
  #           (There Is More Than One Way To Do It)
  #
  #===============================================================================
  function check_mail {
      if  ! perl -e '
  my $mail= $ENV{'EmailAddres'};
  if ( $mail !~ /^[0-9a-zA-Z\.\-\_]+\@[0-9a-zA-Z\.\-]+$/ )
      {print "email address: characters not allowed on name\n";exit 1};
       #characters allowed on name: 0-9a-Z-._ on host: 0-9a-Z-. on between: @
  if ( $mail =~ /^[^0-9a-zA-Z]|[^0-9a-zA-Z]$/)
      {print "email address: must start or end with alpha or num\n";exit 1};
       #must start or end with alpha or num
  if ( $mail !~ /([0-9a-zA-Z]{1})\@./ )
      {print "email address: name must end with alpha or num\n";exit 1};
       #name must end with alpha or num
  if ( $mail !~ /.\@([0-9a-zA-Z]{1})/ )
      {print "email address: host must start with alpha or num\n";exit 1};
       #host must start with alpha or num
  if ( $mail =~ /.\.\-.|.\-\..|.\.\..|.\-\-./g )
      {print "email address: pair .- or -. or -- or .. not allowed";exit 1};
       #pair .- or -. or -- or .. not allowed
  if ( $mail =~ /.\.\_.|.\-\_.|.\_\..|.\_\-.|.\_\_./g )
      {print "email address: pair ._ or -_ or _. or _- or __ not allowed";exit 1};
       #pair ._ or -_ or _. or _- or __ not allowed
  if ( $mail !~ /\.([a-zA-Z]{2,3})$/ )
      {print "email address: host must end with '.' plus 2 or 3 alpha ";exit 1};
       #host must end with '.' plus 2 or 3 alpha for
       #TopLevelDomain (MUST be modified in future!)
  '     ;then
          error_exit "email adress not valid";
      fi

  }    # ----------  end of function check_mail  ----------

  ###############################################################################
  #       Program starts here
  ###############################################################################

  ##### Initialization And Setup #####

  # Set file creation mask so that all files are created with 600 permissions.

  umask 066

  # Trap TERM, HUP, and INT signals and properly exit
  # Read the function : signal exit

  trap "signal_exit TERM" TERM HUP
  trap "signal_exit INT"  INT

  # Create temporary file(s)

  make_temp_files

  ##### Command Line Processing #####

  if [ "$1" = "--help" ]; then
      helptext
      graceful_exit
  fi

  while getopts ":ht:f:" opt; do
      case $opt in
          t )
              EmailAddress=$OPTARG || error_exit "missing email adress."
              case  $EmailAddress in

                  name ) EmailAddress="email@eamil.com"
                  ;;

                  *)     export EmailAddres=${OPTARG}
                             check_mail;

                  ;;

               esac    # --- end of case ---

              ;;
          f )     echo "path of the file to zip - argument = $OPTARG"
              FileName=$OPTARG || error_exit "missing file to zip."
              if [ ! -r $FileName ];then
                  error_exit "file: $FileName does not exsist"
              fi
              echo "zipping into $TEMP_FILE1.zip"
              zip -rq  $TEMP_FILE1.zip $FileName \
                   || error_exit "problam: ziping the flie - program exit"
              ;;
          x )    set -x
              ;;
          h )     helptext
              graceful_exit ;;
          * )     usage
              clean_up
              exit 1
      esac
  done

  # the idea was taken from:
  # http://www.shelldorado.com/articles/mailattachments.html
  #
  # In the command above I had to specify the file name two times:
  # the first name denotes the  the file name the recipient will see.,
  # and the second name is the the attched file.
  #

  echo "This mail sent by the zip_n_send.sh written by Sagiv Barhoom"\
      |mutt  -s "$TEMP_FILE1.zip" -a "$TEMP_FILE1.zip"   $EmailAddress \
              || error_exit "mailing thr file has faild"
  echo
  echo "The file $FileName was sent to: $EmailAddress as $TEMP_FILE1.zip"
  echo "Have a nice day  :-)"
  echo

  ##### Main Logic #####

  graceful_exit

ניספח א' - קיצורי מקשים בקונסול.

Ctrl+a מזיז את הסמן לתחילת השורה
Ctrl+e מזיז את הסמן לסוף השורה
Ctrl+d יוצא אל המשתמש האחרון שאליו נכנסנו (בדומה לפקודה exit ) או יוצא מהקונסול לחלוטין
Ctrl+k מוחק את השורה ממיקום הסמן ועד סוף השורה.
Ctrl+_ ביטול מה שהוקלד לאחרונה בשורת הפקודה.

העברת תווים מיוחדים לשורת הפקודה:
טוב, כתבתם סקריפט נחמד ואתם רוצים שהוא יצפצף לכם בסוף ניתן לעשות זאת גם כך:

  echo $'\a'
אם אתם מכירים קצת C Perl סביר להניח שנתקלתם בדברים דומים בעבר.

שילוב מקשים תאור \a פעמון \b Backspace. \e Escape. \f Form feed. \n שורה חדשה \r Carriage return. \t טאב אופקי \v טאב אנכי
Backslash. \NNN תו שקוד ה ASCII שלו בייצוג אוקטאלי NNN

ניספח ב' - אני רוצה לעשות ולא יודע איך...

המון פעמים תגלו שאתם מכירים פקודה ורוצים לעשות איתה משהו אבל לא יודעים איך. זה מתסכל, אבל בד”כ הפתרון פשוט מאוד,
בסעיף זה אנסה לתת כמה טיפים למציאת פתרונות מהירים לבעיות. זו מיומנות שמפתחים ככל שעובר הזמן. מניסיוני הדל גיליתי שהדרך המהירה ביותר היא להשתמש ב help – אם זה לא מספיק, אני קורא בman ואם גם זה לא מספיק, אני משתמש ב google – בד”כ סביר להניח שמישהו כבר ניתקל בבעיה דומה. אם גם זה לא עוזר, אני חובט את ראשי בשולחן ומוציא קצת תסכול מודחק (כן, יש כבר שקערורית קטנה שם) ואז בלית ברירה, אני משתמש בדפי הinfo עד היום זה קרה רק פעמיים שלוש. אם אתם רוצים להשתפר בסקריפטינג המדריכים בtldp .org מומלצים בחום.

help

בכדי לקבל מושג מהיר על תחביר של פקודה בד”כ ניתן להשתמש באופציה help– או h- למשל, עבורmplayer (סימנתי את הדברים המעניינים באדום):

  [sagivba@80 sagivba]$ mplayer --help
  MPlayer 0.91-3.3.1  (C) 2000-2003 MPlayer Team
  CPU: Intel Pentium 4 Xeon Foster (Family: 8, Stepping: 2)
  Detected cache-line size is 64 bytes
  CPUflags:  MMX: 1 MMX2: 1 3DNow: 0 3DNow2: 0 SSE: 1 SSE2: 1
  Compiled with Runtime CPU Detection - WARNING - this is not optimal!
  To get best performance, recompile MPlayer with --disable-runtime-cpudetection
  Reading config file /etc/mplayer/mplayer.conf
  Reading config file /home/sagivba/.mplayer/config
  Usage:   mplayer [options] [url|path/]filename

  Basic options:  (complete list in the man page)
   -vo   select video output driver & device ('-vo help' for a list)
   -ao   select audio output driver & device ('-ao help' for a list)
   -vcd    play VCD (Video CD) track from device instead of plain file
   -dvd    play DVD title from device instead of plain file
   -alang/-slang    select DVD audio/subtitle language (by 2-char country code)
   -ss     seek to given (seconds or hh:mm:ss) position
   -nosound         do not play sound
   -fs              fullscreen playback (or -vm, -zoom, details in the man page)
   -x  -y     set display resolution (for use with -vm or -zoom)
   -sub       specify subtitle file to use (also see -subfps, -subdelay)
   -playlist  specify playlist file
   -vid x -aid y    select video (x) and audio (y) stream to play
   -fps x -srate y  change video (x fps) and audio (y Hz) rate
   -pp     enable postprocessing filter (details in the man page)
   -framedrop       enable frame dropping (for slow machines)

  Basic keys: (complete list in the man page, also check input.conf)
   <-  or  ->       seek backward/forward 10 seconds
   up or down       seek backward/forward  1 minute
   pgup or pgdown   seek backward/forward 10 minutes
   < or >           step backward/forward in playlist
   p or SPACE       pause movie (press any key to continue)
   q or ESC         stop playing and quit program
   + or -           adjust audio delay by +/- 0.1 second
   o                cycle OSD mode:  none / seekbar / seekbar + timer
   * or /           increase or decrease PCM volume
   z or x           adjust subtitle delay by +/- 0.1 second
   r or t           adjust subtitle position up/down, also see -vop expand

   * * * SEE THE MAN PAGE FOR DETAILS, FURTHER (ADVANCED) OPTIONS AND KEYS * * *
הסבר לאיך לקרוא את זה ממש מהר. בד”כ השורות הראשונות מתארות מה התוכנה עושה ואח”כ מגיע הusage שהוא אופן השימוש, זה נראה קצת מפחיד בפעם הראשונה שנתקלים בזה – אבל ברגע שתבינו את המבנה של זה, אני מבטיח לכם שתמיד תחפשו את הusage בדפי התעוד , הוא נותן את המושג הכי טוב לגבי השימוש בפקודה.
בואו ננסה להבין את השורה הזו:
  mplayer [options] [url|path/]filename
זה אומר בעצם להפעיל את mplayer ואחריה אופציות של שורת הפקודה (הסוגריים המרובעים מראים שהשימוש באופציות לא הכרחי) אחרי האופציות מופיע url או path וגם הם לא הכרחיים ולבסוף שם הקובץ הוא חובה.

man

אם לומר את האמת, לקח לי קצת זמן ללמוד לעבוד עם man. אני מניח זה צירוף של העצלנות שלי ושל כמות המידע העצומה שניתן לדלות מgoogle. בכל האמור בman - מילת המפתח היא less - אם תדעו לעבוד עם less כראוי יהיה לכם קל מאוד להסתדר עם דפי הman. שימו לב כי לפקודות רבות יש הדגמה לשימוש בתוך דפי הman – לעיתים תוכלו למצוא שם כמעט בדיוק את מה שחיפשתם – נסו למשל :

  man convert
על מנת לקבל מושג על מה אני מדבר.

info

לעיתים ניתן לקבל הסבר מקיף יותר בעזרת הפקודה info. התיעוד כאן זהה לעיתים לדפי הman אולם לפעמים אפשר לקבל ממש ספרונים קטנים לגבי כלים מסויימים. אני מוצא כי האורך של התעוד הוא מעבר לנדרש ברוב המקרים שטרחתי להגיע עד למקור מידע זה.

www.google.com

כמות המידע שניתן להשיג מהאינטרנט עצומה, החלטתי לצרף נספח קצר העוסק בטכניקות חיפוש כיוון שזה ללא ספק אחד הכלים רבי העוצמה לפתרון מהיר של בעיות. בד”כ כשצצה לי שאלה או בעיה מישהו כבר נתקל בה לפני ותיעד זאת ברשת, רק צריך לחפש קצת, וברוב המקרים זה הרבה יותר מהיר מלשאול מישהו בפורום ולחכות לתשובה.
לשם כך הקלידו את השאלה שלכם או מילות מפתח בגוגל, חפשו בקבוצות הדיון הרבה מאוד פתרונות נמצאים שם. קיים גם חלק יעודי ללינוקס www.google.com/linux
לעיתים כשנתקלים במונח או מילה לא מוכרים (למשל MBR) הדרך הקצרה להבין מהו היא להקליד בגוגל:

define:mbr

ואם זה לא עובד נסו :

what is MBR

נתקלתם בפקודה שאתם לא מכירים ולא מותקנת אצלכם במחשב (למשל iconv)? בכדי לקבל הרות קצרה איתה לפני שאתם מתקינים אותה, נסו בגוגל:

  man  iconv

www.tldp.org

אתר התיעוד של לינוקס.
מכיל המון מדריכונים (howtos ) שימושיים וגם ספרים מצויינים. בפרט, אני נעזר ב:

http://tldp.org/LDP/abs/html/index.html

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

מדריכים/טיפים_למשתמש_הביתי.txt · שונה לאחרונה ב: 2008/06/19 18:34 (עריכה חיצונית)
chimeric.de = chi`s home Creative Commons License Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0