מה הם 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

הודעת השגיאה מופנית מחדש stdoutechoוההודעה נשלחת לחלון המסוף:

בואו נראה מה יש בקובץ 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

וזה בדיוק מה שאנחנו רואים.

זרמי תודעה

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

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

כמו שקורה בדרך כלל, יותר ידע מביא יותר אפשרויות.