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

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

בלא מעט מערכות יש כלי שורת הפקודה שמאפשר להעתיק פלט בטרמינל ישירות לתוך ה clipboard.
בווינדוס למשל ניתן להשתמש ב clip

c:\> dir | clip 

ובמאק יש את פקודת pbcopy

$ echo bla bla bla | pbcopy

מה קורה אם כך בלינוקס?
משתמשי זיש יכולים להשתמש בפקודת clipcopy

$ cat ~/.ssh/id_rsa.pub| clipcopy

משתמשי באש לעומת זאת שרוצים לממש יכולת דומה צריכים להגדיר את ה alias הבא (שזה אגב בדיוק מה שעושה זיש)

$ alias clipcopy="xclip -selection clipboard"

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

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

$ alias clipcopy="tee >(xclip -selection clipboard)"

נ.ב. בכל מה שקשור ללינוקס ישנה תלות של כלי xclip שצריך להיות מותקן במערכת


#copy
#xclip
#clipboard

@bash_tips
לטעון סביבה
רמת קושי: #advanced

קובץ שמוכר בעולם ה ops הוא .env מדובר על קובץ שבגדול מכיל רשימה של משתני סביבה בהם הסביבה מאותחלת, מספר כלים כדוגמת docker-compose מכירים בקובץ ויודעים לטעון אותו לבד, מה קורה כשאנו רוצים לטעון קובץ .env ישירות לטרמינל?

דוגמה לקובץ .env

$ cat .env
APP_NAME=mytest
DEPLOYMENT_MODE=true
BUNDLE=test
...

מחשבה ראשונה זה לעשות source לקובץ ולטעון אותו, העניין הוא שהכרזת משתנים בלי הפקודה export תטען את המשתנים לסשן של הטרמינל, כל סקריפט שנריץ מאותו הסשן לא יקבל את המשתנים שבקובץ כי הוא רץ בסשן משל עצמו (דברנו על זה מעט בעבר).

נוכל לראות זאת בדוגמה שלהלן

$ source .env

$ cat test.sh
#!/bin/bash
declare -p APP_NAME DEPLOYMENT_MODE BUNDLE

$ bash test.sh
test.sh: line 2: declare: APP_NAME: not found
test.sh: line 2: declare: DEPLOYMENT_MODE: not found
test.sh: line 2: declare: BUNDLE: not found


להלן 2 דרכים מעניינות לפתרון
פתרון אפשרי, export

export $(grep -v '^#' .env)

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


פתרון אפשרי נוסף allexport

set -a
source .env
set +a


בגדול מדובר על הפעלה של flag allexport, האופציה הזאת מעבירה לexport את רצף המשתנים ובעצם מאפשרת לפקודת source לטעון את כל המידע שבקובץ, אנו מכבים את האופציה לאחר שטענו את הסביבה.

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


#env
#export
#source
#variable
#env_variable
#session

@bash_tips
לקפוץ מעל jumpbox

בלא מעט מערכות יש נוהל אבטחה שאין גישת ssh ישירה לשרת, אלא יש מכונה אחת שמורשת להתחבר לשרת ב ssh וכל מי שרוצה להתחבר לשרת צריך לעבור דרך המכונה הזאת, המושג הזה ברשת מוכר בשם מכונת jumpbox

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

1. העתקה של המפתח הציבורי שלנו למכונת ה jumpbox
2. העתקת מפתח של מכונת ה jumpbox לשרת אליו אנו רוצים להתחבר

ואז לבצע את אותה הדרך עם חיבורי ssh
התחברות ssh לשרת ה jumpbox
התחברות נוספת משרת הjumpbox לשרת

נשמע ארוך לא?

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

ssh -J myuser@jumpbox myuser@isolated.server

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

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

#ssh
#jumpbox

@learnlinuxnote
להטמיע בינרי בסקריפט באש
רמת קושי: #advanced

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

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

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

$ cat -n /tmp/installer.sh
1 #!bin/bash
2
3 binary_content=$(awk '/^ARCHIVE_HERE/ {print FNR + 1}' $0)
4
5 tail -n+$binary_content $0 | base64 -d | tar -ztv
6
7 exit 0
8
9 ARCHIVE_HERE
10


