האם מצאת עצמך מעוניין ללמוד עוד על כתיבת סקריפטים ב-Linux shell, אך לא היית בטוח מאיפה להתחיל? האם אתה חדש יחסית לעולם המערכות המבוססות על Unix ורוצה להרחיב את הכישורים שלך כדי לבצע תכנות בשפת ה-shell הבסיסית? המדריך הזה למתחילים יציג את היסודות של כתיבת סקריפטים ב-Linux עם Bash, כולל יצירה והרצה של סקריפט, עבודה עם מחרוזות ולולאות.
כתיבת מחרוזות משמשת לאוטומציה של משימות מנהליות נפוצות
ללא קשר למערכת ההפעלה, סקריפטי shell משמשים לאוטומציה של משימות ניהוליות חוזרות. לדוגמה, ב- Windows תוכל לשנות שמות קבצים באמצעות מפעל הקבצים. אבל אם יש לך צורך לשנות שמות קבצים רבים, זה יהיה משימה זמנית להשתמש ב-shell גרפי. PowerShell מאפשר לך לאוטומציה של המשימה ולחזור עליה באופן אמין.
במערכות ההפעלה שמבוססות על Linux, Bash וshell אחרים משמשים לאוטומציה של משימות כגון עבודה עם קבצים, שינוי תצורת המערכת, ועוד משימות שיכלו להיבצע באמצעות הקלדת פקודות יחידות.
מה שאתה צריך ללמוד בהתכתבות סקריפט בשפת Bash
כדי לכתוב ולהריץ סקריפט Bash, יש רק צורך בשלושה דברים:
- כל עורך טקסט פשוט, כמו Notepad, Text Editor, TextEdit, vi, emacs, או Visual Studio Code.
- A terminal emulator, an application that comes preinstalled with most operating systems and is often called Terminal, Console, or Command Prompt.
- באש בעצמו.
משהו שנקרא מחשב קירבן הוא המקום בו תקליד את הפקודות ותרצף אותן על ידי לחיצה על Enter או Return. בנוגע לבאש, אם יש לך אותו מוקדם יותר תלוי בפלטפורמה שלך:
- על macOS, באש מותקן מראש. בגרסאות החדשות יותר, השלט Z (zsh) הוא השלט המוביל, וזה בסדר. כל עוד באש מותקן, תוכל לרצוץ תוכניות Bash מתוך zsh גם כן.
- דיסטרבוטים Linux בדרך כלל מותקנים בבאש. (תוכל לבדוק אם המערכת שלך כוללת את הקובץ /bin/bash.) Android הוא מקרה מיוחד שאינו נשלח עם Bash. יש צעדים כדי להביא Bash לAndroid, אך המאמר הזה לא יעבור עליהם.
- ווינדוס לא מגיע כולל ב-Bash. PowerShell הוא הסורק שורת פקודה בברירת המחדל בווינדוס. תצטרך להתקין הפצת לינוקס תחת Windows Subsystem for Linux (WSL) כדי להפעיל Bash.
כדי למצוא את גרסת Bash שלך, הריץ את הפקודה bash –version. גרסאות ישנות גם מעניקות לך הרבה כוח, אך Bash 3 ו-4 מציעות גם רישומים קצרים נחמדים עבור פקודות בסיסיות מסוימות. אם פקודה דורשת אחת מהגרסאות באש שלו, ייציין למטה.
מהו של?
בעולם החישובים, של היא תוכנה המשמשת כממשק עבור המערכת הפועלת. של יכול להיות ממשק משתמש גרפי (GUI), דוגמת Shell של ווינדוס.
שפות כתיבת של
אולם, בדרך כלל האנשים משתמשים במונח כדי להתייחס באופן ספציפי לממשק שורת פקודה (CLI) – ממשק המורכב משורות טקסט שאיתן אתה מתקשר באמצעות המקלדת בלבד. הנה כמה דוגמאות לשפות סקריפט של מערכות הפעלה *nix:
- קלט ה-Bash (קיצור של "קורן Bאחרית Aולף ש")
- קלט ה-C shell
- קלט ה-Korn shell
כאן, נתמקד בקלט ה-Bash. זהו קלט Unix חינמי ופופולרי המותקן מראש ברוב הפצות Linux וב- macOS
מהו סקריפט של שורת פקודה?
לקלטים יש שפת תכנות משלהם. השפה נעשה בשימוש עבור שליחת פקודות לקלט, שהוא מבצע אותן. ניתן להקליד את הפקודות הללו ישירות אל תוך הקלט, או לשמור אותן בקובץ – קובץ סקריפט – ולאחר מכן להריץ את הקובץ הזה מתוך הקלט. התחביר לכתיבת פקודות זהה בשני המקרים
מאמר זה יכסה את היסודות של סקריפט של שורת פקודה על מנת ליצור קובץ זה
יסודות סקריפט של שורת פקודה
בואו להתחיל עם קצת יסודות בסקריפט של שורת הפקודה. כדי לכתוב סקריפט פשוט, נלמד כמה פקודות פשוטות לסקריפט של שורת הפקודה ב-Linux:
- צור קובץ טקסט ריק חדש בעורך טקסט.
- כתוב
#!/bin/bash
כשורה ראשונה. - הקלד את הפקודות שלך מתחת לכך.
- שמור את הקובץ, מועדף עם סיומת ".sh" או ללא סיומת.
השורה #!/bin/bash
נקראת "שבנג". זה אומר לשלך שצריך לבצע את הסקריפט ב-Bash וזאת צריכה להיות השורה הראשונה בסקריפט שלך. אם תחליפו לשל קודם, הסקריפט עדיין ירוץ ב-Bash.
כדי לנסות את התהליך בעצמך, צור קובץ בשם 'hello_world' בתיקיית הבית שלך:
#!/bin/bash echo "hello world"
זהו – יצרת סקריפט ב-Bash!

