היום למדתי: הפקודה readarray ב bash
ל bash יש את הפקודה read שאמורה לקרוא קלט למשתנה, ולדעתי היא הסיבה המרכזית שאנשים לא אוהבים bash. היא תעבוד טוב כשניקח מילה בודדת למשתנה:
ubuntu@primary:~$ read name < <(echo ynon)
ubuntu@primary:~$ echo "$name"
ynon
אבל רק תנסו להעביר משהו שהיא לא אוהבת ואיבדתם אותה. הנה לדוגמה read מוחקת את הרווחים מתחילת השורה, סתם כי מתחשק לה:
ubuntu@primary:~$ read name < <(echo " one")
ubuntu@primary:~$ echo "$name"
one
ואם בפלט יש כמה שורות, read פשוט תזרוק את כל מה שבא אחרי השורה הראשונה:
ubuntu@primary:~$ read name < <(cowsay hello)
ubuntu@primary:~$ echo "$name"
_______
ונכון הכל אפשר לפתור, אבל כשהכלים טובים יותר גם החיים פשוטים יותר. הפקודה readarray היא גירסה משודרגת של read שנועדה לקרוא אוסף של שורות לתוך מערך, וגם לטפל טוב יותר בכל סוגי הקלט. כך תיראה הדוגמה השניה עם הרווח בהתחלה עם readarray:
ubuntu@primary:~$ readarray lines < <(echo " one")
ubuntu@primary:~$ echo "$lines"
one
וזאת הדוגמה השלישית, שמדפיסה הפעם את כל השורות:
ubuntu@primary:~$ readarray lines < <(cowsay hello)
ubuntu@primary:~$ echo "${lines[@]}"
_______
< hello >
-------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
יותר מזה, בגלל שהפלט נשמר בתור מערך אפשר לגשת לכל שורה ממנו למשל:
echo "${lines[1]}"
ל readarray יש די הרבה אפשרויות להתאמה כולל המתג -t
שמוחק את תו ירידת השורה מכל שורת קלט, המתג -n
שמאפשר להגביל את מספר השורות שנקרא, המתג -s
שמאפשר לדלג על השורות הראשונות.
נ.ב. בטוח שמתם לב לקריאה המשונה עם כל החצים שמאלה. גם אני כמוכם הייתי שמח לכתוב:
ubuntu@primary:~$ cowsay hello | readarray lines
אבל זה לא יעבוד. סימן |
פותח Sub Shell, והמערך lines יוגדר באותו Shell פנימי. אם נפעיל פקודה כזאת ואחריה ננסה להדפיס את lines ב Shell שלנו נקבל מערך ריק.