לוג לפונקציות, צנזור מידע ו subshell
הרצה של קוד בתת מעטפת מתרחש מכל מיני דרכים כמו בעת שימוש ב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 "${@}")
)