לפני שתוכל להריץ אותו, כנראה תצטרך לשנות הרשאות על הקובץ.
הגדרת הרשאות להרצת סקריפט בשלילה באמצעות chmod
כדי לשנות את ההרשאות על הקובץ 'hello_world', עליך להריץ את הפקודה הספציפית הזו במודד הטרמינל שלך. זה נותן למשתמש שבבעלות הקובץ את ההרשאה לבצע את הקובץ.:
chmod u+x 'hello_world'

אם אתה רק רוצה להריץ את הסקript שלך בshell, אתה יכול להיכנס לחלק הבא. עבור אלה שמתעניינים בchmod
הפקודה, chmod
הוא קצת קרוב ל"שינוי מodus" ומשמש כדי לשנות את "מodus" (או הפרמישונים) של קבצים במערכת Unix. במערכות של סוג Unix, אתה יכול להגדיר את הפרמישונים של קבצים עבור שלושה סוגים של משתמשים:
- המשתמש שבעל את הקבץ (מייצג על ידי
u
בchmod). - הקבוצה שבעלת את הקבץ (
g
). - אחרים (
o
).
עם הפקודה chmod
, אתה יכול גם להשתמש בa
כדי להתייחס לכל אלה.
לכל קבץ יש שלושה סוגים של פרמישונים (או "מodus"):
- קריאה (
r
) - כתיבה (
w
) - הוצאה לשימוש (
x
)
ואתה יכול גם להוסיף (ב+
) או להסיר (ב-
) פרמישונים.
המבחן הראשון בchmod הוא שילוב משלושת אלה — משתמש ראשון, פעולה שני, ומodus שלישי. הנה כמה דוגמאות לפקודות:
chmod gu+rw 'hello_world'
יהוסף את הפרמישונים הקריאה והכתיבה עבור הבעל והקבוצה הבעלת את הקבץ.chmod a-x 'hello_world'
יסיר את הפרמישונים האקסקוביים עchmod u+rwx 'hello_world' 'hello_world_2'
תעניק לבעלים את ההרשאה לקריאה, כתיבה, וביצוע בקבצי "hello_world" ו-"hello_world_2".
רק כיסית את היסודות הקריטיים ביותר של הפקודת chmod
כאן. קיים גם דרך מורכבת יותר, אך פחות ארוכה להגדרת מצבים אלו (ה"הסיווג המספרי"), כמו גם פקודה שונה שניתן להשתמש בה כדי לראות אילו היתרים קיימים אצל קבצים שלך (ls -l
). לא נכנס לעמוק אל אלו הנושאים כאן.
ביצוע סקריפט קוד
זמן לבצע את הסקריפט הראשון שלנו. בכלליות, כדי להריץ סקריפט, פשוט כתבו את נתיבו אל תוך מודד הטרמינל והקלידו על Enter.
./hello_world
ניתן להשתמש בנתיב היחסי או בנתיב המוחלט. כאשר משתמשים ב נתיב היחסי, תמיד שימו דגש על ./
בתחילת הפקודה שלכם: זה אומר לטרמינל לחפש בתיקיית הנוכחית (מיוצג על ידי '.'
), במקום בתיקיות שהוגדרו במשתנה הסביבה של PATH
.

