מה הם stdin, stdout ו- stderr ב- Linux?

stdin
, stdout
, ו stderr
הם שלושה זרמי נתונים שנוצרו בעת הפעלת פקודה לינוקס. אתה יכול להשתמש בהם כדי לדעת אם התסריטים שלך עוברים באמצעות הצנרת או מנותבים מחדש. אנו מראים לך כיצד.
זרמים מצטרפים לשתי נקודות
ברגע שאתה מתחיל ללמוד על לינוקס ויוניקס דמוי מערכות הפעלה, אתה תבוא על פני התנאי stdin
, stdout
, ו stederr
. אלה שלושה זרמים סטנדרטיים שנוצרו בעת ביצוע פקודה של לינוקס. במחשוב, זרם הוא משהו שיכול להעביר נתונים. במקרה של זרמים אלה, הנתונים הם טקסט.
לזרמי נתונים, כמו לזרמי מים, שני קצוות. יש להם מקור וזרם. כל פקודת לינוקס בה אתה משתמש מספקת קצה אחד של כל זרם. הקצה השני נקבע על ידי הפגז שהפעיל את הפקודה. קצה זה יחובר לחלון המסוף, יתחבר לצינור, או ינותב לקובץ או לפקודה אחרת, על פי שורת הפקודה שהשיקה את הפקודה.
הזרמים הסטנדרטיים של לינוקס
בלינוקס, stdin
הוא זרם הקלט הסטנדרטי. זה מקבל טקסט כקלט שלו. פלט טקסט מהפקודה לקליפה מועבר באמצעות stdout
הזרם (סטנדרטי החוצה). הודעות שגיאה מהפקודה נשלחות דרך stderr
זרם (שגיאה סטנדרטית).
אז אתה יכול לראות שיש שני זרמי פלט, stdout
ו stderr
, וזרם קלט אחד stdin
,. מכיוון שלכל אחת מהודעות השגיאה והפלט הרגיל יש צינור משלה להוביל אותן לחלון המסוף, ניתן לטפל בהן באופן עצמאי.
זרמים מטופלים כמו קבצים
מתייחסים לזרמים בלינוקס - כמו כמעט לכל דבר אחר - כאילו היו קבצים. אתה יכול לקרוא טקסט מקובץ, ואתה יכול לכתוב טקסט לקובץ. שתי הפעולות הללו כוללות זרם נתונים. אז הרעיון של טיפול בזרם נתונים כקובץ הוא לא כל כך מתיחה.
לכל קובץ המשויך לתהליך מוקצה מספר ייחודי לזיהויו. זה ידוע כמתאר הקבצים. בכל פעם שדורשים לבצע פעולה בקובץ, מתאר הקובץ משמש לזיהוי הקובץ.
ערכים אלה הם תמיד משמשים stdin
, stdout,
ו stderr
:
- 0 : stdin
- 1 : stdout
- 2 : סטדרר
תגובה לצינורות והפניות מחדש
כדי להקל על מבואו של מישהו לנושא, טכניקה נפוצה היא לימוד גרסה פשוטה של הנושא. לדוגמא, בדקדוק נאמר לנו שהכלל הוא "אני לפני E, למעט אחרי C." אך למעשה, ישנם חריגים יותר לכלל זה מאשר ישנם מקרים המצייתים לו.
ברוח דומה, כאשר מדברים על stdin
, stdout
, ו stderr
זה נוח לשלוף את האקסיומה המקובלת כי תהליך לא יודע ולא אכפת היכן שלה שלושה זרמים סטנדרטיים נסתיים. האם על תהליך להיות אכפת אם הפלט שלו יועבר למסוף או יופנה לקובץ? האם הוא יכול אפילו לדעת אם הקלט שלו מגיע מהמקלדת או שמועבר אליו דרך תהליך אחר?
למעשה, תהליך אכן יודע - או לפחות הוא יכול לברר, אם יבחר לבדוק - והוא יכול לשנות את התנהגותו בהתאם אם מחבר התוכנה החליט להוסיף את הפונקציונליות הזו.
אנו יכולים לראות את שינוי ההתנהגות הזה בקלות רבה. נסה את שתי הפקודות הבאות:
ls
ls | חתול
ls
מתנהג פקוד שונה אם הפלט שלה ( stdout
) מתבצע המוזרמים לתוך פקוד אחרת. זה ls
עובר לפלט עמודה אחת, זה לא המרה שבוצעה על ידי cat
. וזה ls
עושה את אותו הדבר אם הפלט שלה הוא להיות מנותב:
ls> capture.txt
לכידת חתול.טקסט
הפניית stdout ו- stderr
יש יתרון בכך שהודעות שגיאה מועברות על ידי זרם ייעודי. המשמעות היא שנוכל להפנות את פלט הפקודה ( stdout
) לקובץ ועדיין לראות הודעות שגיאה ( stderr
) בחלון המסוף. אתה יכול להגיב על השגיאות אם אתה צריך, כפי שהם מתרחשים. זה גם עוצר את הודעות השגיאה מזיהום הקובץ stdout
שהופנה אליו.
הקלד את הטקסט הבא בעורך ושמור אותו בקובץ שנקרא error.sh.
#! / bin / bash echo "עומד לנסות לגשת לקובץ שאינו קיים" cat bad-filename.txt
הפוך את התסריט להפעלה באמצעות פקודה זו:
שגיאה chmod + x.sh
השורה הראשונה של התסריט מהדהדת טקסט לחלון המסוף, דרך stdout
הזרם. השורה השנייה מנסה לגשת לקובץ שאינו קיים. פעולה זו תיצור הודעת שגיאה שמועברת באמצעות stderr
.
הפעל את הסקריפט באמצעות פקודה זו:
./error.sh
אנו יכולים לראות כי שני זרמי הפלט stdout
וגם stderr
הוצגו בחלונות המסוף.
בואו ננסה להפנות את הפלט לקובץ:
./error.sh> capture.txt
הודעת השגיאה שמועברת באמצעות stderr
עדיין נשלחת לחלון המסוף. אנו יכולים לבדוק את תוכן הקובץ כדי לראות אם stdout
הפלט עבר לקובץ.
לכידת חתול.טקסט
הפלט מ- stdin
הופנה לקובץ כצפוי.
>
סמל ניתוב מחדש עובד עם stdout
כברירת מחדל. באפשרותך להשתמש באחד מתארי הקבצים המספריים כדי לציין איזה זרם פלט רגיל ברצונך להפנות מחדש.
כדי להפנות במפורש stdout
, השתמש בהוראות להפניה זו:
1>
כדי להפנות במפורש stderr
, השתמש בהוראות להפניה זו:
2>
בואו ננסה לבחון שוב והפעם נשתמש 2>
:
./error.sh 2> capture.txt
הודעת השגיאה מופנית מחדש stdout
echo
וההודעה נשלחת לחלון המסוף:
בואו נראה מה יש בקובץ capture.txt.
לכידת חתול.טקסט
stderr
ההודעה נמצאת capture.txt כצפוי.
הפניה מחדש של stdout וגם של stderr
אין ספק שאם אנו יכולים להפנות את הקובץ stdout
או stderr
לקובץ באופן עצמאי זה מזה, עלינו להיות מסוגלים להפנות את שניהם בו זמנית, לשני קבצים שונים?
כן אנחנו יכולים. פקודה זו תפנה stdout
לקובץ הנקרא capture.txt stderr
ולקובץ הנקרא error.txt.
./error.sh 1> capture.txt 2> error.txt
מכיוון ששני זרמי הפלט - פלט רגיל ושגיאה סטנדרטית - מופנים לקבצים, אין פלט גלוי בחלון המסוף. אנו מוחזרים לשורת הפקודה כאילו לא אירע דבר.
בואו לבדוק את התוכן של כל קובץ:
לכידת חתול.טקסט
error cat.txt
הפניית stdout ו- stderr לאותו קובץ
זה מסודר, יש לנו כל אחד מזרמי הפלט הסטנדרטיים עובר לקובץ ייעודי משלו. השאלה היא רק צירוף אחר שאנו יכולים לעשות הוא לשלוח שתי stdout
ו stderr
לאותו קובץ.
אנו יכולים להשיג זאת באמצעות הפקודה הבאה:
./error.sh> capture.txt 2> & 1
בואו נשבר את זה.
- ./error.sh : מפעיל את קובץ הסקריפט error.sh.
- > capture.txt : מפנה את
stdout
הזרם לקובץ capture.txt.>
הוא קצר1>
. - 2> & 1 : זה משתמש בהוראות &> הפניה מחדש. הוראה זו מאפשרת לך לומר לקליפה לגרום לזרם אחד להגיע לאותו יעד כמו זרם אחר. במקרה זה אנו אומרים "הפניה מחדש של זרם 2,
stderr
לאותו יעד אליוstdout
מועבר זרם 1. "
אין פלט גלוי. זה מעודד.
בואו נבדוק את קובץ ה- capture.txt ונראה מה יש בו.
לכידת חתול.טקסט
הן stdout
ו stderr
זרמים הועברו אל קובץ יעד יחיד.
כדי שהפלט של זרם ינותב וייזרק בשקט, הפנה את הפלט אליו /dev/null
.
איתור הפניה מחדש בתסריט
דנו כיצד פקודה יכולה לזהות אם אחד מהזרמים מנותבים מחדש, ויכולה לבחור לשנות את התנהגותה בהתאם. האם אנו יכולים להשיג זאת בתסריטים שלנו? כן אנחנו יכולים. וזו טכניקה קלה מאוד להבנה ולהפעלתה.
הקלד את הטקסט הבא בעורך ושמור אותו כ input.sh.
#! / bin / bash אם [-t 0]; ואז הד סטדין מגיע ממקלדת אחרת הד סטדין מגיע מצינור או מקובץ fi
השתמש בפקודה הבאה כדי להפוך אותו להפעלה:
קלט chmod + x.sh
החלק החכם הוא המבחן בסוגריים המרובעים. האפשרות -t
(terminal) מחזירה true (0) אם הקובץ המשויך לתיאור הקבצים מסתיים בחלון המסוף. השתמשנו במתאר הקבצים 0 כטיעון למבחן, המייצג stdin
.
אם stdin
הוא מחובר לחלון מסוף הבדיקה תוכיח שהיא נכונה. אם stdin
הוא מחובר לקובץ או לצינור, הבדיקה תיכשל.
אנו יכולים להשתמש בכל קובץ טקסט נוח כדי ליצור קלט לתסריט. כאן אנו משתמשים בשם dummy.txt.
./input.sh <dummy.txt
הפלט מראה שהסקריפט מזהה שהקלט לא מגיע ממקלדת, אלא מקור קובץ. אם תבחר בכך, תוכל לשנות את התנהגות התסריט שלך בהתאם.
זה היה עם הפניית קובץ, בואו ננסה עם צינור.
חתול dummy.txt | ./input.sh
התסריט מזהה שהקלט שלו מועבר לתוכו. או ליתר דיוק, הוא מזהה פעם נוספת stdin
שהזרם אינו מחובר לחלון מסוף.
בואו נפעיל את התסריט ללא צינורות ולא הפניות מחדש.
./input.sh
stdin
הזרם מחובר לחלון הטרמינל, ואת התסריט מדווח זו בהתאם.
כדי לבדוק את אותו הדבר עם זרם הפלט, אנו זקוקים לסקריפט חדש. הקלד את הדברים הבאים בעורך ושמור אותו כ- output.sh.
#! / bin / bash אם [-t 1]; ואז הד סטדאוט עובר לחלון המסוף אחרת סטו האקו מנותב או מועבר באמצעות פייפ
השתמש בפקודה הבאה כדי להפוך אותו להפעלה:
קלט chmod + x.sh
השינוי המשמעותי היחיד בתסריט זה הוא במבחן בסוגריים המרובעים. אנו משתמשים בספרה 1 כדי לייצג את מתאר הקבצים עבורו stdout
.
בואו ננסה את זה. נקפיד את התפוקה cat
.
./פלט | חתול
התסריט מזהה שהפלט שלו אינו עובר ישירות לחלון מסוף.
אנו יכולים גם לבדוק את הסקריפט על ידי הפניית הפלט לקובץ.
./output.sh> capture.txt
אין פלט לחלון המסוף, אנו מוחזרים בשקט לשורת הפקודה. כפי שהיינו מצפים.
אנו יכולים להסתכל בתוך קובץ ה- capture.txt כדי לראות מה נלכד. השתמש בפקודה הבאה לשם כך.
לכידת חתול.ש
שוב, הבדיקה הפשוטה בסקריפט שלנו מגלה stdout
שהזרם לא נשלח ישירות לחלון מסוף.
אם אנו מריצים את הסקריפט ללא צינורות או הפניות מחדש, עליו לגלות stdout
שהוא מועבר ישירות לחלון המסוף.
./output.sh
וזה בדיוק מה שאנחנו רואים.
זרמי תודעה
הידיעה כיצד לדעת אם התסריטים שלך מחוברים לחלון המסוף, או לצינור או מנותבים מחדש, מאפשרת לך להתאים את התנהגותם בהתאם.
פלט רישום ואבחון יכול להיות מפורט יותר או פחות, תלוי אם הוא עובר למסך או לקובץ. ניתן לרשום הודעות שגיאה לקובץ אחר מאשר פלט התוכנית הרגיל.
כמו שקורה בדרך כלל, יותר ידע מביא יותר אפשרויות.