←→ Underneath: Background Apps · כל מדריכי ה‑Mac

למה יישום חוזר אחרי הפעלה מחדש של ה‑Mac

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

התשובה הקצרה: ליישום יש משימת launchd. ‏RunAtLoad מפעיל אותה בכל התחברות, ו‑KeepAlive מפעיל אותה שוב בכל פעם שהיא נעצרת. יציאה מהתהליך לא משנה את המשימה. כדי לעצור אותה לתמיד, השביתו את המשימה, לא את התהליך.

מה זה launchd

launchd הוא התהליך הראשון ש‑macOS מפעיל (מזהה תהליך 1). הוא מפעיל כמעט את כל השאר. הוא קורא קובצי .plist קטנים, שנקראים משימות (jobs), שאומרים מה להריץ ומתי. לכל משימה יש תווית (label), שם ייחודי כמו com.google.keystone.agent.

יישומים מתקינים משימות ב‑~/Library/LaunchAgents, ‏/Library/LaunchAgents או /Library/LaunchDaemons, או רושמים אותן מתוך חבילת היישום שלהם.

המפתחות שמחזירים יישום

הנה סוכן הפעלה טיפוסי:

<key>Label</key>
<string>com.example.helper</string>
<key>ProgramArguments</key>
<array>
  <string>/Applications/Example.app/Contents/MacOS/Helper</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
מפתחהשפעהמה רואים
RunAtLoadמפעיל את המשימה ברגע שהיא נטענת, כלומר בכל התחברות (סוכנים) או אתחול (daemons)הוא שם אחרי כל הפעלה מחדש
KeepAlive = trueמפעיל מחדש את התהליך בכל פעם שהוא מסתייםסגירה כפויה לא עוזרת; הוא חוזר תוך שניות
KeepAlive עם תנאיםמפעיל מחדש רק במקרים מסוימים, למשל אחרי קריסה (SuccessfulExit = false) או כל עוד הרשת מחוברתהוא חוזר לפעמים, לא תמיד
StartIntervalרץ כל N שניותהוא מופיע, רץ לרגע, נעלם, וחוזר חלילה
StartCalendarIntervalרץ בשעות קבועות, כמו cronהוא מופיע באותה שעה בכל יום
WatchPathsרץ כשקובץ או תיקייה משתניםהוא מופיע אחרי שעשיתם משהו שלא קשור אליו

launchd ממתין כ‑10 שניות בין הפעלות מחדש של משימה שממשיכה להסתיים, ולכן משימת KeepAlive יכולה גם להיראות כאילו היא ״מהבהבת״.

סיבות אחרות לכך שיישום חוזר

לגלות מה מהם הגורם

  1. מצאו את תווית המשימה. הריצו launchctl list | grep -i example, עם חלק משם היישום או המפתח. העמודה השלישית היא התווית.
  2. קראו את המשימה:
    launchctl print gui/$(id -u)/com.example.helper
    חפשו את path (קובץ ה‑plist), ‏state, ‏runs (כמה פעמים היא הופעלה) ו‑last exit code. מספר הפעלות גבוה מעיד בדרך כלל על KeepAlive.
  3. פתחו את ה‑plist ובדקו את RunAtLoad, ‏KeepAlive ואת מפתחות המרווחים.
  4. אם אין משימה, בדקו את ״פתיחה בעת התחברות״ ואת ההגדרות של היישום עצמו.

עצירה לעומת השבתה

מה עושיםחוזר?
יציאה או סגירה כפויה של התהליךכן: מיד אם יש KeepAlive, בהתחברות הבאה אם יש RunAtLoad
launchctl bootout gui/$(id -u)/labelלא עכשיו. כן בהתחברות הבאה אם יש RunAtLoad
launchctl disable gui/$(id -u)/label + bootoutלא, עד שתריצו launchctl enable
העברת ה‑plist אל מחוץ ל‑LaunchAgents + bootoutלא, עד שתחזירו אותו
כיבוי ב״אפשר ברקע״לא, עד שתפעילו אותו שוב

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

שאלות נפוצות

למה תהליך עולה מחדש מיד אחרי שיצאתי ממנו במנטר הפעילות?

במשימת ה‑launchd שלו מוגדר KeepAlive. launchd משגיח על התהליך ומפעיל אותו שוב כשהוא מסתיים. עצרו את המשימה עם launchctl bootout במקום לצאת מהתהליך.

מה המשמעות של RunAtLoad?

RunAtLoad הוא מפתח בקובץ plist של launchd. כשהערך שלו true, ‏launchd מפעיל את המשימה מיד כשהוא טוען את ה‑plist, ועבור סוכן הפעלה זה אומר בכל פעם שאתם מתחברים.

מה המשמעות של KeepAlive?

KeepAlive אומר ל‑launchd להשאיר את המשימה פועלת. אם התהליך מסתיים או נהרג, launchd מפעיל אותו שוב. הוא יכול להיות גם קבוצת תנאים, למשל הפעלה מחדש רק אחרי קריסה.

מה ההבדל בין עצירה להשבתה של סוכן הפעלה?

עצירה (launchctl bootout) פורקת את המשימה עד ההתחברות הבאה או ההפעלה מחדש. השבתה (launchctl disable, או העברת ה‑plist אל מחוץ ל‑LaunchAgents) מונעת ממנה להיטען שוב אחרי הפעלה מחדש.