שימוש בהערות להערת הסקריפט שלך
כל מה שאחרי #
בשורה אחת בסקריפט בASH מוחשב כ הערה. ניתן להיות מועיל לתקשר איזה פקודה מורכבת עושה או לתת סקירה על מה חלקים גדולים יותר בסקריפט שלך עושים.
לדוגמה:
#!/bin/bash # # This shell script prints "hello world". # echo "hello world" # This line prints "hello world".
הקדמה למשתנים
כאשר אתה כותב סקריפטים, יכול להיות שימושי להגדיר משתנים. ב-Bash, אתה עושה זאת על ידי כתיבת שם המשתנה והערך, מופרדים באמצעות סימן שווה: VARIABLENAME='VALUE'
.
אין לשים רווחים ליד סימן השווה — Bash יחשוב שאתה רוצה להפעיל תהליך במקום זאת.
השתמש בגרשיים יחידים לאחוז בערך ולמנוע מ-Bash לפרש אותו כמשהו אחר. ב-Bash, משתנים לא מכילים סוגים — הכל בסופו של דבר מחרוזת. זה עובר על תוכניות Bash לפרש את המחרוזת כסוג שונה, כמו מספר.
כדי להתייחס לערך של משתנה, השתמש בשם המשתנה שבו קודם מסימן הדולר: $VARIABLENAME
.
כדי לנסות זאת בפועל, אתה יכול לשנות את הסקריפט שלך לכך:
#!/bin/bash HELLO="hello variable world" echo $HELLO # should print "hello variable world"
קבלת ארגומנטים
המילים היחידות שאתה כותב כאשר אתה מקליד פקודה נקראות ארגומנטים. בדוגמה שלנו chmod u+x 'hello_world'
, chmod
, u+x
, ו־'hello_world'
הם שלושה ארגומנטים שונים. chmod
הוא שם הפקודה בעוד u+x
ו־hello_world
נקראים מפרמטרים — ארגומנטים שמספקים מידע נוסף לפקודה.
בסקריפט שלך, אתה יכול לגשת אל הארגומנטים הללו דרך משתנים. כדי למנוע כינון עם משתנים מקומיים, משתנים אלו מקבלים שמות בעזרת מספרים — $0
מתייחס לשם הפקודה, $1
הוא הארגומנט הבא שלאחריו, $2
הבא אחריו, וכן הלאה.
נסו את זה:
#!/bin/bash HELLO="hello $1 world" echo $HELLO
עכשיו, הריצו את הסקריפט הזה עם הפרמטרים האלו:
./hello_world bash script
הפלט צריך להיות שלום bash עולם
, עם הפרמטר הראשון בשימוש והשני מתעלם.
אם ברצונכם ש־script bash
יתקבל כפרמטר אחד, תצטרכו לשים אותו בציטוטים:
./hello_world 'bash script'

שימוש בהצהרת if כדי להריץ קוד באופן תנאי
אחת הדברים המרכזיים שמפתחי תוכנה רוצים לעשות בתוך סקריפט הוא להריץ קטע קוד רק אם תנאי מסוים מתקיים. Bash משתמש בהצהרת if
לכך:
NUM=$RANDOM if (( $NUM % 2 )) # if CONDITION then echo "$NUM is odd" fi # this is how you end an if statement
טיפ: החל מכאן, נניח שהדוגמאות הללו הן חלק מסקריפט גדול ומוֹחזים את #!/bin/bash
בתחילת הסקריפט. עם זאת, אל תשכחו לשים אותו כשורת ההתחלה בסקריפט שלכם!
ניתן גם להשתמש ב־else
בתוך ההצהרה if כדי לציין מה לעשות אם תנאי לא מתקיים, או בהצהרת elif
(קצר ל־"אם־אחרת־אם") כדי לציין תנאי נוסף אם התנאי הראשון לא מתקיים:
NUM=$RANDOM if [ $NUM -eq 12 ] then echo "$NUM is my favorite number" elif (( $NUM % 2 )) then echo "$NUM is odd" else echo "$NUM is even"fi
'fi' משמש כדי לסגור את ההצהרה if.
טיפ: אם אינך בטוח איך לכתוב את התנאי עצמו, חפש בהקשר של test
, סוגריים ריבועיים ([]
) וסוגריים כפולים ((())
).