מה שקורה כאן הוא כך
שורה 3: עוברת על כל הסקריפט ומחפשת את העוגן שהגדרנו, במקרה שלנו העוגן נמצא בשורה 9, ARCHIVE_HERE, למי שלא מכיר פרמטר $0 הוא בעצם שם הסקריפט

שורה 5: לאחר שאנו יודעים מאיזה שורה מתחיל התוכן הבינרי, אנו שומרים רק את התוכן הבינרי לתוך משתנה, הדבר נעשה על ידי פקודת tail שקוראת תוכן מסוף הקובץ ומקבלת שורה ספציפית מהיכן לקרוא, התוכן עובר ל base64 במקרה שלנו ולכן נקודד אותו חזרה לתוכן רגיל, פקודת tar תציג לנו את המידע שהוטמע בפנים

שורה 9: זהו העוגן שהגדרנו

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


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

$ tar -tvf installer.tar
installer/
installer/req_list
installer/installer.db
installer/execfile


ניתן להשתמש ב cat כדי לשפוך את התוכן הבינרי לקובץ אבל ישנם המון מקומות בהן התוכן עשוי להשתנות ולא להישאר נאמן למקור לכן נעדיף לעבוד עם base64

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

9 ARCHIVE_HERE
10


כעת מהטרמיל אנו מקודדים את הקובץ לbase64, ומשרשרים את הפלט לסוף הסקריפט זה נראה כך

$ base64 installer.tar >> installer.sh

אנו משתמשים באופרטור >> כדי להוסיף את התוכן לסוף הקובץ ולכן השורה הריקה שהשארנו מקודם תתמלא בתוכן החדש

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

$ bash installer.sh
installer/
installer/req_list
installer/installer.db
installer/execfile


ניתן כמובן לשנות את שורה 5 וליצור קובץ ישירות מהתוכן שיוצר השחזור של ה base64

#tar
#binary
#base46
#scripting

@bash_tips
installer.sh
415 B
להלן הסקריפט המלא עם התוכן הבינרי
טיפ קצר וחביב להתנהלות בטרמינל
רמת קושי: #beginners

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

לשם כך ישנו הקיצור Alt + Shift + # שכל מה שהוא עושה זה לקחת את הפקודה שרשמנו ולהריץ אותו כהערה כך שלאחר מכן ניתן יהיה לשלוף את ההערה מההיסטוריה ולהריץ אותה כפקודה.


#terminal
#shortcuts
#comments

@bash_tips
יותר less
רמת קושי: #beginners

פקודת less מאפשרת להדפיס קבצים למסך, זהו בערך השימוש הבסיסי שכולם מכירים, מה שלא ממש מכירים אלו הפיצ'רים הנוספים שהכלי מביא איתו

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

הקשה על !ls יריץ את הפקודה בטרמינל ויחזיר אותנו חזרה לקובץ שפתוח ב less


מומלץ להריץ less --help כדי להכיר אלו עוד אפשרויות ופיצ'רים הכלי מאפשר


תודה לליאור קיסוס האלוף על הטיפ


#less
#vim

@bash_tips
איך לכתוב באש ומתי
רמת קושי: #beginners

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

לדוגמה

# Use this

if (( my_var > 3 )); then
do_something
fi

if [[ "${my_var}" -gt 3 ]]; then
do_something
fi


# Instead of this
# Probably unintended lexicographical comparison.
if [[ "${my_var}" > 3 ]]; then
# True for 4, false for 22.
do_something
fi


הדף מופיע כחלק מפרויקט רחב יותר של גוגל בשם Google Style Guides שם תוכלו למצוא עוד המון הערות בקשר לשפות אחרות כמו go, python, c וכו'


#shellguide
#scripting
#rules

@bash_tips
לחלק נכון, awk
רמת קושי: #beginners

לא מעט פעמים אנו נדרשים לקבל פלט ולהוציא ממנו את החלק שרלוונטי אלינו, לצורך העניין הקלט שאנו מנסים לפרסר הוא זה, ואנו רוצים לקבל את העמודה השניה.
$ cat output

one two three
one two three
one two three

הפתרון לבעיה הזאת הוא להשתמש ב cut עליו דיברנו בעבר
הפקודה שלנו תראה משהו כזה כשדגל -d מפצל לפי רווחים ו -f בוחר את מספר "העמודה"

