האם לשלוח אתגרים קלילים בבאש מפעם לפעם?
Anonymous Poll
85%
כן בטח, אתגר יהיה ממש נחמד סוף סוף משהו פרקטי
15%
לא חושב, למי יש זמן להשקיע על אתגרים שהם לא עבודה
קבוצות תווים
באש מספקת לנו מספר אופציות להשתמש בregex לשימושים שנצרכים לעיתים קרובות בלא לכתוב regex, היכולת הזאת בשפה של באש נקראת Character classes והיא נראית כך
אם נתבונן נראה שכל האותיות נמחקו אבל הרווחים נשארו, והסיבה לכך היא שהורדנו רק אותיות ולא את הרווחים, בשביל להסיר גם את הרווחים ניתן להשתמש בביטוי [:space:] שתופס רווחים.
להלן רשימה חלקית של הביטויים
#grep
#sed
#regex
#tr
Character classes
רמת קושי: #beginners
אני מניח שלכל אחד יש יחסי אהבה שנאה עם regex, regex מספק יכולת ממש טובה לבחור טקסט אבל הקריאות שלו מזעזעת במקרה הטוב.באש מספקת לנו מספר אופציות להשתמש בregex לשימושים שנצרכים לעיתים קרובות בלא לכתוב regex, היכולת הזאת בשפה של באש נקראת Character classes והיא נראית כך
[[:alpha:]]
, לדוגמה.$ echo "Have a nice day :-)" | tr -d "[[:alpha:]]"
:-)
ביטוי שבוחר את כל האותיות וכפי שניתן לראות כל האותיות נבחרו ונמחקו. אם נתבונן נראה שכל האותיות נמחקו אבל הרווחים נשארו, והסיבה לכך היא שהורדנו רק אותיות ולא את הרווחים, בשביל להסיר גם את הרווחים ניתן להשתמש בביטוי [:space:] שתופס רווחים.
$ echo "Have a nice day :-)" | tr -d "[[:alpha:][:space:]]"
:-)
במידה ונרצה להפוך את הביטוי ניתן לעשות זאת על ידי ^
$ echo "1 1 root root $" | tr -d "[^[:alpha:]]"
rootroot
בעבר מספיק היה להשתמש בסוגריים מרובעות פעם אחת בשביל לממש את הביטוי לדוגמה [:print:]
, בגרסאות החדשות יותר של gnu צריכים להכפיל את הסוגריים למימוש הביטוי, וכמובן ניתן להשתמש ביותר מביטוי אחד בתוך סוגריים כפי שראינו לעיל [[:alpha:][:space:]].להלן רשימה חלקית של הביטויים
[:alpha:] == אותיות
[:digit:] == מספרים
[:space:] == תוים לבנים
[:blank:] == רווחים וטאבים
[:punct:] == תווים מיוחדים
[:alnum:] == [:alpha:][:digit:]
[:graph:] == [:alnum:][:punct:]
[:print:] == [:alnum:][:punct:][:space:]
[:xdigit:] == Hex
#character_classes#grep
#sed
#regex
#tr
@bash_tips👍1
נענים לאתגר
רמת קושי: #advanced
האתגר הבא מבוסס על סיפור אמיתי, כמו רוב הטיפים בערוץ 😊.
קובץ זיפ הבא מכיל רשימת קבצי דמה PDF של אקורדים לגיטרה בשמות עבריים, שמות הקבצים מורכבים משם הזמר ושם השיר (לרוב), חלק משמות הקבצים הן עם רווח והאחרים עם
לעשות סדר בחדר
האתגר אם כן הוא לכתוב סקריפט קטנטן שלוקח את הקבצים ומסדר את כל השירים של זמר מסויים בתיקייה שנושאת את שמו.
בסופו של דבר התוצאה צריכה להיות הכי קרובה לזו של תמונת הפוסט, עץ תיקיות של רשימת זמרים, כל תיקייה מכילה את השירים של אותו הזמר, וכמובן לא להשאיר תיקיות ריקות.
לאתגר זה יש כמה רמות
1. לבנות את עץ התיקיות על סמך זה ששם הזמר הוא בתחילת שם הקובץ, שירים שאין להם שם זמר יכנסו לתיקיה בעלת שם השיר, או קומבינציה מוזרה אחרת.
2. להצליח להתגבר על קבצים ששם הזמר נמצא בסוף שם הקובץ.
מוזמנים לפרסם את הפתרונות שלכם בתגובות בערוץ גם אם הם חלקיים
בהצלחה לכולם
#challenge
@bash_tips
רמת קושי: #advanced
האתגר הבא מבוסס על סיפור אמיתי, כמו רוב הטיפים בערוץ 😊.
קובץ זיפ הבא מכיל רשימת קבצי דמה PDF של אקורדים לגיטרה בשמות עבריים, שמות הקבצים מורכבים משם הזמר ושם השיר (לרוב), חלק משמות הקבצים הן עם רווח והאחרים עם
.
או עם _
כמפריד בין המילים ובכלל יש עוד כל מיני הפתעות.לעשות סדר בחדר
האתגר אם כן הוא לכתוב סקריפט קטנטן שלוקח את הקבצים ומסדר את כל השירים של זמר מסויים בתיקייה שנושאת את שמו.
בסופו של דבר התוצאה צריכה להיות הכי קרובה לזו של תמונת הפוסט, עץ תיקיות של רשימת זמרים, כל תיקייה מכילה את השירים של אותו הזמר, וכמובן לא להשאיר תיקיות ריקות.
לאתגר זה יש כמה רמות
1. לבנות את עץ התיקיות על סמך זה ששם הזמר הוא בתחילת שם הקובץ, שירים שאין להם שם זמר יכנסו לתיקיה בעלת שם השיר, או קומבינציה מוזרה אחרת.
2. להצליח להתגבר על קבצים ששם הזמר נמצא בסוף שם הקובץ.
מוזמנים לפרסם את הפתרונות שלכם בתגובות בערוץ גם אם הם חלקיים
בהצלחה לכולם
#challenge
@bash_tips
צינורות ושמות
רמת קושי: #advanced
שימוש יומיומי בבאש מכריח אותנו להכיר את הצורך ב pipe זוהי בעצם הדרך לשרשר מידע של פקודה אחת לאחרת, היום נכיר חבר חדש המוכר בשם named pipe
הקונספט
כשאנו מריצים סקריפט כל מה שהוא עושה זה לרוץ בתהליך משלו, ליצור תתי תהליכים תחתיו אבל כל מה שמתרחש הוא בסשן של אותו הסקריפט.
מה שמאפשר לנו named pipe בעצם הוא לשמור מידע בזיכרון המחשב ולגשת לאותו המידע מכל תהליך במערכת, ברגע שהמידע נקרא על ידי תהליך הוא כבר לא קיים בזיכרון.
אפשר להסתכל על זה כעל שירות שליחת "הודעות" בין תהליכים עם תמיכה באופליין, כל עוד התהליך שמעוניין במידע לא לוקח אותו.
מספר דרכים בכדי ליצור named pipe
אוקי מדהים אבל למה לא פשוט לכתוב לקובץ ולמחוק לאחר מכן?
לא כל דבר נרצה לאחסן על המחשב במיוחד מפתחות ומידע רגיש אחר, הרעיון שהמידע קיים רק בזיכרון ונמחק ברגע שהוא נקרא (בהנחה שהוא לא כבד ועובר לswap) מספק לנו פחות דברים לדאוג להם.
מדובר על דרך מהירה לקבל מידע ממספר תהליכים עליו ניתן לבצע עיבוד, למשל הקוד הבא שיצור לוג חביב לכל מידע שיכנס שיופנה אל ה pipe מכל תוכנית שתפנה אל הpipe במערכת
#named_pipe
mkfifo
רמת קושי: #advanced
שימוש יומיומי בבאש מכריח אותנו להכיר את הצורך ב pipe זוהי בעצם הדרך לשרשר מידע של פקודה אחת לאחרת, היום נכיר חבר חדש המוכר בשם named pipe
הקונספט
כשאנו מריצים סקריפט כל מה שהוא עושה זה לרוץ בתהליך משלו, ליצור תתי תהליכים תחתיו אבל כל מה שמתרחש הוא בסשן של אותו הסקריפט.
מה שמאפשר לנו named pipe בעצם הוא לשמור מידע בזיכרון המחשב ולגשת לאותו המידע מכל תהליך במערכת, ברגע שהמידע נקרא על ידי תהליך הוא כבר לא קיים בזיכרון.
אפשר להסתכל על זה כעל שירות שליחת "הודעות" בין תהליכים עם תמיכה באופליין, כל עוד התהליך שמעוניין במידע לא לוקח אותו.
מספר דרכים בכדי ליצור named pipe
$ mkfifo mypipe
$ mknod mypipe p
$ ls -la
prw-rw-r-- 1 user user 0 אוק 24 23:01 mypipe
...
אנו יוצרים "קובץ" בתיקייה הנוכחית בשם mypipe (מסומן עם p) אליו נוכל לשלוח איזה מידע שנרצה, פעולת הכתיבה לא תסתיים עד שהצד השני יקרא את התוכן ולכן נרצה להריץ את הפקודה ברקע כדי לא לעצור את התהליך.$ echo "Sending data through mypipe" > mypipe &
[1] 10839
$ cat < mypipe
[1] + 10839 done echo "Sending data through mypipe" > mypipe
Sending data through mypipe
או אם רוצים להאזין לכל תוכן שמועבר בלי שיסגר ה pipe $ tail -f mypipe
סגירת ה named pipe היא כמו כל קובץ פשוט למחוק עם rm אוקי מדהים אבל למה לא פשוט לכתוב לקובץ ולמחוק לאחר מכן?
לא כל דבר נרצה לאחסן על המחשב במיוחד מפתחות ומידע רגיש אחר, הרעיון שהמידע קיים רק בזיכרון ונמחק ברגע שהוא נקרא (בהנחה שהוא לא כבד ועובר לswap) מספק לנו פחות דברים לדאוג להם.
מדובר על דרך מהירה לקבל מידע ממספר תהליכים עליו ניתן לבצע עיבוד, למשל הקוד הבא שיצור לוג חביב לכל מידע שיכנס שיופנה אל ה pipe מכל תוכנית שתפנה אל הpipe במערכת
mkfifo /tmp/logpipe
while true
do
read record </tmp/logpipe
echo $(date): "$record" >>/tmp/app.log
done
#mkfifo#named_pipe
@bash_tips
Bash Tips
פקודת sed להשתמש ב ! במקום \ פקודה מוכרת בעולם הלינוקס היא sed פקודה שמאפשרת לבצע מניפולציות על טקסט מבלי לפתוח עורך טקסט הקובץ שלי מכיל את הטקסט הפשוט הבא $ cat test.txt my path is /tmp/test/hello שימוש בsed מאפשר להחליף טקסט קיים בקובץ ולשמור אותו.…
רמת קושי: #advanced
עברה תקופה למדנו החכמנו, קבלו שיפור לטיפ
ראינו בעבר שניתן להגדיר
חביב לא? רגע זה לא הדבר הכי משוגע שראיתם
כמובן שאם התו שאיתו בחרתי לעבוד קיים כחלק מהטקסט אצטרך להחריג אותו עם \ כמו כל משפט sed רגיל
פקודת sed מחפשת מהו התו שאחרי ה s ומחליטה להשתמש בו כחוצץ, במידה ואין הצהרה התחלתית במשפט ב sed איזה תהליך הוא הולך לבצע (delete למשל) צריך להחריג את התו הראשון כדי להסביר לsed שהוא נבחר להיות ה delimiter
#bre
עברה תקופה למדנו החכמנו, קבלו שיפור לטיפ
ראינו בעבר שניתן להגדיר
!
כ delimiter, הטיפ הבא מדבר על כך שכמעט כל תו חוץ מסלאש הפוך יוכל להיות delimiter, זה נראה כך$ echo sed is cool | sed 's|cool|great|g'
sed is great
$ echo sed is cool | sed 's#cool#great#g'
sed is great
$ echo sed is cool | sed 's_cool_great_g'
sed is great
$ echo sed is cool | sed 's^cool^great^g'
sed is great
טוב אני מניח שהבנתם את הרעיוןחביב לא? רגע זה לא הדבר הכי משוגע שראיתם
$ echo sed is cool | sed 'swcoolwgreatwg'
sed is great
כשאומרים כל תו הכוונה גם לאותיות, במקרה לעיל השתמשנו ב w בתור חוצץ.כמובן שאם התו שאיתו בחרתי לעבוד קיים כחלק מהטקסט אצטרך להחריג אותו עם \ כמו כל משפט sed רגיל
$ echo sed is cool | sed 'slcoo\llgreatlg'
sed is great
איך זה עובד?פקודת sed מחפשת מהו התו שאחרי ה s ומחליטה להשתמש בו כחוצץ, במידה ואין הצהרה התחלתית במשפט ב sed איזה תהליך הוא הולך לבצע (delete למשל) צריך להחריג את התו הראשון כדי להסביר לsed שהוא נבחר להיות ה delimiter
$ echo sed is not cool | sed '\|not|d'
#sed#bre
@bash_tipsלהיות פרודוקטיבי
רמת קושי: #advanced
פקודה ממש יעילה היא
לא סגורים על איך השינוי שאנו הולכים לעשות יראה בסופו של דבר? בעזרת הדגל
נ.ב. ימים אחרונים לאתגר ולאחר מכן אפרסם פתרון אפשרי.
#rename
@bash_tips
rename
רמת קושי: #advanced
פקודה ממש יעילה היא
rename
, הפקודה מאפשרת לשנות שמות של מספר קבצים בו זמנית, והסינטקס? גמיש כמו של sed $ rename 's/.txt/.log/' *.txt
$ rename 's/_/ /' *.pdf
$ rename 's/[[:punct:]]/ /' *.pdf
אנו מגדירים על אלו קבצים הפקודה תתבצע (*.txt), ועל אותם הקבצים חל ביטוי ההחלפה ( 's/.txt/.log/'
).לא סגורים על איך השינוי שאנו הולכים לעשות יראה בסופו של דבר? בעזרת הדגל
-n
ניתן להשתמש בפקודה על "יבש" ורק אז להריץ אותה באמת.$ rename -n 's|log|txt|' *.log
rename(10.log, 10.txt)
rename(1.log, 1.txt)
rename(2.log, 2.txt)
rename(3.log, 3.txt)
...
כפי שרואים הביטוי דומה מאוד לsed ועל כן הכללים של הטיפ הקודם חלים גם על פקודת rename
וניתן להשתמש בכל תו שרוצים כחוצץנ.ב. ימים אחרונים לאתגר ולאחר מכן אפרסם פתרון אפשרי.
#rename
@bash_tips
Bash Tips
מילונים / מערכים אסוציאטיבים ובאש מאז הגרסאות האחרונות של באש יש אובייקט חדש שמוכר מכל שפת תכנות נפוצה הלא הוא מילון/מערך אסוציטיבי, ניתן להגדיר אותו על ידי שימוש ב declare שדיברנו עליו בעבר $ declare -A my_dict $ my_dict=(["First Name"]="Yossi" ["Last Name"]="Cohen")…
מפתחות וערכים
רמת קושי: #advanced
כפי שראינו בעבר הגדרה של מערך נראית כך
ישנם משתנים בבאש שמכילים מידע במערך אסוציאטיבי, למשל המשתנה הגלובלי BASH_ALIASES שמכיל את כל האליאסים בתצורה של key value
נ.ב. ימים אחרונים לאתגר ולאחר מכן אפרסם פתרון אפשרי.
#array
@bash_tips
רמת קושי: #advanced
כפי שראינו בעבר הגדרה של מערך נראית כך
$ declare -A my_array
$ my_array=([first]="test here" [second]="more text here")
יש לנו מערך אסוציאטיבי בעל שני מפתחות, בכדי לקבל ערך פשוט קוראים למערך עם המפתח המתאים.$ echo "${my_array[first]}"
test here
$ echo "${my_array[second]}"
more text here
אפשרות נוספת שבאש מאפשרת לנו היא לרוץ רק על הערכים על ידי שימוש ב @
במקום מפתח $ for i in "${my_array[@]}"; do
echo $i
done
test here
more text here
או אם רוצים לקבל רק את המפתחות פשוט לשים !
לפני שם המערך$ for i in "${!my_array[@]}"; do
echo $i
done
first
second
ובדומה למערך רגיל #
לפני שם המערך האסוציאטיבי יחזיר את הגודל שלו $ echo "${#my_array[@]}"
2
למה זה מעניין אותנו כל הסיפור הזה?ישנם משתנים בבאש שמכילים מידע במערך אסוציאטיבי, למשל המשתנה הגלובלי BASH_ALIASES שמכיל את כל האליאסים בתצורה של key value
נ.ב. ימים אחרונים לאתגר ולאחר מכן אפרסם פתרון אפשרי.
#array
@bash_tips
לקבץ פקודות ותת מעטפת
רמת קושי: #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
רמת קושי: #advanced
פוסט נהדר של ינון פרק
אני מדביק כאן את הלינק לפוסט כי הדיון בתגובות פשוט מעניין
https://t.me/c/1217780911/5892
#cal
#ncal
@bash_tips
פוסט נהדר של ינון פרק
אני מדביק כאן את הלינק לפוסט כי הדיון בתגובות פשוט מעניין
https://t.me/c/1217780911/5892
#cal
#ncal
@bash_tips
Forwarded from לומדים לינוקס
רישום למערכת
אתחול מעטפת
ישנן שני אפשרויות כניסה של משתמש למערכת, האחת טוענת את כל הסביבה של המשתמש, ומוכרת בשם
והאחרת פשוט מחליפה את המשתמש אבל לא טוענת את כל הסביבה, מוכרת בשם
עוד מידע בנושא ניתן למצוא ב man bash INVOCATION
@learnlinuxnote
אתחול מעטפת
ישנן שני אפשרויות כניסה של משתמש למערכת, האחת טוענת את כל הסביבה של המשתמש, ומוכרת בשם
login shell
.והאחרת פשוט מחליפה את המשתמש אבל לא טוענת את כל הסביבה, מוכרת בשם
non login shell.
כניסה רגילה למערכת טוענת את כל סביבת המעטפת, ומחפשת לטעון את הקבצים שברשימה אם הם קיימים, ברגע שאחד מהם זוהה האחרים לא יטענו פרט לקובץ /etc/bashrc
שיטען תמיד/etc/profileמצד שני אם מחליפים משתמש על ידי
~/.bash_profile
~/.bash_login
~/.bashrc
su
לא כל הסביבה של המשתמש שהוחלף נטענת, והקבצים שיטענו הן רק /etc/bashrcבכדי לטעון משתמש אחר עם su ולטעון את כל הסביבה שלו ציך לציין זאת במפורש על ידי דגל
~/.bashrc
-l
או על ידי הקיצור שלו שמוכר יותר su -
$ su -l
$ su -
אם כן למדנו טריק נחמד, ברגע שרוצים לטעון מחדש את סביבת המשתמש בלי לעשות login logout, ניתן פשוט להריץ$ su - userישנן עוד השפעות non shell login כגון משתני סביבה שלא מוגדרים
עוד מידע בנושא ניתן למצוא ב man bash INVOCATION
@learnlinuxnote
Bash Tips
bash_tips-stop_recursion.sh
רקורסיה $0 $$, ושני אתגרונים בקצה
רמת קושי: #advanced
בעבר דברנו על כך שכשמעבירים לסקריפט באש פרמטרים אז הם נכנסים לסקריפט כמשתנים בשמות $1 לפרמטר הראשון ו$2 $3 לשני והשלישי בהתאמה וכו', מצליחים לנחש איזה ערך נמצא במשתנה $0?
עכשיו המח הקודח שלנו מיד נכנס לפעולה וחושב אה מגניב אז ככה בעצם אפשר ליצור סקריפט שקורא לעצמו. רקורסיה!!!!1 💪💪💪
הסקריפט נח ל20 שניות ומריץ את עצמו שוב
כמו שאתם מבינים החולשות של רקורסיה נמצאות גם כאן, כל התהליכים נוצרים תחת התהליך המקורי, הסקריפט אף פעם לא מגיע לתהליך סיום ולכן כל הרצה שומרת מחדש את כל הסקריפט בזיכרון.
אתגרונים אתגרונים
ועכשיו לשני אתגרים קטנים שתשתגעו עליהם.
1. איך לגרום לסקריפט החדש שרץ (
2. איך לסגור את הסקריפט הפשוט הבא (הקובץ המצוטט בערוץ) כשאתם מריצים אותו ברקע כך
#challenge
#arguments
#bash_pid
@bash_tips
רמת קושי: #advanced
בעבר דברנו על כך שכשמעבירים לסקריפט באש פרמטרים אז הם נכנסים לסקריפט כמשתנים בשמות $1 לפרמטר הראשון ו$2 $3 לשני והשלישי בהתאמה וכו', מצליחים לנחש איזה ערך נמצא במשתנה $0?
$ cat test.sh
echo "$0"
$ ./test.sh
./test.sh
כן!, הפרמטר הראשון של כל סקריפט הוא השם של הסקריפט עצמו.עכשיו המח הקודח שלנו מיד נכנס לפעולה וחושב אה מגניב אז ככה בעצם אפשר ליצור סקריפט שקורא לעצמו. רקורסיה!!!!1 💪💪💪
$ cat test.sh
echo "$0 | $$"
sleep 20
$0
$ ./test.sh
./test.sh | 101394
./test.sh | 101395
./test.sh | 101396
...
מה היה לנו כאן בעצם?$0
מעביר את שם הסקריפט$$
מציג את מספר התהליך של הסקריפטהסקריפט נח ל20 שניות ומריץ את עצמו שוב
כמו שאתם מבינים החולשות של רקורסיה נמצאות גם כאן, כל התהליכים נוצרים תחת התהליך המקורי, הסקריפט אף פעם לא מגיע לתהליך סיום ולכן כל הרצה שומרת מחדש את כל הסקריפט בזיכרון.
אתגרונים אתגרונים
ועכשיו לשני אתגרים קטנים שתשתגעו עליהם.
1. איך לגרום לסקריפט החדש שרץ (
$0
) להחליף את מספר התהליך שלו מבלי להיות תת תהליך של התהליך המקורי ובכך לגרום לסקריפט המקורי להגיע לנקודת סיום ולשחרר את הזיכרון.2. איך לסגור את הסקריפט הפשוט הבא (הקובץ המצוטט בערוץ) כשאתם מריצים אותו ברקע כך
$ ./bash_tips-stop_recursion.sh &
תוכן הקובץ$ batcat bash_tips-stop_recursion.sh
───────┬────────────
│ File: test.sh
───────┼────────────
1 │ #!/bin/bash
2 │
3 │ echo "$0 | $$"
4 │ sleep 1
5 │ $0
מוזמנים לשתף בתגובות מה דגתם#challenge
#arguments
#bash_pid
@bash_tips
Bash Tips
נענים לאתגר רמת קושי: #advanced האתגר הבא מבוסס על סיפור אמיתי, כמו רוב הטיפים בערוץ 😊. קובץ זיפ הבא מכיל רשימת קבצי דמה PDF של אקורדים לגיטרה בשמות עבריים, שמות הקבצים מורכבים משם הזמר ושם השיר (לרוב), חלק משמות הקבצים הן עם רווח והאחרים עם . או עם _ כמפריד…
פתרון האתגר סדר בחדר
רמת קושי: #beginners
משימה ראשונה
בואו נציץ לרגע במשימה הראשונה של האתגר ונראה מהי.
לבנות את עץ התיקיות על סמך זה ששם הזמר הוא בתחילת שם הקובץ,
שירים שאין להם שם זמר יכנסו לתיקיה בעלת שם השיר, או קומבינציה מוזרה אחרת.
האתגר הראשון בו אנו נתקלים כשאנו נגשים לאתגר הוא חוסר סטנדרטיזציה בשמות הקבצים, אם נעיף רגע מבט על כל הקבצים נשים לב שרוב הקבצים מסודרים כך ששם הזמר מופיע בתחילת שם הקובץ, אם כן בשביל להשיג סדר ראשוני בקבצים נוכל לארגן חלק ניכר מהקבצים על ידי שליפת 2 המילים הראשונות של שם הקובץ וליצור ממנו תיקייה.
וזה בדיוק מה שעושה הקוד הבא
שורה 3 ו 4: מעבירה את שם הקובץ את התהליך הבא שמורכב מ3 חלקים
1. מעבירה את שם הקובץ הבא לפקודת
2. פקודת
שלב א' היא מסירה את כל התווים המיוחדים והרווחים שמופיעים בתווים הראשונים של הקובץ .
שלב ב' היא מחליפה את תווי
מה שמביא אותנו למצב ששם הקובץ כרגע הוא כך
פקודת
ואז אנו מעבירים טווח של מילים אותם אנו רוצים לשלוף, 1-2 אלו שני המילים הראשונות.
אז כרגע בסופו של תהליך שורה 3 נראית כך
שורה 5: יוצרת תיקיית על שם הזמר.
שורה 6: מעתיקה את השיר לתיקייה שכרגע נוצרה.
התוצאה היא רשימת תיקיות שמכילות את שני המילים הראשונות של הקבצים.
קבצים שיש להם את אותם 2 מילים בראש הקובץ מקובצים תחת אותה תיקייה.
עד כאן חלק א' של האתגר
יש לכם רעיונות לשיפור, הערות, טיפים? מוזמנים לשתף בתגובות
בימים הקרובים אפרסם פתרון גם למשימה השניה, עד אז מי שרוצה לאתגר את עצמו מוזמן
#challenge
#loops
#sed
#cut
@bash_tips
רמת קושי: #beginners
משימה ראשונה
בואו נציץ לרגע במשימה הראשונה של האתגר ונראה מהי.
לבנות את עץ התיקיות על סמך זה ששם הזמר הוא בתחילת שם הקובץ,
שירים שאין להם שם זמר יכנסו לתיקיה בעלת שם השיר, או קומבינציה מוזרה אחרת.
האתגר הראשון בו אנו נתקלים כשאנו נגשים לאתגר הוא חוסר סטנדרטיזציה בשמות הקבצים, אם נעיף רגע מבט על כל הקבצים נשים לב שרוב הקבצים מסודרים כך ששם הזמר מופיע בתחילת שם הקובץ, אם כן בשביל להשיג סדר ראשוני בקבצים נוכל לארגן חלק ניכר מהקבצים על ידי שליפת 2 המילים הראשונות של שם הקובץ וליצור ממנו תיקייה.
וזה בדיוק מה שעושה הקוד הבא
1 for file in *;
2 do
3 sed_expr='s/^[[:punct:][:space:]]//g ; s/[_,-]/ /g'
4 dest="test/$(echo "${file}" | sed "$sed_expr" | cut -f 1-2 -d ' ' )"
5 mkdir -p "$dest"
6 cp "$file" "$dest"
7 done
שורה 1: אוספת את כל הקבצים שבתיקייה ומעבירה קובץ קובץ לעיבוד.שורה 3 ו 4: מעבירה את שם הקובץ את התהליך הבא שמורכב מ3 חלקים
1. מעבירה את שם הקובץ הבא לפקודת
sed
שמחה_פרידמן_עוד_יבוא_היום_אקורדים_קלים.pdf
2. פקודת
sed
מריצה שני עיבודים כדי ליצור סטנדרט בין כל הקבצים (;
הוא חוצץ בין שני הביטויים)שלב א' היא מסירה את כל התווים המיוחדים והרווחים שמופיעים בתווים הראשונים של הקובץ .
שלב ב' היא מחליפה את תווי
_ , -
ברווח.מה שמביא אותנו למצב ששם הקובץ כרגע הוא כך
שמחה פרידמן עוד יבוא היום אקורדים קלים.pdf
3. בחירה של 2 המילים הראשונות, איך זה קורה? פקודת
cut
מקבלת פרמטר לפיו היא מפצלת מילים על פי רווח, ואז אנו מעבירים טווח של מילים אותם אנו רוצים לשלוף, 1-2 אלו שני המילים הראשונות.
אז כרגע בסופו של תהליך שורה 3 נראית כך
dest="test/שמחה פרידמן"
מפה זה די פשוט וקלשורה 5: יוצרת תיקיית על שם הזמר.
שורה 6: מעתיקה את השיר לתיקייה שכרגע נוצרה.
התוצאה היא רשימת תיקיות שמכילות את שני המילים הראשונות של הקבצים.
קבצים שיש להם את אותם 2 מילים בראש הקובץ מקובצים תחת אותה תיקייה.
עד כאן חלק א' של האתגר
יש לכם רעיונות לשיפור, הערות, טיפים? מוזמנים לשתף בתגובות
בימים הקרובים אפרסם פתרון גם למשימה השניה, עד אז מי שרוצה לאתגר את עצמו מוזמן
#challenge
#loops
#sed
#cut
@bash_tips
Bash Tips
נענים לאתגר רמת קושי: #advanced האתגר הבא מבוסס על סיפור אמיתי, כמו רוב הטיפים בערוץ 😊. קובץ זיפ הבא מכיל רשימת קבצי דמה PDF של אקורדים לגיטרה בשמות עבריים, שמות הקבצים מורכבים משם הזמר ושם השיר (לרוב), חלק משמות הקבצים הן עם רווח והאחרים עם . או עם _ כמפריד…
פתרון האתגר סדר בחדר
משימה שניה
רמת קושי: #beginners
החלק השני של המשימה הוא
להצליח להתגבר על קבצים ששם הזמר נמצא בסוף שם הקובץ.
לכאורה כשחושבים על המשימה הזאת בפעם הראשונה לא מבינים איך זה אפשרי לביצוע בלא שיהיה רשימה של הזמרים לעבור עליה ולחפש מחרוזות. לאחר שמסיימים את האתגר הראשון מבינים שבעצם יש לנו רשימה של זמרים, הלא היא רשימת התיקיות שיצרנו במשימה הראשונה שבעצם נתנה לנו רשימה נכבדה של זמרים.
מה יהיה אם פשוט נעבור על שמות התיקיות שיצרנו ונחפש את המחרוזות שלהם בכל הקבצים? בצורה הזאת לא משנה היכן יהיה קיים שם הזמר, אם לפני כן היה קובץ אחד ששם הזמר היה בתחילתו, נוכל לאתר את כל הקבצים ששם הזמר נמצא בסופם.
הקוד שמריץ את התהליך הזה פשוט אף הוא והוא נראה כך
שורה 7: אוספת את כל שמות התיקיות שנמצא תחת תיקיית העבודה שיצרנו (test)
ובעצם יוצא שכך נראה כרגע התוכן של משתנה
1. לוקחת את שם הזמר בדוגמה שלנו הוא
הנתיבים שאנו מקבלים נראים כך
2. שמות הקבצים שיצאו תואמים לשם התיקייה של הזמר מועברים לאותה תיקייה.
זה גורם לכך שכל תיקיית זמר מאורגנת מחדש ומקבלת קבצים חדשים, ולכך שיש כרגע תיקיות ריקות בעץ הקבצים שלנו לאחר ששלפנו משם את הקבצים שהיו תואמים את החיפוש.
שורה 12: הפקודה האחרונה בסופו של דבר עוברת על כל התיקיות הריקות ומוחקת אותם.
זהו עד כאן משימה שניה של האתגר
התיקיות לא מסודרות עדין 100% כי יש זמרים ששמם מופיע בסוף הקובץ מבלי שיהיו להם קבצים ששם הזמר מופיע בתחילתם, עוד קבצים אחרים שאינם נושאים שם זמר וכו' אבל 95% עבודה נעשתה, כנראה שזהו שלב 20/80 במצב שלנו.
#challenge
#find
#loop
#rmdir
@bash_tips
משימה שניה
רמת קושי: #beginners
החלק השני של המשימה הוא
להצליח להתגבר על קבצים ששם הזמר נמצא בסוף שם הקובץ.
לכאורה כשחושבים על המשימה הזאת בפעם הראשונה לא מבינים איך זה אפשרי לביצוע בלא שיהיה רשימה של הזמרים לעבור עליה ולחפש מחרוזות. לאחר שמסיימים את האתגר הראשון מבינים שבעצם יש לנו רשימה של זמרים, הלא היא רשימת התיקיות שיצרנו במשימה הראשונה שבעצם נתנה לנו רשימה נכבדה של זמרים.
מה יהיה אם פשוט נעבור על שמות התיקיות שיצרנו ונחפש את המחרוזות שלהם בכל הקבצים? בצורה הזאת לא משנה היכן יהיה קיים שם הזמר, אם לפני כן היה קובץ אחד ששם הזמר היה בתחילתו, נוכל לאתר את כל הקבצים ששם הזמר נמצא בסופם.
הקוד שמריץ את התהליך הזה פשוט אף הוא והוא נראה כך
7 for dir in test/*;
8 do
9 dirname="${dir/ /*}"
10 find test/* -type f -path "*${dirname##*/}*" -exec mv {} "$dir" \;
11 done
12 rmdir test/*
אחרי שהסברנו מה הרעיון שהקוד בא לממש, נעבר לראות איך זה קורה בפועלשורה 7: אוספת את כל שמות התיקיות שנמצא תחת תיקיית העבודה שיצרנו (test)
test/שמחה פרידמן
שורה 9: מחליפה את הרווח בכוכבית, למה אתם שואלים? כי regex זה חשוב.ובעצם יוצא שכך נראה כרגע התוכן של משתנה
dirname
test/שמחה*פרידמן
שורה 10: מבצעת 2 פעולות1. לוקחת את שם הזמר בדוגמה שלנו הוא
שמחה*פרידמן
ומחפשת קבצים שנושאים את שם שלו תחת הנתיב testהנתיבים שאנו מקבלים נראים כך
test/שמחה פרידמן/שמחה_פרידמן_עוד_יבוא_היום_אקורדים_קלים.pdf
החיפוש נעזר בregex, זוכרים את ה * ממקודם? אז כאן היא באה לידי שימוש ו find
מקבל את המחרוזת ה regex הבאה *שמחה*פרידמן*
ומחפש אותה בנתיב של הקבצים כמו זה שראינו שלעיל, זה מביא לידי כך שלא משנה אלו תווים יש לפני ואלו תווים יש אחרי או אפילו באמצע המחרוזת, שם הזמר תמיד יהיה מזוהה.2. שמות הקבצים שיצאו תואמים לשם התיקייה של הזמר מועברים לאותה תיקייה.
זה גורם לכך שכל תיקיית זמר מאורגנת מחדש ומקבלת קבצים חדשים, ולכך שיש כרגע תיקיות ריקות בעץ הקבצים שלנו לאחר ששלפנו משם את הקבצים שהיו תואמים את החיפוש.
שורה 12: הפקודה האחרונה בסופו של דבר עוברת על כל התיקיות הריקות ומוחקת אותם.
זהו עד כאן משימה שניה של האתגר
התיקיות לא מסודרות עדין 100% כי יש זמרים ששמם מופיע בסוף הקובץ מבלי שיהיו להם קבצים ששם הזמר מופיע בתחילתם, עוד קבצים אחרים שאינם נושאים שם זמר וכו' אבל 95% עבודה נעשתה, כנראה שזהו שלב 20/80 במצב שלנו.
#challenge
#find
#loop
#rmdir
@bash_tips
Forwarded from לומדים לינוקס
לקבל את רשומי המערכת
getent
לינוקס מלאה בקבצים שמכילים מידע על משתמשים, תהליכים, הגדרות וכו', במקום לרוץ ולאסוף את כל המידע הזה ולזכור היכן הוא ממוקם ישנה פקודה שמנגישה את המידע, קובץ ההגדרות נמצא בנתיב /etc/nsswitch.conf
ומאפשר להגדיר מהיכן לאסוף את המידע, להלן רשימת המידע אותו היא מספקת ברירת מחדל$ getent --helpבכדי לקבל מידע במלואו ניתן להריץ
...
Supported databases:
ahosts ahostsv4 ahostsv6 aliases ethers group gshadow hosts initgroups
netgroup networks passwd protocols rpc services shadow
...
$ getent hostsאו לבחור לקבל מידע על ערך ספציפי
127.0.0.1 localhost
192.168.39.12 myrancher.com
178.62.121.30 playground
$ getent services 67@learnlinuxnote
bootps 67/udp
$ getent services git
git 9418/tcp
Forwarded from Alex M. Schapelle
לכל אוהבי באש ואוכל :
https://gitlab.com/lpi-devops/bash_cuisine
https://gitlab.com/lpi-devops/bash_cuisine
GitLab
Lpi and DevOps Course / Bash Cuisine
👍1
טיפ נהדר של @dank3y והזוית של באש
רמת קושי: #advanced
משתמשי Zsh
אם אתם על הטרמינל כותבים פקודה כלשהי, מעבר לשימוש ב-vi mode של zsh כדי לערוך אותה,
לחיצה על ctrl + e (או מקש אחר לבחירתכם) תביא אתכם ל- vim על מלא בו תוכלו לערוך את הקוד ממש כאילו היה מיני סקריפט שלכם.
כשתסיימו תוכלו לשגר אותו ל-prompt שלכם עם שמירה ויציאה כמו שאתם מכירים.
נדרש רק להוסיף את שתי השורות האלו לקובץ
ניתן להשתמש בפונקציונליות דומה אין צורך להגדיר שום דבר, קיצור המקשים הוא
בשני המקרים העורך שיפתח הוא העורך שמוגדר למשתנה הסביבה
רמת קושי: #advanced
משתמשי Zsh
אם אתם על הטרמינל כותבים פקודה כלשהי, מעבר לשימוש ב-vi mode של zsh כדי לערוך אותה,
לחיצה על ctrl + e (או מקש אחר לבחירתכם) תביא אתכם ל- vim על מלא בו תוכלו לערוך את הקוד ממש כאילו היה מיני סקריפט שלכם.
כשתסיימו תוכלו לשגר אותו ל-prompt שלכם עם שמירה ויציאה כמו שאתם מכירים.
נדרש רק להוסיף את שתי השורות האלו לקובץ
.zshrc
שלכם:autoload edit-command-line; zle -N edit-command-line
bindkey '^e' edit-command-line
משתמשי Bashניתן להשתמש בפונקציונליות דומה אין צורך להגדיר שום דבר, קיצור המקשים הוא
Ctrl + X
Ctrl + E
בשני המקרים העורך שיפתח הוא העורך שמוגדר למשתנה הסביבה
$EDITOR
#editor
@bash_tips