חוזר על סדרת פקודות בעזרת לולאת for
עכשיו שכיסינו איך להריץ קוד באופן תנאי, בואו נביט איך מריצים קוד מספר מסוים של פעמים על פי תנאי.
הלולאת for
היא מושלמת למשימה כזו — במיוחד התחביר של "שלושה ביטויים". הרעיון מאחורי זה הוא להקצות משתנה מיוחד ללולאה ולשנות אותו בהדרגה עד שהתנאי מתקיים. הנה כיצד זה מורכב:
for (( ASSIGNMENT_EXPRESSION ; CONDITION_EXPRESSION ; UPDATE_EXPRESSION )) do COMMANDS done
לדוגמה, אם ברצונך שלולאה תרוץ 10 פעמים עם ערכים ל-i שהם מ-0 עד 9, ה־for
שלך עשוי להיראות כך:
for (( i=0; i<10; i++ )) do echo $i done
נברר את זה:
i=0
is the assignment expression here. It’s run only once before the loop is executed, which is why it’s useful for initializing a variable.i<10
is our condition expression. This expression is evaluated before each iteration of a loop. If it is equal to zero (which means the same as “true” in Bash), the next iteration is not run.i++
is our update expression. It’s run after each iteration of a loop.

עובר דרך איברים ברשימה
לצד התחביר עם שלושה ביטויים, ניתן להשתמש גם במילת המפתח in
כדי להגדיר לולאת for
. תחביר זה יחלוף דרך סדרת פריטים.
הדוגמה הבסיסית ביותר היא פשוט לרשום את סדרת הפריטים שברצונך לעבור בהתמודדות אחרי מילת המפתח in
, מופרדת ברווחים. לדוגמה:
for i in 0 1 2 3 4 5 6 7 8 9 # space-separated list items do echo $i done
בנוסף, ניתן גם לעבור דרך פריטים המוצאים בפלט של פקודה:
for i in $(seq 0 1 9)
הסימון $()
משמש להחלפת פקודה באופן כללי – הוא מפעיל פקודה והפלט שלה משמש כקלט לפקודת ההורה שסובבת אותו.
אם אתה עובר דרך מספרים, עדיף להשתמש בתחביר טווח מובנה של Bash, שהוא יעיל יותר מהפקודה seq
. עם זאת, תחביר זה זמין רק בגרסאות מעודכנות יותר של Bash:
לב i ב- {0..9}
, זמין ב- Bash 3.לב i ב- {0..9..1}
, זמין ב- Bash 4, שבו המספר האחרון מייצג את ההגדלה.
על אותו אשכול, ניתן לעבור גם דרך מחרוזות:
for s in 'item1' 'item2' 'item3'
שימוש ב- globbing כדי לקבל קבצים התואמים תבנית
אחד מהמקרים השכיחים יותר של שימוש בלולאות הנדונות בקטע הקודם הוא העברה דרך קבצים בודדים.
כדי לטפל בזה, עלינו לכסות את ה- "תפיסות ה-glob" הכוחלות. זהו מאפיין ב- Bash המאפשר לך לציין שמות קבצים באמצעות התאמת תבניות. קיימים תווים מיוחדים שנקראים wildcards שאתה משתמש בהם כדי להגדיר את התבניות האלה.
לפני שנעמיק בזה, בואו נסתכל על כמה דוגמאות ספציפיות:
echo *
: פקודה שמחזירה את שמות כל הקבצים בתיקיית העבודה הנוכחית שלך, למעט הקבצים המוסתרים.echo *.txt
: פקודה שמחזירה את שמות כל הקבצים הלא מוסתרים עם סיומת .txt בתיקיית העבודה הנוכחית שלך.echo ????
: פקודה שמחזירה את כל שמות הקבצים באורך של ארבעה תווים בתיקיית העבודה הנוכחית שלך.
הגלאים (wildcards) שהשתמשנו בהם היו * ו־? כאן. יש גם עוד גיליון גלאים שלא השתמשנו בו. הנה סקירה:
- הכוכבית (
*
) מייצגת כל מספר של תווים (כולל 0) בשם קובץ או תיקייה. - סימן השאלה (
?
) מייצג תו יחיד בשם קובץ או תיקייה. - הכוכבית המשוננת (
**
) מייצגת כל מספר של תווים בנתיב קובץ מלא. זו תכונה ב־Bash 4 ומעלה ויש להפעילה על ידי הרצתshopt -s globstar
. - סוגריים מרובעים (
[]
) משמשים לייצוג תו בתוך קבוצת סמלים בשם קובץ או תיקייה. לדוגמה[st]ake
תמצא קבצים בשמות sake או take, אבל לא stake.
שימו לב שכל הקבצים המוסתרים (שהם קבצים שמתחילים בנקודה .) מתעלמים בשימוש בהרחבת גלוב.
התייחסות לסימני חד-קרן אופשרת רמה עדינה יותר, כולל:
- טווחים המוגדרים על ידי הערך הראשון והאחרון — לדוג'
[1-8]
- הסרת תווים מסוימים על ידי שימוש ב־! כתו הראשון בתוך הסוגריים — לדוג'
[!3]
כדי לטפל באחד מהתווים המיוחדים כתו רגיל ללא משמעות, יש לשים קו נטוי לפניו — לדוג' \?
.

