העברת מידע בין תהליכים ()>
רמת קושי: #advanced
הטיפ הבא מניח ידע בהפניות וערוצים
שימוש ב pipe
צורת העבודה עם באש מורכבת מאוסף של כלים קטנים שמשרשרים אותם ביחד כדי לקבל תוצאה מרשימה שיותר, לשם כך הכלי העיקרי שלנו הוא שימוש ב pipe (
שימוש ב Process Substitution
קיימת אפשרות נוספת להעביר פלט של פקודה אחת לפקודה אחרת והוא על ידי שימוש בהחלפת הקונטקסט לתהליך.
היכולת הזאת מאפשרת לנו לבצע
העברת פלט של פקודות לפקודות אחרות שעובדות רק עם קבצים
ועוד יכולת קריטית נוספת שנראה בטיפ הבא
#pipe
#redirection
#named_pipe
#process_substitution
@bash_tips
רמת קושי: #advanced
הטיפ הבא מניח ידע בהפניות וערוצים
שימוש ב pipe
צורת העבודה עם באש מורכבת מאוסף של כלים קטנים שמשרשרים אותם ביחד כדי לקבל תוצאה מרשימה שיותר, לשם כך הכלי העיקרי שלנו הוא שימוש ב pipe (
|
)$ echo "(5 + 5) * 1000" | bc
10000
מה שבעצם מתרחש כאן הוא היכולת של באש להעביר פלט של פקודה אחת לפקודה אחרת. אם נרצה להסביר את הפעולה הזאת בשפה היותר טכנית, באש מפנה את ה stdout של הפקודה הראשונה ל stdin של הפקודה שמגיע לאחר הpipe.שימוש ב Process Substitution
קיימת אפשרות נוספת להעביר פלט של פקודה אחת לפקודה אחרת והוא על ידי שימוש בהחלפת הקונטקסט לתהליך.
$ more <(ls /bin)
מה בעצם קורה מתחת למכסה המנוע? התהליך הראשון רץ בסביבה משלו ואת התוכן הוא מעביר לnamed pipe, שזה שקול בערך לכתיבה לקובץ, ולאחר מכן הנתיב "לקובץ" המדובר עובר לפקודה הבאה.$ less <(ls /bin)
/proc/self/fd/11 is not a regular file (use -f to see it)
$ cat <(ls /bin)
[
2to3-2.7
411toppm
7z
...
$ less < <(ls /bin)
<less open with the relevant content>
כפי שניתן לראות ישנן פקודות שיודעות לקרוא תוכן ישירות מ named pipe וישנן כאלה שלא, בכדי "להמיר" את התוכן לפקודות שאינן תומכות בקריאה ישירות מ named pipe ניתן להפנות את הפלט אל ה stdin של הפקודה בעזרת >
(כפי שקורה בדוגמה האחרונה).היכולת הזאת מאפשרת לנו לבצע
העברת פלט של פקודות לפקודות אחרות שעובדות רק עם קבצים
ועוד יכולת קריטית נוספת שנראה בטיפ הבא
#pipe
#redirection
#named_pipe
#process_substitution
@bash_tips
קוד קריא
מכירים את זה ששרשרתם כמה פקודות עם pipe כדי לפלטר בדיוק את המידע שרציתם מהפלט אבל קיבלתם שורה ארוכה ולא קריאה בעליל?
@bash_tips
pipe
רמת קושי: #beginnersמכירים את זה ששרשרתם כמה פקודות עם pipe כדי לפלטר בדיוק את המידע שרציתם מהפלט אבל קיבלתם שורה ארוכה ולא קריאה בעליל?
$ curl https://google.com -v --trace-time 2>&1 | grep "^[0-9]" | cut -d ' ' -f1 | cut -d ':' -f3
אז מסתבר שאפשר לפצל שורות בעזרת ה pipe, קוד הגיוני סך הכל$ curl https://google.com -v --trace-time 2>&1 |
grep "^[0-9]" |
cut -d ' ' -f1 |
cut -d ':' -f3
#pipe@bash_tips
להעביר שגיאות ב pipe
רמת קושי: #beginners
דבר קטן וחשוב שכדאי להכיר
כולנו מכירים את השימוש ב pipe בבאש, להעביר פלט של פקודה אחת לפקודה אחרת, מה שלא כולם יודעים זה שpipe מעביר רק stdout ולא stderr
כפי שרואים השגיאה הודפסה ישירות לטרמינל ופקודת wc לא קיבלה שום פלט (ערך 0)
איך כן?
בכדי להעביר גם את stderr וגם את stdout דרך ה pipe צריך להריץ את ה pipe בצורה הבאה עם
#pipe
#redirection
@bash_tips
רמת קושי: #beginners
דבר קטן וחשוב שכדאי להכיר
כולנו מכירים את השימוש ב pipe בבאש, להעביר פלט של פקודה אחת לפקודה אחרת, מה שלא כולם יודעים זה שpipe מעביר רק stdout ולא stderr
$ ls /not_exist | wc -l
ls: cannot access /not_exist: No such file or directory
0
כפי שרואים השגיאה הודפסה ישירות לטרמינל ופקודת wc לא קיבלה שום פלט (ערך 0)
איך כן?
בכדי להעביר גם את stderr וגם את stdout דרך ה pipe צריך להריץ את ה pipe בצורה הבאה עם
&
$ ls /not_exist |& wc
1 9 50
#pipe
#redirection
@bash_tips
לשרשר ולספור
הזכרנו בעבר ששימוש ב pipe מתסיר את הקוד יציאה של הפקודה שרצה לפני הpipe
לדוגמה הפקודה הבאה תחזיר קוד יציאה 0 למרות שהפקודה הראשונה נכשלה
#pipe
#env_variable
#exit_code
@bash_tips
PIPESTATUS
רמת קושי: #beginners הזכרנו בעבר ששימוש ב pipe מתסיר את הקוד יציאה של הפקודה שרצה לפני הpipe
לדוגמה הפקודה הבאה תחזיר קוד יציאה 0 למרות שהפקודה הראשונה נכשלה
$ ls /not/exist/path | echo 123בכדי לקבל את הקוד יציאה של כל פקודה שהורצה ב pipe ניתן להשתמש במשתנה הסביבה PIPESTATUS, מדובר על משתנה סביבה מסוג מערך שמכיל קוד יציאה של כל פקודה שהורצה ב pipe
123
ls: cannot access '/not/exist/path': No such file or directory
$ echo $?
0
$ ls /not/exist/path | echo 123 | grep -o 2ניתן לראות אם כן שבעוד ששני הפקודות האחרונות יצאו בקוד 0, הפקודה הראשונה שנכשלה יצאה בקוד שגיאה
ls: cannot access '/not/exist/path': No such file or directory
2
$ declare -p PIPESTATUS
declare -a PIPESTATUS=([0]="2" [1]="0" [2]="0")
#pipe
#env_variable
#exit_code
@bash_tips
👍4🔥3