$ cat output | cut -d " " -f2
two
two
two
אחלה, עובד מעולה

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

docker ps | cut -d " " -f 2

במקום לקבל את הפלט של כל סוגי האימג'ים ששל הקונטיינרים מה שנקבל במקום זה את הרווח שלאחר מכן

איך כן?
בכדי לפתור את הבעיה הזאת יהיה קל יותר להשתמש ב awk כדי לפצל פלט

docker ps | awk '{print $2}'

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


#cut
#awk

@bash_tips
לשרשר ולספור PIPESTATUS
רמת קושי: #beginners

הזכרנו בעבר ששימוש ב pipe מתסיר את הקוד יציאה של הפקודה שרצה לפני הpipe
לדוגמה הפקודה הבאה תחזיר קוד יציאה 0 למרות שהפקודה הראשונה נכשלה

$ ls /not/exist/path | echo 123
123
ls: cannot access '/not/exist/path': No such file or directory

$ echo $?
0

בכדי לקבל את הקוד יציאה של כל פקודה שהורצה ב pipe ניתן להשתמש במשתנה הסביבה PIPESTATUS, מדובר על משתנה סביבה מסוג מערך שמכיל קוד יציאה של כל פקודה שהורצה ב pipe

$ ls /not/exist/path | echo 123 | grep -o 2 
ls: cannot access '/not/exist/path': No such file or directory
2

$ declare -p PIPESTATUS
declare -a PIPESTATUS=([0]="2" [1]="0" [2]="0")

ניתן לראות אם כן שבעוד ששני הפקודות האחרונות יצאו בקוד 0, הפקודה הראשונה שנכשלה יצאה בקוד שגיאה


#pipe
#env_variable
#exit_code

@bash_tips
אוטומציה ל telnet
רמת קושי: #advanced

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

$ telnet localhost 25 
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 My Mail Server

התחברנו לשרת ה SMTP דרך telnet ומשלב זה שורת הפקודה (עדין telnet) ממתינה שנשלח פקודות לשירות אליו התחברנו, במקרה שלנו פקודות לשירות SMTP עד שנעביר את הפקודה quit שתסגור את החיבור.

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

יש 2 דרכים עיקריים לביצוע אוטומציה ל telnet
הראשונה היא על ידי כלי אוטומציה של באש בשם expect עליו לא נדבר היום
האופציה השניה היא על ידי העברת ערכים ל stdin של telnet

echo "ehlo test" | telnet localhost 25

להלן דוגמה לסקריפט ששולח מייל על ידי telnet

{
echo "ehlo test"
sleep 1
echo "mail from:meir@any.domain"
echo "rcpt to:fpk1ezqg@my.domain"
echo "data"
sleep 1
echo "subject: bla bla bla"
echo "more bla bla bla"
echo "."
sleep 1
echo "quit"
} | telnet localhost 25

בדוגמה אנו משתמשים ביכולת group command של באש כדי לחסוך כתיבה של תווי \n שנדרשים ל telnet.
כפי שניתן לראות הקוד משתמש ב sleep כדי לצלוח את המשימה, מאחר וכל הקוד מגיע כבלוק אחד של טקסט נדרש לשירות זמן להגיב לפקודות אותם הוא קיבל


#telnet
#scripting

@bash_tips
לעשות פיל מזבוב fallocate
רמת קושי: #advanced

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

$ fallocate -l 500G fill_half_disk.img

בכדי ליצור קובץ בגודל מסויים אנו משתמשים בדגל -l ומעבירים לו ערך בפורמט K M G וכו' כש 50G הם בעצם 50 ג'יגה בייט

$ du -h fill_half_disk.img 
500.1G fill_half_disk.img


#disk
#fallocate

@bash_tips
לסדר ולהשוות כמו בן אדם sort
רמת קושי: #beginners

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

$ {
echo 2
echo 3
echo 0
} | sort

והפלט

0
2
3

להלן 2 דברים חביבים ממש שהפקודה מאפשרת

פילטור בשפה של בני אדם
לפלטר לפי מספרים או אותיות זה קל, מה קורה אם רוצים לפלטר מידע שמבוסס על נפח של קובץ / מקום?
בדומה לפקודות אחרות שימוש בדגל -h יאפשר לפלטר תוכן שמבוסס על נפח כמו K M G T P וכו' (aka human-readable)

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