עוברים דרך קבצים באמצעות לולאת for
עכשיו שכיסינו את היסודות של הרחבת glob, בואו נצפה כיצד להשתמש בה כדי לעבור דרך קבצים.
נוכל פשוט להשתמש באופרטורים של glob בתוך הלולאה עצמה. הנה דוגמה פשוטה של לולאה שמדפיסה את שם כל קובץ בתיקייה הנוכחית:
for f in * do echo $f done
כדי להדפיס את שמות כל קובץ בתיקייה הנוכחית וגם בתיקיות משנה שלה, יש לוודא שאתם מריצים Bash 4.0 או מעלה על ידי הרצת bash --version
, ואז ניתן להריץ את הפקודה הבאה:
shopt -s globstar # enables using ** for f in ** do echo $f done
עצה: אם אתם מריצים גרסה ישנה יותר של Bash, לא תוכלו להשתמש בגלובינג עם לולאת for לצורך זה. הפעולה הטובה ביותר תהיה להשתמש בפקודת find
, אך אנחנו לא נדון בכך במאמר זה.
אלה הם, כמובן, רק חלק מהלולאות הפשוטות ביותר שאפשר להפעיל, אבל יש הרבה דברים נוספים שניתן לעשות. לדוגמה, כדי לשנות את כל ה-JPGs בתיקייה ולתת להם שם רצוף ישיר, תוכל להריץ:
i=1 for f in *.jpg do mv -i -- "$f" "image_$i.jpg" let i=i+1 done

הרצת קוד כל עוד תנאי נכון
הלולאת for אינה הסוג היחיד של לולאה שאפשר להשתמש בה ב־Bash — יש גם while
: סוג זה של לולאה רץ כל עוד תנאי ספציפי נכון.
התחביר דומה לתחביר הלולאה של סוג ה־for:
while CONDITION do COMMANDS done
לדוגמה פרקטית, כך נראה איך אפשר לקרוא קובץ שורה אחר שורה (ללא רווחים מובילים או סופיים) עד שנגיע לסוף הקובץ:
while read -r line do echo "$line" done < FILENAME # Replace FILENAME with the path to a text file you'd like to read

