Bash Tips
973 subscribers
14 photos
4 files
45 links
רוצים להשתמש בלינוקס אבל לא ממש מכירים את הכלים שהיא מספקת לעבודה?

בערוץ הבא תמצאו אוסף טיפים שימושיים ב-Bash והכרות עם כלים שונים שעשויים לחסוך מאמץ ועבודה בכתיבת סקריפטים ומימוש אוטומציות.
Download Telegram
לקבץ פקודות ותת מעטפת
רמת קושי: #advanced

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

לדוגמה
הקוד הבא לא ישרשר את שני המילים לקובץ test אלא ידפיס אחד למסך ואחד לקובץ המדובר

$ echo first; echo second > /tmp/test
first
$ cat /tmp/test
second

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

$ (echo first echo second) > /tmp/test
$ cat /tmp/test
first
second

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

השמה בתת מעטפת

$ (a=1; b=2; c=3; echo $a-$b-$c)
1-2-3
$ echo $a-$b-$c
--

השמה במעטפת הראשית

$ {a=1; b=2; c=3; echo $a-$b-$c}
1-2-3
$ echo $a-$b-$c
1-2-3

#subshell
#grouping_commands

נ.ב. ימים אחרונים לאתגר ולאחר מכן אפרסם פתרון אפשרי.

@bash_tips
לוג לפונקציות, צנזור מידע ו subshell
רמת קושי: #advanced

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

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

get_page(){
logger "run function: ${FUNCNAME[0]} with parameters: ${*}"
echo "${page}"
}

וכך נראית הסקריפט כשאנו מריצים אותו

$ bash test.sh https://google.com
[*] run function: get_page with parameters: https://google.com

ולמי שמאוד סקרן כך נראית פונקציית logger

logger() {
status=$?
if [[ $status -eq 0 ]]; then
echo -e "\e[92m[*] ${@}"
else
echo -e "\e[91m[!] ${@}"
fi
}

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

$ test.sh https://admin.site myuser mypass
[*] run function: get_page with parameters: https://admin.site myuser mypass

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

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

get_page(){
input=$(sed "s|${REPLACE}|${REPLACE_TO}|g" <<<"${@}")
logger "run function: ${FUNCNAME[0]} with parameters: ${input}"
echo "${page}"
}

וכך אנו קוראים לפונקציה בסקריפט

REPLACE="myp.*"
REPLACE_TO="***"
get_page "${@}"

נבדוק רגע נראה שהכל עובד תקין

$ test.sh https://admin.site myuser mypass
[*] run function: get_page with parameters: https://admin.site myuser ***

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

REPLACE="myp.*"
REPLACE_TO="***"
get_page "${@}"
unset REPLACE
unset REPLACE_TO

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

(
REPLACE="myp.*"
REPLACE_TO="***"
page=$(get_page "${@}")
)

#scripting
#subshell
#function

@bash_tips