$ du -h | sort -h

פילטור לפי עמודות
במידה והפלט אותו אנו רוצים לפלטר הוא טבלה אבל אנו רוצים לפלטר רק לפי עמודה מסויימת נוכל להריץ את הפקודה עם דגל -k ומספר העמודה לפיה נרצה לפלטר

$ df -h | sort -hk2

לצורך הדוגמה הסרתי את שאר הטבלה אך כעת ניתן לראות שהתוכן של פקודת df יוצג לנו מפולטר על פי העמודה השניה היא עמודת Size

Size
497M
2.7G
14G
86G
200G

למה זה חביב ממש?
כי כרגע ניתן ליצור פונקציית השוואה לפי משקל קובץ, מבלי להמיר את הערכים למספרים אלא פשוט להשוות 3M < 9G, אכן לא ככה כותבים קוד אבל היי, זה עובד.


#sort
#human_readable

@bash_tips
Bash Tips
לקבל את כל הפרמטרים עם *! בעבר כתבתי על שימוש ב $! כדי להעביר את הפרמטר האחרון שהשתמשתי בו בפקודה מסוימת לפקודה חדשה. הבעיה מתחילה כשיש רשימה של פרמטרים במידה ונריץ $! נקבל רק את הפרמטר האחרון ולא את כל רשימת הקבצים שהזנו $ touch app.js index.html internal.css…
לזכור
רמת קושי: #beginners

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

^ - בוחר את הערך ההתחלתי
$ - בוחר את הערך הסופי
* - בוחר את הכל
לדוגמה

$ echo aaa bbb ccc
aaa bbb ccc
$ echo !^
aaa
$ echo !$
ccc
$ echo !*
aaa bbb ccc


#hints

@bash_tips
ניקיון history
רמת קושי: #beginners

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

בשביל לנקות את כל ההיסטוריה של באש ישנן 2 דרכים

echo >| ~/.bash_history

או פשוט

history -c

בכדי להסיר שורות ספציפיות ניתן להריץ את פקודת history עם דגל -d

history -d 1988

או אפילו להסיר טווח של פקודות מההיסטוריה

history -d 1988-1999

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

שיוט! מחקתי את ההיסטוריה


#history

@bash_tips
This media is not supported in your browser
VIEW IN TELEGRAM
לנהל ssh
רמת קושי: #beginners

כמעט לכולנו יצא לעבוד עם ssh להתחבר ולהריץ פקודות ממכונה אחת לאחרת

$ ssh user@host 
$ ssh user@host "cat /etc/nginx/nginx.conf"

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

בכדי להגדיר חיבורים רק למשתמש ניתן להוסיף את הערך הבא לקובץ ~/.ssh/config, בכדי להוסיף הגדרות לכלל משתמשי המערכת ניתן לערוך את הקובץ /etc/ssh/ssh_config או להוסיף קובץ הגדרות תחת הנתיב /etc/ssh/ssh_config.d/

$ cat ~/.ssh/config
Host smtp-prod
HostName 10.248.13.216
User ec2-user

Host smtp-test
HostName 10.247.13.215
User ec2-user

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

$ ssh smtp-prod

נוכל להרחיב את סט ההגדרות ולהגדיר key ספציפי לכל התחברות, או אפילו להגדיר התחברות למכונה דרך מכונה אחרת (Jumpbox)
למשתמשי vscode ישנו תוסף מעולה שמנהל התחברויות ssh ומתבסס על קובץ הconfig המדובר


#ssh
#vscode

@bash_tips
ליצור היסטוריה touch
רמת קושי: #beginners

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

מה שאנו צריכים זה כלי שיאפשר לנו ליצור קובץ כאילו הקובץ נוצר כבר לפני שבוע ועליו לבצע את הניסיונות והפעולות שלנו

פקודת touch מאפשרת לנו ליצור קבצים

$ touch newfile

ומאפשרת לנו בנוסף לשנות זמן יצירה של קובץ מסויים או ליצור אותו מלכתחילה עם תאריך אחר מהזמן הנוכחי