אפשר גם להחליף לולאת for בלולאת while, לדוגמה כדי לעבור מ־0 עד 9:
i=0 while [ $i -lt 10 ] do echo $i let i=i+1 done
והייתה אפשרות להפעיל לולאה לנצח. הנה דוגמא לפקודה:
while true do echo "running forever" done
טיפ: כדי לסיים את הסקריפט, תלחץ על Ctrl+C.
למרבית הזמן לולאת האינסוף הזו עשויה להראות חסרת ערך במבט ראשון, אך בעצם היא עשויה להיות מאוד שימושית, במיוחד כאשר משולבת עם ההוראה של break
.
יציאה מלולאה
ההוראה break
משמשת לצאת מלולאה.
זה מאפשר לך להריץ לולאת אינסוף ולצאת ממנה כאשר נתקלים בכל תנאי יציאה.
לדוגמה פשוטה, נוכל לשכפל את הלולאה שרצה מ־0 עד 9 עם לולאת אינסוף כזו:
i=0while true do if [ $i -eq 10 ] then break fi echo $i let i=i+1 done
אם יש כמה מעגלים while מתעוררים, אתה יכול להוסיף מספר אחרי break כדי להצהיר מה רמה של המעגל להפסיק ממנו: break 1
זה אותו כמו break
ויסיים את המעגל הקרוב ביותר, break 2
יסיים את המעגל העליון ברמה אחת, וכך הלאה.
בואו נביט בדוגמה קטנה, הפעם עם for מעגלים, שמתפקדים על ידי התבצעות כל שילוב של מילים בן 4 תווים עד שנתקלים במילה "bash":
for l4 in {a..z} do for l3 in {a..z} do for l2 in {a..z} do for l1 in {a..z} do echo "$l4$l3$l2$l1" if [ $l4 = "b" -a $l3 = "a" -a $l2 = "s" -a $l1 = "h" ] then break 4 fi done done done done
A related keyword that’s also worth a mention is continue
, which skips to the next iteration of the loop. Just like break
, it also takes an optional numeric argument that corresponds to the loop level.
הנה דוגמה מטורפת בה אנחנו מעלים על כל המילים בתווים קצרים ברצף של 4 תווים שלא מכילים את התווים "Es":
for l4 in {a..z} do if [ $l4 = "e" ] then continue fi for l3 in {a..z} do if [ $l3 = "e" ] then continue fi for l2 in {a..z} do if [ $l2 = "e" ] then continue fi for l1 in {a..z} do if [ $l1 = "e" ] then continue fi echo "$l4$l3$l2$l1" if [ $l4 = "b" -a $l3 = "a" -a $l2 = "s" -a $l1 = "h" ] then break 4 fi done done done done
אנחנו יכולים גם לבצע את כל האותם continue
הצעיות ברמה העמוקה ביותר של המעגל:
for l4 in {a..z} do for l3 in {a..z} do for l2 in {a..z} do for l1 in {a..z} do if [ $l4 = "e" ] then continue 4 fi if [ $l3 = "e" ] then continue 3 fi if [ $l2 = "e" ] then continue 2 fi if [ $l1 = "e" ] then continue fi echo "$l4$l3$l2$l1" if [ $l4 = "b" -a $l3 = "a" -a $l2 = "s" -a $l1 = "h" ] then break 4 fi done done done done

איך לקבל קבעים משותף בסhell סקript
לפעמים, אתה רוצה שהמשתמש יתעסק בסקript שלך ישירות ולא רק באגרות סקript ראשוניות. זה המקום בו מגיע הפקטיבית read
.
על מנת לקבל קבעים מהמשתמש ולשמור עליהם במשתנה שנקרא NAME
, אתה יכול להשתמש בפקטיבית זו:
read NAME
זו הצורה הפשוטה ביותר של הפקטיבית, היכולה לכל זאת מורכבת מרקמה הפקטיבית והמשתנה בו אתה רוצה לשמור.
אך רב
הנה איך אתה יכול לבקש שם, ולהקצות אותו למשתנה בשם NAME
:
read -p "Your name: " NAME echo "Your name is $NAME." # this line is here just to show that the name has been saved to the NAME variable

