פקודת השמה ו
מה שמוביל אותנו לשאלה לשם מה צריך את הפקודה
העניין עם פקודת
מצד שני אם נשתמש ב
#export
#variable
#env_variable
#session
#sub_process
@bash_tips
export
לא מעט סקריפטים שנמצא נראה שמכריזים על משתנים במספר דרכים, אחת בצורה מפורשת עם export והשניה פשוט על ידי פקודת השמה של ערך למשתנהmyvar="some text here"
export my_another_var="another text here"
בשני המקרים המשתנה שלנו יהיה קיים אך ורק לסשן הנוכחי ולאחר מכן יתנדף ולא יהיה קיים יותר.מה שמוביל אותנו לשאלה לשם מה צריך את הפקודה
export
אם שני הפעולות עושות את אותה עבודה?העניין עם פקודת
export
הוא כזה, כשיוצרים משתנה רגיל הוא אכן נוצר לסשן הקיים אבל הוא רלוונטי אך ורק לקוד של הפרוסס הנוכחי שרץ/tmp/tests $ myvar="some text here"
/tmp/tests $ bash echo_myvar.sh
/tmp/tests $
בשלב הראשון אני מכריז על משתנה בסשן בשלב השני אני מריץ סקריפט, הסקריפט רץ תחת הסשן שלי אבל כ sub process.מצד שני אם נשתמש ב
export
/tmp/tests $ export myvar="another text here"
/tmp/tests $ bash echo_myvar.sh
another text here
/tmp/tests $
שימוש ב export
יורש את כל סביבת הסשן הנוכחי ומעביר אותו אל תת התהליך. כמובן שלאחר שהמשתנה הוכרז עם export
כל פקודת השמה של ערך למשתנה בתהליך הראשי ישפיע על התוכן בתתי התהליכים.#export
#variable
#env_variable
#session
#sub_process
@bash_tips
סימניות בטרמינל
כולנו מכירים את הקונספט של רשימת מועדפים, רשימה של נתיבי תיקיות שמורות ברשימה שדי בהקלקה ואנו שם.
רעיון דומה ניתן ליישם בטרמינל, לספק גישה מהירה לנתיבים שאנו מרבים להשתמש בהם.
באש מחזיקה משתנה מערכת בשם
2. תיקיית
ובכל זאת תמיד יש כוכביות כדאי שכדאי להכיר.
1. במידה וקיימות שתי תיקיות בעלות אותו השם בשני מיקומים שונים, העדיפות תיקבע על פי סדר התיקיות שהכנסנו למשתנה CDPATH ככל שהתיקייה קרובה לתחילת הרשימה כך העדיפות שלה גבוהה יותר, אם נקביל את זה לדוגמה דלעיל, תיקיית הבית תקבל את העדיפות הגבוהה ביותר.
2. במידה ונמצאים בתוך תיקייה שקיימת בה תיקייה בעלת שם דומה לתיקייה שקיימת לנו "במועדפים" פקודת
בכדי להתגבר על בעיה זו כשניגשים לתיקיות בעלות אותו השם במיקום שונה ניתן פשוט להעביר את זה בצורה מפורשת לבאש על ידי
#favorite
#env_variable
CDPATH
רמת קושי: #beginnersכולנו מכירים את הקונספט של רשימת מועדפים, רשימה של נתיבי תיקיות שמורות ברשימה שדי בהקלקה ואנו שם.
רעיון דומה ניתן ליישם בטרמינל, לספק גישה מהירה לנתיבים שאנו מרבים להשתמש בהם.
באש מחזיקה משתנה מערכת בשם
CDPATH
בו אנו יכולים להכניס רשימה של מיקומים במערכת וכל פעם שנקליד שם של תיקייה שנמצאת תחת אותו המיקום, נתיב העבודה שלנו ישתנה לאותה התיקייה.user@home /etc $ cd Videos
/home/user/Videos
user@home ~/Videos $ cd gimp
/tmp/gimp
user@home /tmp/gimp $
אז איך עושים את זה בעצם, אנו מעבירים רשימה של מיקומים למשתנה CDPATH
והמערכת תתעדף את התיקיות שבאותם המיקומים. כמו שאנו מכירים באש אוהבת נקודותיים (:
) כחוצץ בין ערכים והמקרה כאן אינו שונה.export CDPATH='~:/var/log:/tmp:'
הגדרנו 3 מיקומים במערכת על ידי חוצץ של :
1. תיקיית הבית (~
)2. תיקיית
/var/log
3. תיקיית /tmp
כעת ברגע שנרצה להיכנס לאחת מהתיקיות שנמצאות במיקומים שברשימה נוכל פשוט להיכנס אליה מבלי להקליד את הנתיב המלאuser@home /tmp/gimp$ cd Videos
/home/user/Videos
user@home ~/Videos$ cd hp
/var/log/hp
user@home /var/log/hp$ cd Projects
/home/user/Projects
ובשביל שזה יהיה כיף אפילו יותר אנו מקבלים גם השלמה אוטומטית לתיקיות הקיימות באותם המיקומים על ידי לחיצת טאב כפולהuser@home /tmp/gimp$ cd P <TAB> <TAB
Pictures/ Projects/
מ ו ש ל ם ! ובכל זאת תמיד יש כוכביות כדאי שכדאי להכיר.
1. במידה וקיימות שתי תיקיות בעלות אותו השם בשני מיקומים שונים, העדיפות תיקבע על פי סדר התיקיות שהכנסנו למשתנה CDPATH ככל שהתיקייה קרובה לתחילת הרשימה כך העדיפות שלה גבוהה יותר, אם נקביל את זה לדוגמה דלעיל, תיקיית הבית תקבל את העדיפות הגבוהה ביותר.
2. במידה ונמצאים בתוך תיקייה שקיימת בה תיקייה בעלת שם דומה לתיקייה שקיימת לנו "במועדפים" פקודת
cd
תכניס אותנו לתיקייה במועדפים במקום לתיקייה שמול העיניים, וכדי להוריד את מכבסת המילים לפרקטיקה להלן דוגמה $ echo $CDPATH
~:/var/log:
user@home /tmp$ tree -d -L 1
/tmp
├── Downloads
├── gimp
...
user@home /tmp$ cd Downloads/
/home/user/Downloads
user@home ~/Downloads$
כפי שניתן לראות באש העבירה את המיקום שלנו לתיקיית Downloads
שבתיקיית הבית במקום לזו שקיימת בתיקייה בה אנו נמצאים. בכדי להתגבר על בעיה זו כשניגשים לתיקיות בעלות אותו השם במיקום שונה ניתן פשוט להעביר את זה בצורה מפורשת לבאש על ידי
.
לפני שם התיקייה.user@home /tmp$ cd .Downloads/
Downloads/
user@home /tmp/Downloads$
#cdpath#favorite
#env_variable
@bash_tipsלפרמט את היסטוריה
רמת קושי: #beginners
כלי מוכר בלינוקס מאפשר לראות את ההיסטוריה של הפקודות שהורצו על מכונה או משתמש מסויים על ידי הרצה של פקודת
למה לפרמט?
הבעיה עם הפלט של פקודת history הוא שאין לנו מושג איזו פקודה הורצה מתי אלא רק רשימה ממוספרת, ולא מעט פעמים זהו מידע מעניין שעשוי לתת לנו יותר מרמז למה דברים מוזרים מתרחשים במכונה.
לפרמט
בכדי להציג שעה ותאריך לכל פקודה בהיסטוריה צריך להגדיר את המשתנה הגלובלי
הערות
* לכל הדואגים עדין אפשר להריץ !258.
* כמו שאנו מכירים בכדי לגרום להתנהגות הזאת להישאר קבועה, פשוט להכניס את הexport לbashrc ולעשות source.
#history
#env_variable
@bash_tips
רמת קושי: #beginners
כלי מוכר בלינוקס מאפשר לראות את ההיסטוריה של הפקודות שהורצו על מכונה או משתמש מסויים על ידי הרצה של פקודת
history
למה לפרמט?
הבעיה עם הפלט של פקודת history הוא שאין לנו מושג איזו פקודה הורצה מתי אלא רק רשימה ממוספרת, ולא מעט פעמים זהו מידע מעניין שעשוי לתת לנו יותר מרמז למה דברים מוזרים מתרחשים במכונה.
לפרמט
בכדי להציג שעה ותאריך לכל פקודה בהיסטוריה צריך להגדיר את המשתנה הגלובלי
HISTTIMEFORMAT
ונקבל רטרואקטיבית את הזמנים בהם הורצו הפקודות$ export HISTTIMEFORMAT="%d/%m/%y %T "
$ history
256 11/06/21 11:05:32 init 0
257 11/06/21 11:05:32 su user -
258 11/06/21 11:05:32 ls
259 11/06/21 11:05:32 python
260 11/06/21 11:05:32 rm users
...
הערות
* לכל הדואגים עדין אפשר להריץ !258.
* כמו שאנו מכירים בכדי לגרום להתנהגות הזאת להישאר קבועה, פשוט להכניס את הexport לbashrc ולעשות source.
#history
#env_variable
@bash_tips
Forwarded from shahar
למצוא את הדרך
רמת קושי: #beginners
כאשר אנחנו מריצים פקודה כגון
$
כיצד המערכת יודעת מה זה curl, ואיפה הבינארי של curl נמצא?
משתנה הסביבה PATH הוא זה שנותן לנו להריץ פקודות ללא צורך בציון הנתיב המלא לבינארי שאנו מנסים להריץ, הוא הסיבה שאנחנו לא צריכים לכתוב
הדרך שבה PATH עובד הוא שאם מוגדר לנו
ואנחנו מנסים להריץ משהו שנקרא curl, אז המערכת תחפש את הבינארי curl קודם בfoo ואחר"כ בbar, במידה והיא מצאה בfoo את הבינארי, המערכת תריץ את curl שבתוך foo, ואפילו לא תחפש את curl בתוך bar.
במידה ולא נמצא שום בינארי בתוך התקיות המצויינות בPATH המערכת תזרוק שגיאה שתגיד:
אפשרי להוסיף תקיות משלנו ע"י לשים שורה כזאת בתוך .bashrc
ככה אנחנו יכולים להוסיף לPATH תקיות מבלי לפגום בשימוש הסדיר של המערכת
#env_variable
#path
@bash_tips
רמת קושי: #beginners
כאשר אנחנו מריצים פקודה כגון
$
curl example.com
כיצד המערכת יודעת מה זה curl, ואיפה הבינארי של curl נמצא?
משתנה הסביבה PATH הוא זה שנותן לנו להריץ פקודות ללא צורך בציון הנתיב המלא לבינארי שאנו מנסים להריץ, הוא הסיבה שאנחנו לא צריכים לכתוב
/usr/bin/curl example.com
הדרך שבה PATH עובד הוא שאם מוגדר לנו
PATH="/foo:/bar"
ואנחנו מנסים להריץ משהו שנקרא curl, אז המערכת תחפש את הבינארי curl קודם בfoo ואחר"כ בbar, במידה והיא מצאה בfoo את הבינארי, המערכת תריץ את curl שבתוך foo, ואפילו לא תחפש את curl בתוך bar.
במידה ולא נמצא שום בינארי בתוך התקיות המצויינות בPATH המערכת תזרוק שגיאה שתגיד:
curl: command not found
אפשרי להוסיף תקיות משלנו ע"י לשים שורה כזאת בתוך .bashrc
export PATH="/path/to/my/scripts/dir:$PATH"
ככה אנחנו יכולים להוסיף לPATH תקיות מבלי לפגום בשימוש הסדיר של המערכת
#env_variable
#path
@bash_tips
לטעון סביבה
רמת קושי: #advanced
קובץ שמוכר בעולם ה ops הוא .env מדובר על קובץ שבגדול מכיל רשימה של משתני סביבה בהם הסביבה מאותחלת, מספר כלים כדוגמת docker-compose מכירים בקובץ ויודעים לטעון אותו לבד, מה קורה כשאנו רוצים לטעון קובץ .env ישירות לטרמינל?
דוגמה לקובץ .env
מחשבה ראשונה זה לעשות
נוכל לראות זאת בדוגמה שלהלן
להלן 2 דרכים מעניינות לפתרון
פתרון אפשרי, export
מה שקורה כאן הוא שפקודת
פתרון אפשרי נוסף allexport
בגדול מדובר על הפעלה של flag allexport, האופציה הזאת מעבירה לexport את רצף המשתנים ובעצם מאפשרת לפקודת
בכדי לראות שהמשתנים שלנו אכן נטענו לסביבה ניתן לבדוק זאת על ידי פקודת
#env
#export
#source
#variable
#env_variable
#session
@bash_tips
רמת קושי: #advanced
קובץ שמוכר בעולם ה ops הוא .env מדובר על קובץ שבגדול מכיל רשימה של משתני סביבה בהם הסביבה מאותחלת, מספר כלים כדוגמת docker-compose מכירים בקובץ ויודעים לטעון אותו לבד, מה קורה כשאנו רוצים לטעון קובץ .env ישירות לטרמינל?
דוגמה לקובץ .env
$ cat .env
APP_NAME=mytest
DEPLOYMENT_MODE=true
BUNDLE=test
...
מחשבה ראשונה זה לעשות
source
לקובץ ולטעון אותו, העניין הוא שהכרזת משתנים בלי הפקודה export
תטען את המשתנים לסשן של הטרמינל, כל סקריפט שנריץ מאותו הסשן לא יקבל את המשתנים שבקובץ כי הוא רץ בסשן משל עצמו (דברנו על זה מעט בעבר).נוכל לראות זאת בדוגמה שלהלן
$ source .env
$ cat test.sh
#!/bin/bash
declare -p APP_NAME DEPLOYMENT_MODE BUNDLE
$ bash test.sh
test.sh: line 2: declare: APP_NAME: not found
test.sh: line 2: declare: DEPLOYMENT_MODE: not found
test.sh: line 2: declare: BUNDLE: not found
להלן 2 דרכים מעניינות לפתרון
פתרון אפשרי, export
export $(grep -v '^#' .env)
מה שקורה כאן הוא שפקודת
export
יודעת להגדיר מספר משתנים בו זמנית, grep
מחריג כל שורה שהיא הערה וכך טוען רק את המשתנים, אפשר כמובן לשפר את החלק האחרון אבל הרעיון במקומו.פתרון אפשרי נוסף allexport
set -a
source .env
set +a
בגדול מדובר על הפעלה של flag allexport, האופציה הזאת מעבירה לexport את רצף המשתנים ובעצם מאפשרת לפקודת
source
לטעון את כל המידע שבקובץ, אנו מכבים את האופציה לאחר שטענו את הסביבה.בכדי לראות שהמשתנים שלנו אכן נטענו לסביבה ניתן לבדוק זאת על ידי פקודת
env
שמציגה בעצם את כל המשתנים של הסביבה בה אנו עובדים.#env
#export
#source
#variable
#env_variable
#session
@bash_tips
לשרשר ולספור
הזכרנו בעבר ששימוש ב pipe מתסיר את הקוד יציאה של הפקודה שרצה לפני הpipe
לדוגמה הפקודה הבאה תחזיר קוד יציאה 0 למרות שהפקודה הראשונה נכשלה
#pipe
#env_variable
#exit_code
@bash_tips
PIPESTATUS
רמת קושי: #beginners הזכרנו בעבר ששימוש ב pipe מתסיר את הקוד יציאה של הפקודה שרצה לפני הpipe
לדוגמה הפקודה הבאה תחזיר קוד יציאה 0 למרות שהפקודה הראשונה נכשלה
$ ls /not/exist/path | echo 123בכדי לקבל את הקוד יציאה של כל פקודה שהורצה ב pipe ניתן להשתמש במשתנה הסביבה PIPESTATUS, מדובר על משתנה סביבה מסוג מערך שמכיל קוד יציאה של כל פקודה שהורצה ב pipe
123
ls: cannot access '/not/exist/path': No such file or directory
$ echo $?
0
$ ls /not/exist/path | echo 123 | grep -o 2ניתן לראות אם כן שבעוד ששני הפקודות האחרונות יצאו בקוד 0, הפקודה הראשונה שנכשלה יצאה בקוד שגיאה
ls: cannot access '/not/exist/path': No such file or directory
2
$ declare -p PIPESTATUS
declare -a PIPESTATUS=([0]="2" [1]="0" [2]="0")
#pipe
#env_variable
#exit_code
@bash_tips