$ touch newfile -t 01012022
$ ls -la
...
-rw-rw-r-- 1 bash_tips bash_tips 0 Jan 1 2022


כפי שניתן לראות זמן היצירה של הקובץ הוא מ01.01.2022


אחלה מעולה הכל עובד מושלם בקשר לקבצים, מה בקשר לתיקיות?

גם כאן פקודת touch באה לעזרנו למרות שהיא עובדת בעיקר על קבצים, אם ניצור תיקייה ו"ניגע" בה עם פקודת touch נוכל לשנות לה את
תאריך היצירה של התיקיה
ה mtime (התאריך האחרון בו הקובץ השתנה)
או ה atime (התאריך האחרון שמישהו ניגש לקובץ)

$ mkdir newdir
$ ls -l
...
drwxrwxr-x 2 bash_tips bash_tips 4096 Oct 31 21:11 newdir

$ touch newdir -t 01012022
$ ls -l
...
drwxrwxr-x 2 bash_tips bash_tips 4096 Jan 1 2022 newdir



#touch

@bash_tips
Forwarded from ToCode
# היום למדתי: הפקודה fc תאפשר לכם לערוך היסטוריה ולהריץ אותה שוב
זה אולי לא קורה לעתים קרובות, אבל לפעמים יש לנו פקודה או כמה פקודות מההיסטוריה שאנחנו רוצים להריץ שוב ושוב, ובזה בדיוק fc יכולה לעזור.

בשימוש הפשוט שלה הפקודה יודעת למצוא פקודות ישנות שהרצתם. לכן אם אני מפעיל:

mkdir foo
touch foo/bar
cp /etc/passwd foo


אז אני יכול אחרי זה לכתוב:

fc -l mkdir cp


ולקבל את רשימת כל הפקודות מ mkdir עד cp כולל:

544      mkdir foo
545 touch foo/bar
546 cp /etc/passwd foo


מה שיותר מדליק קורה אם אני מוותר על ה -l, ואז fc פותח את הרשימה בתוך עורך טקסט, מאפשר לי לשנות את הפקודות ובסוף מריץ את כולן. בדוגמה שלנו אני מוותר על ה -l ומקבל את כל הרשימה בעורך טקסט, משנה כל מופע של foo ל bar ומקבל את הקובץ:

mkdir bar
touch bar/bar
cp /etc/passwd bar


שומר ויוצא וכך יצרתי את תיקיית bar בדיוק כמו שיצרתי קודם את תיקיית foo.

שימו לב רק שאתם בודקים טוב טוב מה אתם מריצים כשאתם בתוך העורך, כי מרגע ש fc יצא לדרך אי אפשר לעצור אותו וזה שפקודה מסוימת הופיעה בהיסטוריה לא בהכרח אומר שאתם רוצים להריץ אותה שוב.
Forwarded from ToCode
# יצירת סיסמאות משורת הפקודה עם pwgen
אחד הכפתורים שהכי אהבתי ב lastpass ודי חסר לי ב 1Password היה כפתור Generate Password. נכון, גם 1Password מג'נרט אוטומטית סיסמאות בטפסי רישום לאתרים, אבל הרבה פעמים בבדיקות אני צריך סיסמה אקראית שלא תישמר בכספת הסיסמאות. וכאן pwgen יכולה לעזור.

בהפעלה רגילה pwgen מדפיסה המון סיסמאות אקראיות למסך:

$ pwgen