הדפסת תווים מיוחדים במחרוזת
יש מספר תווים ב-Bash שעליך להיזהר בשימושם. לדוגמה, רווחים בתוך שמות קבצים, מרכאות בתוך מחרוזות, או סלאשים אחוריים כמעט בכל מקום.
כדי להגיד ל-Bash להתעלם מהמשמעות המיוחדת שלהם במקומות מסוימים, אתה יכול או ל"הוסיף סלאש אחורי" להם או להקיף אותם במרכאות מילוליות.
“הוספת סלאש אחורי” לתו מיוחד אומר להגיד ל-Bash להתייחס אליו כאל תו בלתי מיוחד. כדי לעשות זאת, כתוב סלאש אחורי לפני התו.
בואו נניח שיש לנו קובץ בשם img \ 01 *DRAFT*, לדוגמה. ב-Bash, נוכל להתייחס אליו באופן הבא:
img\ \\\ 01\ \*DRAFT\*
הנה רשימה לא מוחלטת של תווים מיוחדים ב-Bash:
- רווחים: רווח, טאב, שורה ריקה
- מרכאות: ”, “”
- סוגריים, סוגריים מסולסלים, וסוגריים מרובעים: ( ), { }, [ ]
- צינורות והפניות: |, <, >
- תווים כלליים: *, ?
- שונות: !, #, ;, =, &, ~, `
- תו הבריחה עצמו: \
אם אתה חדש ב-Bash, עשוי להיות קשה לזכור אילו תווים יש להם משמעות מיוחדת. כל כך, במצבים רבים, זה עשוי להיות קל יותר להשתמש ב-מרכאת מילולית: פשוט הקיף את הטקסט שמכיל תווים מיוחדים במרכאות מילוליות, וכל התווים המיוחדים בתוך המרכאות האלו יתעלמו.
כך זה יראה במקרה שלנו:
'img \ 01 *DRAFT*'
מה אם תרצו להשתמש במקום ספציפי אבל להימנע מאחרים? תוכלו להימנע מכל תווים אחד בעזרת צירף חזרה, אך תוכלו גם לחסוך לעצמכם את הבעיה ולהקיף את הכל מבחירים פשוטים חזרה חיצונית חוץ מהתווים הספציפיים.
לדוגמה, אם יש לך מספר קבצים בשמות img \ 01 *v1 DRAFT*, img \ 01 *v2 DRAFT*, img \ 01 *ROUGH DRAFT*, וכולים, ואתה רוצה להשתמש בהתפשטות גלובלית כדי להתאים את כל אותם שמות קבצים. כך שתוכלו לכתוב:
'img \ 01 *'*' DRAFT*'

אם מה שאתה צריך לכתוב מכיל צירוף אחד של צירוף מקום — לדוגמה img \ 01 *'FINAL'* — תוכלו להשתמש באסטרטגיה דומה, ביציע שטחים מילים ולהידחף:
'img \ 01 '\''FINAL'\'
איך להדביק מקטעים בבאש
נניח שיש לך שתיים או יותר מקטעים משתנים — לדוגמה שם ראשון ושם סוף, כך ש:
FIRST_NAME="Johnny"LAST_NAME="Appleseed"
כדי לשלב את המקטעים האלה למקטע אחד, אולי עם מפתח מיוחד, פשוט תיצרו מקטע חדש שמכיל את שני המקטעים האלה:
NAME="$LAST_NAME"', '"$FIRST_NAME"
אתם יכולים גם להשתמש בצירוף מקטעים עם מפתחים מקטעים באינלין, בעזרת סימנים קוד להפרדת שמות המפתחים מהטקסט הסובב:
NAME="${LAST_NAME}, ${FIRST_NAME}"
באש גם מאפשר לך להשתמש במפתח +=
כדי להוסיף טקסט למקטע, כך ש:
NAME='Appleseed'NAME+=', 'NAME+='Johnny'

Bash מאפשר גם להשתמש בפלט של פקודה בתוך מחרוזת, שנקראת גם substitution פקודה. פשוט סובב את הפקודה שלך בתוך $()
. לדוגמה, כדי להדפיס חותמת זמן נוכחית, אפשר להריץ:
echo "Current timestamp: $(date)"

