עבודה עם
עורך הטקסט
טיפ נחמד ש-nano מאפשרת זה לפתוח מספר קבצים במקביל על ידי העברת שמות הקבצים כפרמט או על ידי שימוש ב wildcard למשל כך
@bash_tips
nano
ומספר קבציםעורך הטקסט
nano
הפך להיות עורך ברירת מחדל בלא מעט הפצות (אפילו יותר מvim), יש ברשת לא מעט קיצורי מקשים איך עובדים איתו, טיפ נחמד ש-nano מאפשרת זה לפתוח מספר קבצים במקביל על ידי העברת שמות הקבצים כפרמט או על ידי שימוש ב wildcard למשל כך
$ touch /tmp/test{1..3}.txtמה שיקרה זה שכל הקבצים שמתאים לתיאור יפתחו ב-
$ nano /tmp/test*
nano
מעבר בין קובץ לקובץ נעשה על ידי >+Alt לקובץ הבא ו <+Alt לקובץ הקודם@bash_tips
אתר מעולה שנותן רשימה יפה מאוד של cheatsheets לשפות תכנות וסקריפט אבל גם לפריימוורקים, מסדי נתונים ועוד
בהקשר של באש
https://devhints.io/bash
בהקשר של באש
https://devhints.io/bash
Devhints.io cheatsheets
Bash scripting cheatsheet
Variables · Functions · Interpolation · Brace expansions · Loops · Conditional execution · Command substitution · One-page guide to Bash scripting
סו sed
בשביל למנוע שורות כפולות בשימוש עם sed משתמשים עם דגל -n שמוריד את ה stdout.
@bash_tips
בשביל למנוע שורות כפולות בשימוש עם sed משתמשים עם דגל -n שמוריד את ה stdout.
sed -n
בהרצה רגילה sed לא משכתב לקובץ את העריכת התוכן שהוא ביצע, בכדי שהוא יערוך את הקובץ עליו הוא רץ מוסיפים את הדגל -i, ניתן להוסיף לפרמטר i שם קובץ חדש כדי שפלט יועבר לקובץ חדש ולא ידרוס את הקובץ הישן$ sed -i.backupfile 'any/filter/here'
myfile.conf
אפשר להשתמש ביותר מביטוי אחד בכל פעם עם sed על ידי שימוש ב ; בין ביטוי לביטוי כך שלמשל אפשרי גם לפלטר שורה שבהערה וגם להסיר שורות ריקות$ sed ' /^#/d ; /^$/d'
@bash_tips
Forwarded from $~deb
אליאס (alias)
אליאס זו הגדרה שנותנת לנו אופציה להגדיר קיצור לפקודה אחרת
איך זה עוזר לנו ? מקל על חיינו בהרבה !
לדוגמה מהיום אני רוצה ליצור משתמשים במקום
בפקודת
כדי לעשות אותם קבועים נשמור אותם בקובץ
מגדירים כך:
מה שגורם לחסרון לעומת הפקודה המקורית.
מה הפתרון?
סקריפט שמוסיפים ל.
איך מתקינים?
נתחיל בהתקנה של bash-completion
נוריד את את תקיית הrepo
נכנס אליה ונכתוב כך
אליאס זו הגדרה שנותנת לנו אופציה להגדיר קיצור לפקודה אחרת
איך זה עוזר לנו ? מקל על חיינו בהרבה !
לדוגמה מהיום אני רוצה ליצור משתמשים במקום
בפקודת
sudo adduser
אני אקצר ל sudo AU
.כדי לעשות אותם קבועים נשמור אותם בקובץ
.bashrc
שנמצא בתקיית הבית.מגדירים כך:
~$ alias <short command> <custom command>אז מה הבעיה באליאס? שבמצב רגיל לא נקבל השלמה אוטומטית לפרמטרים האפשריים של הפקודה
מה שגורם לחסרון לעומת הפקודה המקורית.
מה הפתרון?
סקריפט שמוסיפים ל.
bash_completion
שנותן לנו אפשרות להגדיר alias שיעבוד בדיוק כמו הפקודה המקורית.איך מתקינים?
נתחיל בהתקנה של bash-completion
apt install bash-completion
נעבור להתקנת הסקריפטנוריד את את תקיית הrepo
נכנס אליה ונכתוב כך
cat complete_alias >> ~/.bash_completion
זהו, מהיום כל alias שנגדיר כדי להפעיל לו השלמה אוטומטית כל מה שנעשה זה נכתוב אחרי ההגדרה בbashrc
complete -F _complete_alias <alias name>
GitHub
complete-alias/complete_alias at master · cykerway/complete-alias
automagical shell alias completion;. Contribute to cykerway/complete-alias development by creating an account on GitHub.
Forwarded from לומדים לינוקס
לקבל מידע על החומרה שבמחשב
להלן דוגמאות
dmidecode
, lshw
כל מערכת הפעלה פועלת על חומרה ממנה בנוי המחשב, בכדי לקבל את המידע על חומרת המחשב ישנה טבלה שמחזיקה את כל הערכים דבר הנקרא SMBIOS בעבר זה נקרא DMI ושם לינוקס נמצאת, את המידע אפשר להשיג על ידי פקודת dmidecode
בהרצה פשוטה הפקודה תחזיר מלל ארוך מאוד בקשר לכל הידוע לה על החומרה, כדי לקבל את המידע הרלוונטי שאנו מחפשים על המערכת אפשרי להשתמש בדגלים -t או -s כשהראשון מאפשר לנו לחפש לפי type והשני לפי מחרוזתלהלן דוגמאות
$ sudo dmidecode -s chassis-manufacturerכלי נוסף שמציג מידע על המערכת הוא lswh, בשביל לא לטבוע בכמות המידע אפשר לפלטר את הפלט על ידי שימוש בקטגוריה (Class) של החלק שמעניין אותנו, לדוגמה
ASUSTeK COMPUTER INC.
$ sudo dmidecode -s processor-version
Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz
$ sudo dmidecode -t bios
# dmidecode 3.2
Getting SMBIOS data from sysfs.
SMBIOS 3.0.0 present.
Handle 0x0000, DMI type 0, 24 bytes
BIOS Information
Vendor: American Megatrends Inc.
...
$ sudo lshw -C CPU
*-cpu
description: CPU
product: Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz
vendor: Intel Corp.
physical id: 11
או להשתמש עם דגל -short
שיציג תצוגה מקוצרת שמחולקת לפי קטגוריות$ sudo lshw -short
H/W path Device Class Description
======================================================
system X556URK
/0 bus X556URK
/0/0 memory 64KiB BIOS
תקציר
לפקודה
להלן הבסיס של
כל שיש לזכור הוא s.p.i.d.a
למי שרוצה SS שהוא sed spida
s (substitute) - בכדי להחליף תוכן תחת מיקום ספציפי במסמך
p (print) - בכדי לערוך קובץ ולהדפיס למסך
i (insert) - בכדי להוסיף תוכן מעל מיקום ספציפי במסמך
d (delete) - בכדי למחוק תוכן מהמסמך
a (append) - בכדי להוסיף תוכן תחת מיקום ספציפי במסמך
להרחיב מעט את הבסיס ולבצע כמה פעולות ויחד לדוגמה, לעשות חיפוש והחלפה
בשביל שזה באמת כיף אפשרי להכניס את רצף הפקודות לקובץ כל פקודת עריכה בשורה חדשה ופשוט לקרוא לו שיחיל את רצף העריכות על הקובץ שלנו
כמו שאמרנו לא לשכוח להשתמש ב-
@bash_tips
sed
לפקודה
sed
לא מעט יכולות ופרמטרים הפעם תקראו על sed
ויש מצב שגם תזכרו, למה? בגלל ש-sed
ספידה (s.p.i.d.a)להלן הבסיס של
sed
עם hint לזיכרוןכל שיש לזכור הוא s.p.i.d.a
למי שרוצה SS שהוא sed spida
s (substitute) - בכדי להחליף תוכן תחת מיקום ספציפי במסמך
sed 's/regex/replace to/g' myfile
p (print) - בכדי לערוך קובץ ולהדפיס למסך
sed '/regex/p' myfile
i (insert) - בכדי להוסיף תוכן מעל מיקום ספציפי במסמך
sed '/regex/ i some text to add above the match' myfile
d (delete) - בכדי למחוק תוכן מהמסמך
sed '/regex/d ' myfile
a (append) - בכדי להוסיף תוכן תחת מיקום ספציפי במסמך
sed '/regex/ a some text to add below match' myfile
להרחיב מעט את הבסיס ולבצע כמה פעולות ויחד לדוגמה, לעשות חיפוש והחלפה
$ sed '{
/regex/ a some text here
/regex/ d
}' myfile
בשביל שזה באמת כיף אפשרי להכניס את רצף הפקודות לקובץ כל פקודת עריכה בשורה חדשה ופשוט לקרוא לו שיחיל את רצף העריכות על הקובץ שלנו
$ sed -f myedits myfile
כמו שאמרנו לא לשכוח להשתמש ב-
i
לפני שעושים עריכות על קובץ אמיתי@bash_tips
להריץ פקודות עם
@bash_tips
sed
פיצ'ר נחמד ש-sed
מאפשר זה להריץ פקודות על תוכן שהוא מפלטר, מבנה הפקודה הוא כזהsed 'action/regex/command /e' fileבא נראה איך זה בעצם עובד, לצורך העניין יש לי קובץ של נתיבים שנראה כך ואני רוצה ליצור את הנתיבים הללו במערכת
$ cat mypathאני רוצה לקבל רק את הנתיבים שקיימים בקובץ ולהריץ עליהם
# directories for test
/tmp/tests/first
/tmp/tests/second
# any text here
/tmp/tests/mytest
mkdir
שיצור לי את רצף התיקיות שברשימה$ sed 's/ ^\/ /mkdir -p /e ' mypath
אני משתמש ב substitute כדי לקבל רק את השורות שמתחילות ב /
ואז מריץ עליהם את פקודת mkdir
שתיצור לי תיקייה, כדי להגדיר ל-sed
שמדובר על פקודה שאני רוצה להריץ יש לאחר הפקודה e/
וקיבלתי את שבקשתיtmp/
└── tests
├── first
├── mytest
└── second
@bash_tips
Forwarded from לומדים לינוקס
אחסון
דגל -i יתן מידע על החומרה עצמה ואם היא תומכת ב SMART
לייבל
smarctl
, lsblk
בכדי לקבל רשימה ויזואלית של התקני האחסון שקיימים במערכת ותצוגת המחיצות שלהם ניתן להריץ את lsblk
, כך ניתן לדעת איזה התקן מעוגן לאיזה סוקט$ lsblk
...
sda 8:0 0 238.5G 0 disk
├─sda1 8:1 0 260M 0 part /boot/efi
├─sda2 8:2 0 16M 0 part
├─sda3 8:3 0 79.4G 0 part
...
בכל דיסק מודרני ישנה מערכת שמספקת נתונים על בריאות הדיסק ואם הוא לקראת סוף חייו נקרא בימינו smart בכדי לקבל נתונים על הדיסק אותו אנו רוצים לחקור ניקח את שם הדיסק ונעביר לתוכנת smartctl
שהיא בעצם תוכנה שיודעת לבדוק את הדיסק לקבל את הנתונים ולתת אינפורמציה על הדיסקדגל -i יתן מידע על החומרה עצמה ואם היא תומכת ב SMART
$ sudo smartctl -i /dev/sda
תגית short מסמלת טסט מקוצר $ sudo smartctl -t short /dev/sdaניתן לחזור לבדוק תוצאות לאחר הבדיקה על ידי -l
לייבל
devstat
יחזיר נתונים חשובים על הדיסק, טמפרטורה, כמות reboots שהדיסק עשה ועוד $ sudo smartctl -l devstat /dev/sda
לייבל xerror
יחזיר את השגיאות מהבדיקה שנעשתה$ sudo smartctl -l xerror /dev/sdaלייבל
selftest
יציג סיכום של הבדיקה$ sudo smartctl -l selftest /dev/sda
להתחיל ברגל ימין Awk
לא יודע מה איתכם אבל בעבר כל פתרון ב SO שמשתמש ב-
אז בקצרה מדובר על כלי למניפולציית טקסט שמכיל גם אפשרויות תכנות משתנים תנאים לולאות וכו'
ישנן 2 צורות עבודה עם
תוכן לפקודת
פקודת
ניתן להשתמש בפקודת printf כדי לעצב טקסט בצורה חכמה יותר.
טוב קבלתי את רשימת כל המשתמשים אבל חלקם בכלל לא משתמשים אלא שירותים במערכת, awk מאפשרת לנו להדפיס על עוד תנאי מסויים מתקיים
זהו הפלט שלי
יאפ משתנה NR שומר את כל הרשומות שהוא מקבל ולא את החלקים שפלטרנו, במידה ונרצה את מספר הרשומות שתכלס פלטרנו פשוט נוסיף לשורת התוכן שלנו מונה שהוא בעצם משתנה כלשהו כמו a++ או עם שם יותר מסביר count++ ונחליף את NR במונה שיצרנו
לא יודע מה איתכם אבל בעבר כל פתרון ב SO שמשתמש ב-
awk
היה נראה לי מסובך לאללה, מסתבר שזה כלי ממש פשוט ונח לעבודה.אז בקצרה מדובר על כלי למניפולציית טקסט שמכיל גם אפשרויות תכנות משתנים תנאים לולאות וכו'
ישנן 2 צורות עבודה עם
awk
, אחת היא להעביר לטרמינל מחרוזת שמכילה פקודות awk
והשניה היא לכתוב את הפקודות בקובץ ולהעביר את הקובץ לפקודת awk
.תוכן לפקודת
awk
יכול לעבור גם בשרשור וגם על ידי העברת קובץ.$ awk -f myawk.txt any_fileנתחיל
$ echo “any text here” | awk -f myawk.txt
פקודת
awk
מאפשרת להכניס תוכן בתחילת ובסוף תהליך הפרסור של הטקסט, למשל אם נרצה ליצור טבלה שמציגה כותרות בשורה הראשונה וסיכום התוצאות בשורה האחרונה $ echo any text here | awk 'BEGIN {print "Title" }אז מה שהיה לנו כאן היה די פשוט
pipe quote> END {print "\nTotal: ", NR}'
Title
======
======
Total 1
BEGIN
ו-END
אלו משפטי ההוראה איפה לכתוב ואז יש בלוק של { print "text" }
שאומר מה להדפיס או איזה פעולה לבצע באותו מקום, משתנה NR
מחזיק את מספר הרשומות שפקודת awk
קיבלה לעבד מה שיוצר לנו סיכום נחמד בסוף הפלט, כמו שאתם רואים עטפתי את את משפטי ההוראה בגרש בודד, הוראות שנכתבים לקובץ אינן צריכות להיות מגורגשות, פשוט וקל יאללה בואו נכניס קצת תוכן משמעותי יותר.$ cat /etc/passwdכפי שבטח הבחנתם כמו בסקריפטינג כל מילה (field) מקבלת איבר משלה שמיוצג על ידי $, בחרנו באיבר הראשון והשישי של כל שורה על ידי
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
…
$ awk 'BEGIN {FS=":" ; print "Users\n======" }
pipe quote> { print $1, $6}
pipe quote> END {print "======\nTotal:" NR}' /etc/passwd
Users
======
root /root
daemon /usr/sbin
...
======
Total:46
$1, $6,
וכן כמו בבאש ברירת מחדל התו שמוגדר לחלוקה של מילים לפרמטרים הוא רווח, בשביל להגדיר תו אחר יש את משתנה FS
שכפי שרואים מוגדר בשורה הראשונה לחלק על פי תו ":"
, אפשר להכניס יותר מהוראה אחת בכל סוגריים על ידי נקודה פסיק.ניתן להשתמש בפקודת printf כדי לעצב טקסט בצורה חכמה יותר.
$ awk 'BEGIN {FS=":";print "Title\n====="}לסנן פלט
pipe quote> { printf "%-20s %s \n" ,$1, $6 }
pipe quote> END {print "======\nTotal:" NR}' /etc/passwd
Title
======
root /root
daemon /usr/sbin
...
======
Total:46
טוב קבלתי את רשימת כל המשתמשים אבל חלקם בכלל לא משתמשים אלא שירותים במערכת, awk מאפשרת לנו להדפיס על עוד תנאי מסויים מתקיים
$ awk 'BEGIN {FS=":";print "Users\n===="}
pipe quote>
$3 > 999 { printf "%-20s %s \n" ,$1, $6}
pipe quote>
END {print "====\nTotal:" NR}' /etc/passwd
אז מה היה פה, לפני השורה שמציגה את התוכן שמתי תנאי שאומרת תדפיס את התוכן רק אם הערך של משתנה $3 גדול מ 999, למי שלא מכיר ברוב מערכות הלינוקס משתמשים מקבלים id שמתחיל מ1000, שאר שירותי המערכת מקבלים id מ 999 ומטהזהו הפלט שלי
Usersרגע מה, 46 רשומות???
======
green /home/green
someone /home/someone
======
Total:46
יאפ משתנה NR שומר את כל הרשומות שהוא מקבל ולא את החלקים שפלטרנו, במידה ונרצה את מספר הרשומות שתכלס פלטרנו פשוט נוסיף לשורת התוכן שלנו מונה שהוא בעצם משתנה כלשהו כמו a++ או עם שם יותר מסביר count++ ונחליף את NR במונה שיצרנו
$ awk 'BEGIN {FS=":";print "Users\n===="}
pipe quote>
$3 > 999 { printf "%-20s %s \n" ,$1, $6 ; count++}
pipe quote>
END {print "====\nTotal:" count}' /etc/passwd
Users@bash_tips
====
green /home/green
someone /home/someone
====
Total:2
Forwarded from HackTips
טיפ #7 - פקודות רצות אחרי סגירת ssh
לכל מי שלא הכיר, אם אתם בssh ולא רוצים שהפקודה שלכם תיסגר אם אתם פתאום מתנתקים (אינטרנט לדוג)
יש כמה דרכים להתמודד עם זה
1. תוכנות terminal multiplexerx
לדוג tmux או screen שעובדים בתצורת לקוח שרת, שאתה מדבר איתו דרך unix socket שנפתח בדרכ ב/run מאפשר לך בקליינט לפתוח כל מיני פקודות, תוכנות שבפועל רצות ב"שרת". בtmux הצירוף ctrl-b ואז d יאפשר לכם לעשות detach לסשן הנוכחי, ואז אפשר לחזור אליו עם tmux attach
2. סיגנל nohup עם &
אתם יכולים להתחיל פקודות עם nohup כדי לדרוס את סיגנל הhup, שזה סיגנל שנשלח לתהליכים כאשר הטרמינל שלהם (pty, tty) נסגר (כולל חיבור ssh)
ה& אומר לbash שמפרסר את האופרטור בתור "תריץ אסינכרוני, תריץ בshell אחר שהוא fork שלי"
3. שיטת job disown
נגיד והפקודה שלכם כבר רצה ואנחנו לא רוצים לעצור אותה, אפשר לדפוק ctrl z כדי להעביר אותה לתור הjobs, משם היא עוצרת, אז נמשיך את הריצה שלה עם bg, עכשיו היא רצה והטרמינל שלנו פתאום חופשי - מפה, נכתוב disown. זה bash builtin (לא תוכנה שנמצאת במקום כמו /usr/bin, אלא פקודה שממומשת בתוך המפרש של bash) שמאפשרת לבאש להסיר את הjobs ששייכים לו ומעכשיו הם יהיו תהליכים לגיטימיים. שימו לב שזה *לא* אותו הדבר כמו nohup, אתה לא משתיק סיגנל סגירת טרמינל ועושה fork לshell-ילד, הjob אחרי הdisown עדיין מכיל טבלת file descriptors של stdin stdout stderr שהם symlinkים לזרמים של... הטרמינל שעשה להם disown. אם התוכנה שלכם מתישהו תנסה לקרוא, לכתוב או אפילו להתלונן על שגיאות למסך - היא עלולה לקרוס. אפשר לטפל בזה מראש ע"י steam redirect לdev null, אבל זה קצת פוגע בפואנטה הרי לא יכלנו לחשוב על זה מראש באופציה 3. ראו הוזהרתם!
לסיום, חידה מגניבה - איך זה שכאשר אתם מרסטים את הsshd, חיבור הssh שלכם עדיין נשאר עובד? מוזמנים לחקור על זה, מבטיח שהתשובה מגניבה! :)
לכל מי שלא הכיר, אם אתם בssh ולא רוצים שהפקודה שלכם תיסגר אם אתם פתאום מתנתקים (אינטרנט לדוג)
יש כמה דרכים להתמודד עם זה
1. תוכנות terminal multiplexerx
לדוג tmux או screen שעובדים בתצורת לקוח שרת, שאתה מדבר איתו דרך unix socket שנפתח בדרכ ב/run מאפשר לך בקליינט לפתוח כל מיני פקודות, תוכנות שבפועל רצות ב"שרת". בtmux הצירוף ctrl-b ואז d יאפשר לכם לעשות detach לסשן הנוכחי, ואז אפשר לחזור אליו עם tmux attach
2. סיגנל nohup עם &
אתם יכולים להתחיל פקודות עם nohup כדי לדרוס את סיגנל הhup, שזה סיגנל שנשלח לתהליכים כאשר הטרמינל שלהם (pty, tty) נסגר (כולל חיבור ssh)
ה& אומר לbash שמפרסר את האופרטור בתור "תריץ אסינכרוני, תריץ בshell אחר שהוא fork שלי"
3. שיטת job disown
נגיד והפקודה שלכם כבר רצה ואנחנו לא רוצים לעצור אותה, אפשר לדפוק ctrl z כדי להעביר אותה לתור הjobs, משם היא עוצרת, אז נמשיך את הריצה שלה עם bg, עכשיו היא רצה והטרמינל שלנו פתאום חופשי - מפה, נכתוב disown. זה bash builtin (לא תוכנה שנמצאת במקום כמו /usr/bin, אלא פקודה שממומשת בתוך המפרש של bash) שמאפשרת לבאש להסיר את הjobs ששייכים לו ומעכשיו הם יהיו תהליכים לגיטימיים. שימו לב שזה *לא* אותו הדבר כמו nohup, אתה לא משתיק סיגנל סגירת טרמינל ועושה fork לshell-ילד, הjob אחרי הdisown עדיין מכיל טבלת file descriptors של stdin stdout stderr שהם symlinkים לזרמים של... הטרמינל שעשה להם disown. אם התוכנה שלכם מתישהו תנסה לקרוא, לכתוב או אפילו להתלונן על שגיאות למסך - היא עלולה לקרוס. אפשר לטפל בזה מראש ע"י steam redirect לdev null, אבל זה קצת פוגע בפואנטה הרי לא יכלנו לחשוב על זה מראש באופציה 3. ראו הוזהרתם!
לסיום, חידה מגניבה - איך זה שכאשר אתם מרסטים את הsshd, חיבור הssh שלכם עדיין נשאר עובד? מוזמנים לחקור על זה, מבטיח שהתשובה מגניבה! :)
שפת הסקריפט awk
אחרי ראינו את העקרונות והמבנה הכללי של awk הנה עוד כמה דברים נחמדים שאפשר לעשות
נגטיב
בצורה זו אפשרי ליצור כלים הרבה יותר גמישים
הנה עוד כמה מעניינים שכדאי להכיר
להלן חלקם
I/O
תנאים: רגילים / ternary
לולאות: switch / for / while / do while
@bash_tips
אחרי ראינו את העקרונות והמבנה הכללי של awk הנה עוד כמה דברים נחמדים שאפשר לעשות
נגטיב
$ cat test.awk
!(/Never logged in/) { print $1 }
$ lastlog | awk -f test.awk
Username
someone
רגע יש שם בפלט Username שאינו משתמש במערכת אלא רק כותרת של הפקודה, בא נוסיף חוק שיסיר גם אותו.!(/Never logged in/ || /^Username/) { print $1 }
להשתמש בתוכן דינמי על ידי משתניםבצורה זו אפשרי ליצור כלים הרבה יותר גמישים
$ cat test.awk
BEGIN {print var_a, var_b}
$ awk -f test.awk -v var_a=Username -v var_b=Login
Username Login
יש לא מעט משתני סביבה ל awk ראינו בפוסטים הקודמים את NR ואת FSהנה עוד כמה מעניינים שכדאי להכיר
OFMT - The output format for numbers,
"%.6g", by default.
OFS - The output field separator,
a space by default.
ORS - The output record separator,
by default a newline.
NF - The number of fields in the current input record.
FIELDWIDTHS:
A whitespace-separated list of field widths.
ENVIRON:
An array of the environment variables.
FILENAME:
The name of the current input file.
p.s. filename is undefined inside the BEGIN rule (unless set by getline).
בשביל שיהיה ממש נחמד יש גם פונקציות מובנות להלן חלקם
I/O
printf - Format and print.
system("cmd") - Execute the command cmd-line,
and return the exit status.
Numeric Functionsint(expr) | atan2(y, x) | sin(x) | cos(x) | sqrt(x) | exp(x) | log(x) | rand()
String Functionslength(s) | toupper(s) | tolower(s) | substr(s, i) | strtonum(s) |match(s, rgx) | index(s, t)
שאר ממתקים שיעבדו לכם כמו כל שפת תכנות C Likeתנאים: רגילים / ternary
לולאות: switch / for / while / do while
@bash_tips
להוריד עם חשבון
בשביל שזה באמת יקרה ניתן להריץ את
wget
לעיתים אנו רוצים להוריד קבצים אבל אין לנו מושג בדיוק כמה, אז להוריד קבצים אנו יודעים איך $ wget https://somehost/1.mp3וכשאנו רוצים להוריד רצף קבצים אנו גם יודעים איך
$ wget https://somehost/{1..100}.mp3הבעיה מתחילה כשאנו לא יודעים כמה קבצים אנו בדיוק רוצים להוריד, אנו בעצם מעוניינים שברגע שחוזרת שגיאה של 404 אז
wget
יפסיק את ההורדה.בשביל שזה באמת יקרה ניתן להריץ את
wget
עם תנאי שברגע שהוא נכשל שיצא מהתוכנית$ wget https://somehost/{1..100}.mp3 || exit@bash_tips
לקרוא json עם
עולם האינטרנט מתקשר לא מעט דרך אובייקטי json בכדי שנוכן לעבוד בקלות גם בעולם הזה כדאי שיהיה לנו כלי שדובר את השפה, למזלנו יש כלי ממש חזק בסביבת ה shell שנותן לבצע מניפולציות ופרסור של json נעים להכיר
כלי
הקובץ שלי מכיל מערך בודד עם 3 אובייקטים
בדומה ל-
כדי לקבל את רשימת האובייקטים המחרוזת שלי ל-
בשביל לקבל את התוכן שאני רוצה פשוט אוסיף את שם הkey הספציפי במקרה שלנו
ניתן לבחור מספר keys על ידי שימוש בפסיק
אני רוצה שמתחת לכל שם יופיע גם הגיל
סינון
ניקח את זה שלב אחד קדימה, אני רוצה רק את האובייקטים של מי שמבוגר מ-20
בשביל כך יש את פונקציית select שמאפשרת לנו להגדיר תנאי על פיו יסונן התוכן
לדוגמה
אתגרון לסיום
איזה משפט ישלוף לי את כל רשימות ההשמעה מהלינק הבא?
jq
ואתגרון בקצהעולם האינטרנט מתקשר לא מעט דרך אובייקטי json בכדי שנוכן לעבוד בקלות גם בעולם הזה כדאי שיהיה לנו כלי שדובר את השפה, למזלנו יש כלי ממש חזק בסביבת ה shell שנותן לבצע מניפולציות ופרסור של json נעים להכיר
jq
.כלי
jq
מנסה להיות מה שawk
לטקסט רק בצורה טובה ואינטואיטיבית יותר, עוד לא החלטתי כמה זה הצליח להם אבל אחרי תרגול קל דברים נראים הגיוניים, יאללה לעבודההקובץ שלי מכיל מערך בודד עם 3 אובייקטים
$ cat my.jsonאני מעוניין לשלוף את שמות האנשים עם
[
{"name":"John", "age":31, "city":"New York"},
{"name":"Smith", "age":13, "city":"Bnei Brak"},
{"name":"Joe", "age":21, "city":"Honolulu"}
]
jq
זה יראה כך$ cat my.json | jq ' .[].name 'הסבר
"John"
"Smith"
"Joe"
בדומה ל-
awk
גם jq
מקבל את הפקודות שלו בתור מחרוזת (או בתור קובץ נפרד)כדי לקבל את רשימת האובייקטים המחרוזת שלי ל-
jq
היא '.[]'
שהמשמעות שלה זה תביא בבקשה את כל האובייקטים שקיימים למערך הנוכחי, באותה מידה אוכל להכניס טווח של אובייקטים (.[1:42]
) או מספר ספציפי של אובייקט (.[42]
)בשביל לקבל את התוכן שאני רוצה פשוט אוסיף את שם הkey הספציפי במקרה שלנו
.name
כעת jq
יעבור באיטרציה על כל האובייקטים וישלוף את הערך של .name
בחירה של מספר keysניתן לבחור מספר keys על ידי שימוש בפסיק
$ cat my.json | jq '.[].name, .[].age'בעיה, עכשיו אני לא יודע איזה גיל שייך לאיזה שם
"John"
"Smith"
"Joe"
31
13
21
אני רוצה שמתחת לכל שם יופיע גם הגיל
$ cat my.json | jq '.[] | .name, .age'בדומה ל-bash גם jq לקחו את הגישה של שרשור פלט מפקודה אחת לפקודה שניה עם
"John"
31
"Smith"
13
"Joe"
21
|
, בפעולה הראשונה בפקודה jq שולף את כל האובייקטים ומעביר אותם להמשך תהליך שם אנו בוחרים רק keys ספציפים מכל האובייקטים שהועברוסינון
ניקח את זה שלב אחד קדימה, אני רוצה רק את האובייקטים של מי שמבוגר מ-20
בשביל כך יש את פונקציית select שמאפשרת לנו להגדיר תנאי על פיו יסונן התוכן
לדוגמה
$ cat my.json | jq '.[] | select(.age >= 20) '@bash_tips
{
"name": "John",
"age": 31,
"city": "New York"
}
{
"name": "Joe",
"age": 21,
"city": "Honolulu"
}
אתגרון לסיום
איזה משפט ישלוף לי את כל רשימות ההשמעה מהלינק הבא?
https://eco99fm.maariv.co.il/api/v1/public/playlist/12033תשובות לתגובות
Forwarded from $~deb
tee
זהו כלי שנמצא ברוב ההפצות כחלק מהמערכת
הפקודה משמשת לכתיבה למספר קבצים בנוסף לפלט הרגיל.
איך משתמשים?
echo "hi" | tee file1 file2 file1000
וכמובן אפשר להשתמש בwildcard כדי לכתוב למספר קבצים עם אותו סייומת
echo 'print("hi")' | tee {file1,file2}.py
זהו כלי שנמצא ברוב ההפצות כחלק מהמערכת
הפקודה משמשת לכתיבה למספר קבצים בנוסף לפלט הרגיל.
איך משתמשים?
echo "hi" | tee file1 file2 file1000
וכמובן אפשר להשתמש בwildcard כדי לכתוב למספר קבצים עם אותו סייומת
echo 'print("hi")' | tee {file1,file2}.py
אמת או שקר
ניתן לבצע מספר רב של תנאים בבאש החל מקיומם של קבצים סוגים וכו', דבר שצריך לקחת בחשבון הוא שבאש מבצעת השוואות רק על מחרוזות ומספרים
בואו נראה דוגמה
עד כאן זה בערך מה שתקראו בכל מקום בקשר לבוליאנים בבאש.
יצא לי להיתקל בסוף השרשור הזה בטיפ הבא שמראה שאפשר לעבוד עם בוליאנים בצורה פשוטה כמו בשאר השפות, זה נראה כך
ניתן לבצע מספר רב של תנאים בבאש החל מקיומם של קבצים סוגים וכו', דבר שצריך לקחת בחשבון הוא שבאש מבצעת השוואות רק על מחרוזות ומספרים
בואו נראה דוגמה
$ bool=true
$ declare -p bool
declare -- bool="true"
כפי שאפשר לראות משתנה bool מסומן עם ערך — שזה מקביל לשום ערך מיוחד, מה שמאפיין מחרוזות מה שאומר שהתנאי הבא לא יוכל להתקיים כי ערך של מחרוזת הוא תמיד trueif [[ $bool ]];
then echo print true
fi
print true
$ bool=false
if [[ $bool ]];
then echo print true
fi
print true
בשביל להשוות בוליאן ההשוואה תצטרך להיות או מספרית או של מחרוזת.עד כאן זה בערך מה שתקראו בכל מקום בקשר לבוליאנים בבאש.
יצא לי להיתקל בסוף השרשור הזה בטיפ הבא שמראה שאפשר לעבוד עם בוליאנים בצורה פשוטה כמו בשאר השפות, זה נראה כך
$ bool=true
$ if ${bool};
> then echo some text here
> fi
some text here
וכמובן תנאי שלילי שלא יציג כלום$ bool=false
$ if ${bool};
> then echo some text here
>fi
@bash_tipsלצמצם עם
עד כאן הכל נחמד, מה אם אני רוצה לחתוך שיר למשקל מוגדר מראש?
#truncate
#cat
#du
@bash_tips
truncate
רמת קושי: #beginners
פקודת truncate
מאפשרת לנו להגדיר משקל מוגדר לכל קובץ, אם לגומה יש לי לוג ששוקל 10MB ואני רוצה לשמור רק את 2 MB החדשים ביותר של הלוג$ du -h myapp.log
10M myapp.log
$ truncate --size=2M myapp.log
$ du -h myapp.log
2.0M myapp.log
בעצם מה שקרה הוא שכל החלק הישן יותר של הקובץ נזרק לפח ונשארתי רק עם הרשומות החדשות ביותר.עד כאן הכל נחמד, מה אם אני רוצה לחתוך שיר למשקל מוגדר מראש?
$ cat long_song.mp3 > shrink.mp3
$ du -h shrink.mp3
15M shrink.mp3
$ truncate --size=2M shrink.mp3
$ du -h shrink.mp3
2.0M shrink.mp3
#truncate
#cat
#du
@bash_tips
רצפים ופורמטים עם
רמת קושי: #beginners
כפי שאנו מכירים באש מאפשרת ליצור רצפים של מספרים על ידי שימוש ב Brace expansion (הביטוי שמתאר את הפעולה הבאה
נעים להכיר
פקודה חביבה נוספת שמאפשרת ליצור רצפים היא seq, השימוש בה קל וכל שצריך הוא פשוט להעביר ערכים של התחלה וסוף ומקבלים רצף
יאפ, הפקודה מאפשרת ליצור רצפים בדילוג
seq
רמת קושי: #beginners
כפי שאנו מכירים באש מאפשרת ליצור רצפים של מספרים על ידי שימוש ב Brace expansion (הביטוי שמתאר את הפעולה הבאה
{10..1}
) וזה עובד יפה מאוד כשמשתמשים בזה עם מספריםcat myscript.sh
for i in {1..10}; do
echo $i
done
$ bash myscript.sh
1
2
3
...
הבעיות מתחילות כשרוצים שהקוד יהיה קצת יותר דינמי ומחליטים במקום להכניס מספרים בצורה ישירה להכניס משתנים שיכילו את ההתחלה והסוף, אם כן הכירו את המשתנים שלנו start וend$ cat myscript.sh
start=1
end=10
for i in {$start..$end}; do
echo $i
done
$ bash myscript.sh
{1..10}
הופההה בעיה, במקום שבאש תפרש את הערכים ששמנו בסוגריים המסולסלות כביטוי שיש לחולל, באש מתייחסת לביטוי כמחרוזת ולכן משתנה i פשוט מדפיס את המחרוזת.נעים להכיר
seq
פקודה חביבה נוספת שמאפשרת ליצור רצפים היא seq, השימוש בה קל וכל שצריך הוא פשוט להעביר ערכים של התחלה וסוף ומקבלים רצף
$ cat myscript.sh
start=1
end=10
for i in $(seq $start $end); do
echo $i
done
$ bash myscript.sh
1
2
3
...
נשמע אחלה מעולה, אפשר מזה עוד?יאפ, הפקודה מאפשרת ליצור רצפים בדילוג
$ seq 0 2 20
0
2
4
6
ודבר נחמד עוד יותר שהיא מאפשרת זה למלא אפסים לפני מספרים קטנים, וכך חסכנו את הצורך להשתמש ב printf
כדי לפרמט רצף כרונולוגי$ seq -w 100
001
002
003
...
010
011
012
...
099
100
#seq
#brace_expansion
@bash_tipsמעקב אחר שינויים במספר קבצים בזמן אמת עם
צפייה בקבצים מרובים
פקודת
tail
רמת קושי: #beginners
קבצי לוג מכילים מספר נאה מאוד של רשומות ובדרך כלל הרשומות הרלוונטיות הן בסוף הקובץ, בשביל להקל על החיים נולדה פקודת tail
שמאפשרת לצפות ב 10 שורות האחרונות של הקובץ $ tail blender_collector.sh
blend_dest=$(readlink -m "$dest/${file_name%.*}/")
mkdir -p "$blend_dest"
mv "$BLEND_FILES" "$blend_dest"
Organize_files
done
echo "Finished, files exist in: $dest"
ניתן כמובן לשנות את כמות השורות שהפקודה תדפיס על ידי השמת ערך מספרי לדגל n-
דבר נחמד שהכלי מאפשר הוא צפייה זמן אמת של שינויים בקובץ על ידי שימוש בדגל f-
בדומה לפקודת journalctl
שראינו בעברצפייה בקבצים מרובים
פקודת
tail
מאפשרת מעקב בזמן אמת אחרי שינויים במספר קבצים בו זמנית, אפשרי להעביר מספר שמות קבצים לפקודה או להשתמש ב wildcard $ tail -f *
==> blender_collector.sh <==
blend_dest=$(readlink -m "$dest/${file_name%.*}/")
mkdir -p "$blend_dest"
blender -b "$BLEND_FILES" --python-expr "import bpy; bpy.ops.file.pack_all()" > /dev/null 2>&1
mv "$BLEND_FILES" "$blend_dest"
Organize_files
done
echo "Finished, files exist in: $dest"
exit 0
==> README.md <==
├── House(Texturing).blend
└── textures
├── 1725 Sun Clouds.jpg
├── studio024.hdr
├── style_cottage_Flanagan_IMG1.jpg
├── wood06.jpg
├── WoodFine0024_M.jpg
└── WoodFine0042_5_L.jpg
#tail
#journalctl
@bash_tipsלקבל קלט מהמשתמש עם
רמת קושי: #beginners
פקודת read היא פקודה המאפשרת בזמן שהסקריפט רץ לקבל קלט מהמשתמש, מה שבעצם הופך את הסקריפט לאינטרקטיבי
הקוד הבא ימתין 30 שניות לקלט ובמידה והוא לא יקבל הוא ימשיך הלאה
read
רמת קושי: #beginners
פקודת read היא פקודה המאפשרת בזמן שהסקריפט רץ לקבל קלט מהמשתמש, מה שבעצם הופך את הסקריפט לאינטרקטיבי
$ cat test.sh
echo "Insert text here"
read myvar
echo "#### $myvar ####"
$ bash test.sh
Insert text here
GOD
#### GOD ####
אפשרי לכתוב את אותו הקוד בצורה קצרה יותר על ידי שימוש בדגל -p של פקודת read$ cat test.sh
read -p "Insert text here " myvar
echo "#### $myvar ####"
$ bash test.sh
Insert text here GOD
#### GOD ####
עוד מהדברים הנחמדים שהפקודה מאפשרת היא להמתין זמן מוגדר לקלט מהמשתמש, ברגע שעובר הזמן הפקודה תמשיך הלאה והמשתנה ישאר ריקהקוד הבא ימתין 30 שניות לקלט ובמידה והוא לא יקבל הוא ימשיך הלאה
$ cat test.sh
read -t 30 -p "press any key to continue (or wait)" myvar
echo "#### $myvar ####"
#read
@bash_tips