OnWorks Linux ו-Windows Online WorkStations

לוגו

אירוח מקוון בחינם עבור תחנות עבודה

<הקודם | תוכן | הבא>

מלכודות

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

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

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

מלכודת אות טיעון [אוֹת...]

איפה טענה היא מחרוזת שתיקרא ותתייחס אליה כפקודה ו אוֹת הוא המפרט של האות שיפעיל את ביצוע הפקודה המתפרשת.

הנה דוגמה פשוטה:



#! / bin / bash


# trap-demo: הדגמה פשוטה לטיפול באותות

#! / bin / bash


# trap-demo: הדגמה פשוטה לטיפול באותות


trap "הד 'אני מתעלם ממך'." SIGINT SIGTERM עבור i ב-{1..5}; לַעֲשׂוֹת

הד "איטרציה $i של 5" שינה 5

עשה

trap "הד 'אני מתעלם ממך'." SIGINT SIGTERM עבור i ב-{1..5}; לַעֲשׂוֹת

הד "איטרציה $i של 5" שינה 5

עשה


סקריפט זה מגדיר מלכודת שתבצע הד פקודה בכל פעם שהאות SIG-INT או SIGTERM מתקבל בזמן שהסקריפט פועל. הפעלת התוכנית נראית כך כאשר המשתמש מנסה לעצור את הסקריפט על ידי לחיצה Ctrl-c:


[me@linuxbox ~]$ מלכודת-הדגמה

איטרציה 1 מתוך 5

איטרציה 2 מתוך 5 אני מתעלם ממך. איטרציה 3 מתוך 5 אני מתעלם ממך. איטרציה 4 מתוך 5

איטרציה 5 מתוך 5

[me@linuxbox ~]$ מלכודת-הדגמה

איטרציה 1 מתוך 5

איטרציה 2 מתוך 5 אני מתעלם ממך. איטרציה 3 מתוך 5 אני מתעלם ממך. איטרציה 4 מתוך 5

איטרציה 5 מתוך 5


כפי שאנו יכולים לראות, בכל פעם שהמשתמש מנסה להפריע לתוכנית, ההודעה מודפסת במקום זאת.

בניית מחרוזת ליצירת רצף שימושי של פקודות עשויה להיות מביכה, ולכן נהוג לציין פונקציית מעטפת בתור הפקודה. בדוגמה זו, פונקציית מעטפת נפרדת מוגדרת עבור כל אות שיש לטפל בו:



#! / bin / bash

# trap-demo2: הדגמה פשוטה לטיפול באות exit_on_signal_SIGINT () {

echo "הסקריפט הופסק." 2>&1 יציאה 0

}


exit_on_signal_SIGTERM () {

echo "הסקריפט הסתיים." 2>&1 יציאה 0

}


trap exit_on_signal_SIGINT SIGINT trap exit_on_signal_SIGTERM SIGTERM

#! / bin / bash

# trap-demo2: הדגמה פשוטה לטיפול באות exit_on_signal_SIGINT () {

echo "הסקריפט הופסק." 2>&1 יציאה 0

}


exit_on_signal_SIGTERM () {

echo "הסקריפט הסתיים." 2>&1 יציאה 0

}


trap exit_on_signal_SIGINT SIGINT trap exit_on_signal_SIGTERM SIGTERM



עבור i ב-{1..5}; לַעֲשׂוֹת

הד "איטרציה $i של 5" שינה 5

עשה


עבור i ב-{1..5}; לַעֲשׂוֹת

הד "איטרציה $i של 5" שינה 5

עשה


תסריט זה כולל שניים מלכודת פקודות, אחת לכל אות. כל מלכודת, בתורה, מציינת פונקציית מעטפת שתתבצע כאשר האות המסוים מתקבל. שים לב להכללה של an יציאה פקודה בכל אחת מפונקציות הטיפול באות. בלי א יציאה, הסקריפט ימשיך לאחר השלמת הפונקציה.

כאשר המשתמש לוחץ Ctrl-c במהלך ביצוע הסקריפט הזה, התוצאות נראות כך:



[me@linuxbox ~]$ trap-demo2

איטרציה 1 מתוך 5

איטרציה 2 מתוך 5 הסקריפט הופסק.

[me@linuxbox ~]$ trap-demo2

איטרציה 1 מתוך 5

איטרציה 2 מתוך 5 הסקריפט הופסק.


תמונה

קבצים זמניים

אחת הסיבות לכך שמטפלי אותות כלולים בסקריפטים היא להסיר קבצים זמניים שהסקריפט עשוי ליצור כדי להחזיק תוצאות ביניים במהלך הביצוע. יש משהו כמו אמנות במתן שמות לקבצים זמניים. באופן מסורתי, תוכניות במערכות דמויות Unix יוצרות את הקבצים הזמניים שלהן ב- / Tmp ספרייה, ספרייה משותפת המיועדת לקבצים כאלה. עם זאת, מכיוון שהספרייה משותפת, הדבר מעורר חששות אבטחה מסוימים, במיוחד עבור תוכניות הפועלות עם הרשאות משתמש-על. מלבד השלב הברור של הגדרת הרשאות מתאימות לקבצים החשופים לכל משתמשי המערכת, חשוב לתת לקבצים הזמניים שמות קבצים שאינם ניתנים לחיזוי. זה נמנע מניצול המכונה א התקפת מירוץ זמני. דרך אחת ליצור שם לא צפוי (אך עדיין תיאורי) היא לעשות משהו כזה:

tempfile=/tmp/$(basename $0).$$.$RANDOM

פעולה זו תיצור שם קובץ המורכב משם התוכנית, ואחריו מזהה התהליך שלה (PID), ואחריו מספר שלם אקראי. שים לב, עם זאת, כי $RAN- DOM משתנה shell מחזיר רק ערך בטווח של 1-32767, שאינו טווח גדול במיוחד במונחי מחשב, כך שמופע בודד של המשתנה אינו מספיק כדי להתגבר על תוקף נחוש.



תמונה

דרך טובה יותר היא להשתמש ב- mktemp התוכנית (לא להתבלבל עם ה mktemp פונקציית ספרייה רגילה) כדי לתת שם לקובץ הזמני וגם ליצור אותו. ה mk- טמפ' התוכנית מקבלת תבנית כארגומנט המשמש לבניית שם הקובץ. התבנית צריכה לכלול סדרה של תווי "X", המוחלפים במספר תואם של אותיות ומספרים אקראיים. ככל שסדרת הדמויות "X" ארוכה יותר, סדרת הדמויות האקראיות ארוכה יותר. הנה דוגמה:

tempfile=$(mktemp /tmp/foobar.$$.XXXXXXXXXX)

זה יוצר קובץ זמני ומקצה את שמו למשתנה קובץ זמני. תווי "X" בתבנית מוחלפים באותיות ומספרים אקראיים כך ששם הקובץ הסופי (שבדוגמה זו כולל גם את הערך המורחב של הפרמטר המיוחד $$ כדי להשיג את ה-PID) עשוי להיות משהו כמו:

/tmp/foobar.6593.UOZuvM6654

עבור סקריפטים שמבוצעים על ידי משתמשים רגילים, ייתכן שיהיה חכם להימנע משימוש ב- / Tmp ספרייה וצור ספרייה לקבצים זמניים בתוך ספריית הבית של המשתמש, עם שורת קוד כמו זו:

[[ -d $HOME/tmp ]] || mkdir $HOME/tmp


מחשוב ענן מערכת ההפעלה המוביל ב-OnWorks: