קריאה עם read מ Pipe ב Bash
הפקודה read קוראת שורה מהקלט הסטנדרטי, שוברת אותה למילים (עם תו ההפרדה במשתנה IFS
) ושומרת את התוצאה למשתנה אחד או יותר שאת שמו היא מקבלת בהפעלה.
לכן הקוד הבא קורא את השורה הראשונה מהקובץ /etc/shells
ושומר אותו למשתנה בשם first_line
:
read first_line < /etc/shells
והקוד הבא קורא רק את המילה הראשונה מאותו קובץ ושומר אותה למשתנה first_word
:
read first_word rest < /etc/shells
קל לשכוח שההתנהגות של read בשילוב |
אינה אינטואיטיבית, וזה לא בגלל read. כל פעם שאנחנו מפעילים פקודות בתוך Pipeline, באש פותח תת-מעטפת (Sub Shell) ומבצע את הפקודות בתוכה. הבעיה היא שמשתנים שמוגדרים באותו Sub Shell יימחקו כשה Sub Shell יסתיים, כלומר ביציאה מה Pipeline. הפקודה הזאת לדוגמה לא לוקחת את המילה הראשונה מהפלט של wc /etc/shells
לתוך המשתנה lines:
wc /etc/shells | read lines
כלומר היא כן, אבל המשתנה נשמר בתוך Sub Shell ונמחק איך שהשורה נגמרת. בשביל ש read תוכל לשמור משתנה ל Shell הנוכחי שלי היא חייבת להיות מופעלת ממנה, כלומר לא מצד ימין של סימן Pipe. במצב כזה אני צריך להשתמש בפקודת <()
כדי להריץ פקודה ולשמור את הפלט שלה לתוך File Handle, ואז בעזרת הפניית קלט רגילה אני יכול להעביר את השורה הראשונה מאותו File Handle ל read:
read lines words chars rest < <(wc /etc/passwd)