לקבץ פקודות ותת מעטפת
רמת קושי: #advanced
באש מאפשרת לנו לאגוד מספר פעולות יחד ולשרשר את הפלט הסופי רק בגמר הריצה של כל הפקודות ל stdout, בכדי לעשות כך ניתן להריץ את הפקודות בתוך סוגרים / מסולסלות ואת הפלט לשרשר החוצה.
לדוגמה
הקוד הבא לא ישרשר את שני המילים לקובץ test אלא ידפיס אחד למסך ואחד לקובץ המדובר
זה לא משנה אם נשתמש בסוגריים מסולסלות או בסוגריים רגילות, בשני המקרים הפקודות ירוצו בגרופ. העניין הוא ששימוש בסוגריים רגילות הפקודות ירוצו ב
השמה בתת מעטפת
#grouping_commands
@bash_tips
רמת קושי: #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 או בעת הרצת פקודה בתוך סוגריים, הכירות עם התכונה הזאת של באש עשויה לא רק למנוע באגים לא צפויים אלא אפילו למצוא פתרונות יצירתיים לבעיות שעולות.
ניקח לדוגמה סיטואציה בה יש לנו פונקציית לוגר שמתעדת כל פונקציה שנקראת ועם אלו פרמטרים היא רצה, הפונקציה נראית כך
מה שיקרה כרגע הוא שהמידע הרגיש שלנו יכתב ללוג וזה כבר פחות סבבה.
אנחנו רוצים בעצם יכולת לצנזר מידע רגיש שעובר ללוגר, העניין הוא שלא תמיד נדע איזה מידע אנו רוצים לצנזר ואם בכלל צריך לצנזר, לכן אנו צריכים אופציה להגדיר מהו מידע רגיש מחוץ ללוגר ושנוכל להשתמש באופציה הזאת רק מתי שנחוץ לנו.
אפשרות למימוש
פשוט להריץ פקודת sed שתעשה החלפה למחרוזות שהלוגר מקבל, על ידי הגדרה של שני משתנים כשהראשון מקבל regex מה להחליף והשני מגדיר לאיזה מחרוזת להחליף.
נשנה מעט את הפונקציה שלנו וכעת היא נראית כך.
אבל עכשיו יש בעיה אחרת, אם כל פעם נצטרך ליצור משתנים שמגדירים איזה תוכן לצנזר, זה אומר שנצטרך גם למחוק את אותם משתנים כדי שלא ישפיעו על פונקציות אחרות ויצנזרו מידע שאנו כן צריכים
כדי לפתור את הבעיה הזאת נוכל להריץ את הקוד בתת מעטפת וכך כל המשתנים ימחקו אוטומטית ברגע שהקוד יצא מתת המעטפת.
#subshell
#function
רמת קושי: #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
ולמי שמאוד סקרן כך נראית פונקציית loggerlogger() {
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