←→ 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, ή τις καταχωρίζουν μέσα από το δικό τους πακέτο εφαρμογής.
Τα κλειδιά που φέρνουν πίσω μια εφαρμογή
Ένα τυπικό launch agent μοιάζει έτσι:
<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 | Ξεκινά την εργασία μόλις φορτωθεί, δηλαδή σε κάθε σύνδεση (agents) ή εκκίνηση (daemons) | Είναι εκεί μετά από κάθε επανεκκίνηση |
KeepAlive = true | Επανεκκινεί τη διεργασία κάθε φορά που τερματίζεται | Η αναγκαστική έξοδος δεν κάνει τίποτα· επιστρέφει σε δευτερόλεπτα |
KeepAlive με συνθήκες | Επανεκκινεί μόνο σε ορισμένες περιπτώσεις, όπως μετά από κατάρρευση (SuccessfulExit = false) ή όσο υπάρχει δίκτυο | Επιστρέφει μερικές φορές, όχι πάντα |
StartInterval | Εκτελείται κάθε N δευτερόλεπτα | Εμφανίζεται, εκτελείται για λίγο, εξαφανίζεται, επαναλαμβάνεται |
StartCalendarInterval | Εκτελείται σε καθορισμένες ώρες, όπως το cron | Εμφανίζεται την ίδια ώρα κάθε μέρα |
WatchPaths | Εκτελείται όταν αλλάζει ένα αρχείο ή φάκελος | Εμφανίζεται αφού κάνετε κάτι φαινομενικά άσχετο |
Το launchd περιμένει περίπου 10 δευτερόλεπτα ανάμεσα στις επανεκκινήσεις μιας εργασίας που τερματίζεται συνεχώς, οπότε μια εργασία KeepAlive μπορεί επίσης να μοιάζει να «αναβοσβήνει».
Άλλοι λόγοι για τους οποίους επανέρχεται μια εφαρμογή
- Άνοιγμα κατά τη σύνδεση. Η εφαρμογή βρίσκεται στις Ρυθμίσεις συστήματος › Γενικά › Στοιχεία σύνδεσης και επεκτάσεις. Το macOS την ανοίγει σε κάθε σύνδεση.
- Εκ νέου άνοιγμα παραθύρων κατά την επανασύνδεση. Το πλαίσιο στο παράθυρο διαλόγου Επανεκκίνησης και Τερματισμού λειτουργίας επαναφέρει κάθε εφαρμογή που ήταν ανοιχτή.
- Η εφαρμογή προσθέτει ξανά τον εαυτό της. Η δική της ρύθμιση «Εκκίνηση κατά τη σύνδεση» την καταχωρίζει ξανά κάθε φορά που εκτελείται.
- Μια βοηθητική διεργασία ανοίγει την κύρια εφαρμογή. Μια μικρή βοηθητική διεργασία παρασκηνίου ξεκινά πρώτη και μετά ανοίγει την πλήρη εφαρμογή, για παράδειγμα για να δείξει την κατάσταση συγχρονισμού.
- Υπηρεσίες Homebrew. Το
brew services startγράφει ένα launch agent μεRunAtLoad. Σταματήστε το μεbrew services stop <name>.
Βρείτε ποιο από όλα είναι
- Βρείτε την ετικέτα της εργασίας. Εκτελέστε
launchctl list | grep -i example, με μέρος του ονόματος της εφαρμογής ή του προγραμματιστή. Η τρίτη στήλη είναι η ετικέτα. - Διαβάστε την εργασία:
Αναζητήστε ταlaunchctl print gui/$(id -u)/com.example.helperpath(το αρχείο plist),state,runs(πόσες φορές ξεκίνησε) καιlast exit code. Ένας μεγάλος αριθμός runs συνήθως σημαίνειKeepAlive. - Ανοίξτε το plist και ελέγξτε τα
RunAtLoad,KeepAliveκαι τα κλειδιά διαστήματος. - Αν δεν υπάρχει εργασία, ελέγξτε το Άνοιγμα κατά τη σύνδεση και τις ρυθμίσεις της ίδιας της εφαρμογής.
Διακοπή ή απενεργοποίηση
| Τι κάνετε | Επανέρχεται; |
|---|---|
| Έξοδος ή αναγκαστική έξοδος από τη διεργασία | Ναι: αμέσως με KeepAlive, στην επόμενη σύνδεση με RunAtLoad |
launchctl bootout gui/$(id -u)/label | Όχι τώρα. Ναι στην επόμενη σύνδεση με RunAtLoad |
launchctl disable gui/$(id -u)/label + bootout | Όχι, μέχρι να εκτελέσετε launchctl enable |
| Μετακίνηση του plist έξω από το LaunchAgents + bootout | Όχι, μέχρι να το μετακινήσετε πίσω |
| Απενεργοποίηση στο Να επιτρέπεται στο παρασκήνιο | Όχι, μέχρι να το ενεργοποιήσετε |
Οι εντολές βήμα προς βήμα βρίσκονται στον οδηγό πώς να απενεργοποιήσετε με ασφάλεια launch agents.
Συχνές ερωτήσεις
Γιατί μια διεργασία ξεκινά ξανά αμέσως μόλις τη σταματήσω στην Παρακολούθηση δραστηριότητας;
Η εργασία launchd της έχει ορισμένο το KeepAlive. Το launchd παρακολουθεί τη διεργασία και την ξεκινά ξανά όταν τερματιστεί. Σταματήστε την εργασία με launchctl bootout αντί να σταματήσετε τη διεργασία.
Τι σημαίνει RunAtLoad;
Το RunAtLoad είναι κλειδί σε ένα plist του launchd. Όταν είναι true, το launchd ξεκινά την εργασία μόλις φορτώσει το plist, που για ένα launch agent σημαίνει κάθε φορά που συνδέεστε.
Τι σημαίνει KeepAlive;
Το KeepAlive λέει στο launchd να κρατά την εργασία σε λειτουργία. Αν η διεργασία τερματιστεί ή σκοτωθεί, το launchd την ξεκινά ξανά. Μπορεί επίσης να είναι ένα σύνολο συνθηκών, όπως επανεκκίνηση μόνο μετά από κατάρρευση.
Ποια είναι η διαφορά ανάμεσα στη διακοπή και την απενεργοποίηση ενός launch agent;
Η διακοπή (launchctl bootout) αποφορτώνει την εργασία μέχρι την επόμενη σύνδεση ή επανεκκίνηση. Η απενεργοποίηση (launchctl disable ή μετακίνηση του plist έξω από το LaunchAgents) την εμποδίζει να φορτωθεί ξανά μετά από επανεκκίνηση.