cahhoh2G oofah7Wo Kain5pha eeKue9th Shieng9i ail5Mai3 ahgh1Woh uuQuu2oh
IVahg0ro Ahju2tah Zuox3laS ual3Iece Ohx7ua2e ib2riyoG UuYie9Oh eicuc7Ib
loh5ja7T Nen9biTh Zee5vaiw ies6AoBo eGheip3m eiyeeNg9 Aish1ohn eM6isees
oR7Zeam4 ithang7O Aing4hah eeNae6Ro ahRashi2 xo2eiVie Eew4ohp8 uusaeCh0
chaic0Vu eu2phaeJ oFee7ei8 zohBu4xe mu9iTeik oow0Ia7e Noothah5 yuuph2Ie
keiFair2 Chutoh1i ji9Quei5 OoX5Ophe yay3AeNo Ahoong3C keeS5Eih Ohbaivi4
pheiPh1A aaloof4B ahsoMai6 they7Xoo IeN1aiqu eoGhai7e ahLaqu9u EiGh3ook
kooCh3ah niGieb7E Chohpai9 uibi2Lah Aiqueiz9 the7ua1T fooS2Ohl Cha9aene
aeT9ahzi teeG8axa the9Wahy WooT0eis tieW5yoh aiYeip1l eTh0iewu azucew3A
oofoKu6h Wievei4c xoo0Quae Lah7Nue0 ieZ8ahqu Oi1ahjee OoW6eeZ3 yei1fi7A
ohb9phuN Gee5see4 eeD5jaik Figha4oo Jet2uo6e Eir9re3i OhDohk9e Yai8ahsu
Ahjaev2i ea8ohJ0e yeiHai4i Cev4Wuuh sheih9Hi akeiZa8t Aic3ahro zoo2AeCa
Ohgoong0 Bouhoo5a wai7Eih0 ZooP7eif ba5eiy3R eewooCh7 Aga2ueZ1 aiT8Shah
Aethee0h Eir9cieg Wo6zoodi iV6idohv Iezei7am chaeR5uf Ooree0ie aequa5Wi
Eeyu8uiF aibac7Li fee4Ahpe HooGo1ei pahng4Ah ohXuo9tu Eeseew0u aefes4Ph
Ea8ohnie kiyaiTh9 Lai9eifu aib4eeSa ua8aaM2o Tied3tee Lo5sooVo Ieshaiw4
pe3Aib4j HiujeeX2 teiJu0Ni geeSh7hi ieNg4oov Ua9ma1oC ahpieC9k Peit0Eih
ab9Raelo jahC6eix QuahG6to aeL7iera ze5OP9Ie uoBai7ob MohK8Ohm Ahr2eemi
loh8iGhu Iu3ahwie uDa4ia8j Quoh4iek aQu6ith0 Ahs5jaiy uech4aiS eodai7Ah
kei4Noox quooy0Ae ohnais7A jeech9Ae ob8ehaeN die4Ahth Ahg8jah3 Aishe8Yi


אם הפלט אינו tty אז תיוצר רק סיסמה אחת, וכמו עם ls גם פה אפשר להעביר -1 כדי לקבל את אותה התנהגות:

$ pwgen | cat
zo3gi3Ie

$ pwgen -1
shaiPoo2


יש מתגים שמאפשרים להפוך את הסיסמאות ליותר בטוחות, למשל המתג -y שמוסיף תווים מיוחדים ו -s שהופך את הסיסמה ליותר מסובכת לבני אדם. ואפשר גם לצרף מספר בסוף כדי לספר כמה תווים אתם רוצים:

$ pwgen -s -1 -y 30
bPcAig)mVL|\_hMpib|f.=?7$o^RQ|


חוץ מיצירת סיסמאות אפשר להשתמש ב pwgen כדי ליצור בעצם כל מחרוזת שאתם צריכים לבדיקות. לדוגמה אם אתם צריכים 10 כתובות אימייל שנראות אקראיות תוכלו לכתוב:

$ pwgen 10 10 | sed 's/$/@test.com/'
ige6Eiji3i@test.com
joiC9kaes0@test.com
EiZuwofu3z@test.com
nee6Ea0eid@test.com
iye7ieJ4oh@test.com
abaeReeP4y@test.com
ebei4NiQu6@test.com
OCheil6ahr@test.com
ootheiH3tu@test.com
ei8ne6ohMi@test.com


או הסקריפט הקצר הבא שמדפיס 10 משתמשים אקראיים ל JSON כאשר כל משתמש מקבל מזהה, שם ואימייל אקראיים:

echo "["
for i in {1..10}; do
id=$(pwgen -1 10)
name=$(pwgen -s 2 1)
email="${name:l}.${id}@example.com"
if [ $i -eq 10 ]; then
echo "{\"id\":\"$id\",\"name\":\"$name\",\"email\":\"$email\"}"
else
echo "{\"id\":\"$id\",\"name\":\"$name\",\"email\":\"$email\"},"
fi
done
echo "]"
Forwarded from Udi Oron
Today I learned:

ls --hyperlink