כדי לזכור גם שימוש בתחביר זה מדוגמת לולאת for קודמת, כאשר עברנו דרך רצפי מספרים מ-0 עד 9:
for i in $(seq 0 1 9) do echo $i done
הפקודה המוחלפת מורצה בתוך subshell. זה אומר, לדוגמה, שכל משתנים שנוצרים במהלך הפקודה לא ישפיעו על הסביבה שבה אתה מריץ את סקריפט השלך.
הגדרת והחזרת קודי יציאה בתסריט של shell
עבור תסריט מורכב יותר, נהוג לו להחזיר יציאה code — מספר בין 0 ל-255 שמעביר לאנשים האם התסריט רץ בהצלחה או נתקל בשגיאה.
לגבי אילו מספרים להשתמש, המדריך הרשמי של Bash מפרט אלו:
- 0: התוכנית הורצה בהצלחה.
- 2: תוכנית נוצרה באופן שגוי (למשל, עקב ארגומנטים לא תקינים או חסרים).
- 1 ו-3-124: שגיאות מוגדרות על ידי המשתמש.
- 126: הפקודה אינה ניתנת לביצוע.
- 127: הפקודה לא נמצאה.
- 125 ו-128-255: מצבי שגיאה שה-shell משתמש בהם. אם תהליך נהרג על ידי אות שידור
N
, מצב היציאה הוא 128 + N.
כפי שאתה יכול לראות, כל המספרים מלבד 0 מצביעים על סוג שגיאה מסוים. קוד היציאה 1
משמש בדרך כלל לשגיאות כלליות. ברוב המקרים, לא תצטרך להשתמש בשום קוד יציאה מעל 2
.
כדי להחזיר קוד יציאה מהתסריט שלך, פשוט השתמש בפקודת exit
. לדוגמה, כדי לצאת עם קוד 2, תרשום exit 2
.
אם אינך משתמש בפקודת exit
בתסריט שלך או משתמש בפקודה מבלי לציין קוד, מצב היציאה של הפקודה האחרונה שהוצגה בתסריט שלך יוחזר.
כדי לקבל את קוד היציאה של הפקודה שנרצתה בקובץ השל, השתמש במשתנה $?: echo $?
.
כיצד לקרוא לפונקציה
כאשר אתה כותב תסריט ארוך או תסריט עם קטעי קוד שנשנים, ייתכן שתרצה להפריד חלק מהקוד ל-פונקציות. ישנם שני פורמטים שניתן להשתמש בהם כדי להגדיר פונקציות: בשני המקרים, כל קוד הפונקציה מוחזק בתוך סוגריים מסולסלים ורק ההכרזה על הפונקציה שונה.
הפורמט הקומפקטי יותר משתמש בסוגריים אשר מתחילים אחרי השם של הפונקציה כדי להכריז על פונקציה:
function_name () { echo "This is where your function code goes" }
הפורמט השני משתמש במילת המפתח function
מול שם הפונקציה:
function function_name { echo "This is where your function code goes" }
פונקציות חייבות להודיע לפני שהן נקראות בסקריפט שלך. אתה קורא לפונקציה בדיוק כמו שאתה מבצע פקודה רגילה, בשימוש בשם הפונקציה כמו פקודה:
function_name
העברת נתונים לפונקציה באמצעות משתנים
ב־Bash, פונקציות לא יכולות לקבל ארגומנטים. כדי לשלוח מידע לפונקציה, עליך להשתמש במשתנים גלובליים בסקריפט שלך.
לדוגמה:
is_your_name_defined () { if [ -z "$YOUR_NAME" ] then echo "It doesn't seem like I have your name." else echo "Is this your name: ${YOUR_NAME}?" fi } read -p "Your name: " YOUR_NAME is_your_name_defined
שונה ממה שאתה רגיל בו בשפות אחרות, המשתנים שאתה מגדיר בתוך הפונקציה שלך הם גלובליים, ונראים לקוד מחוץ לסקריפט שלך. כדי להגדיר משתנה בתוקף רק לפונקציה שלך בלבד (כלומר ללא הגישה לכל קוד מחוץ לה), השתמש במילת המפתח local: לדוגמה local i=0
אם אתה רוצה להחזיר ערכים מתוך פונקציה, עליך גם להשתמש במשתנים גלובליים. ב־Bash, פונקציות יכולות להחזיר רק קודי יציאה, באמצעות מילת מפתח return. בוא נסתכל על דוגמה:
is_your_name_defined () { if [ -z "$YOUR_NAME" ] then MESSAGE="It doesn't seem like I have your name." else MESSAGE="Is this your name: ${YOUR_NAME}?" fi } read -p "Your name: " YOUR_NAME is_your_name_defined echo $MESSAGE

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