web-dev-qa-db-fra.com

Aide à déchiffrer `ps` et` pstree` avec `cron` et` Sudo`

Désolé pour cette copie d’écran en couleur, mais je pense que cela aide à mieux cerner le problème que le copier/coller + format de code:

ps display-auto-brightness

Voici le même écran en format de code:

───────────────────────────────────────────────────────────────────────────────
rick@Dell:~$ ps a | grep display-
26457 pts/2    S+     0:00 grep --color=auto display-
───────────────────────────────────────────────────────────────────────────────
rick@Dell:~$ ps a | grep display-
28927 pts/18   S+     0:00 Sudo /usr/local/bin/display-auto-brightness
29174 pts/18   S+     0:00 /bin/bash /usr/local/bin/display-auto-brightness
30183 pts/2    S+     0:00 grep --color=auto display-
───────────────────────────────────────────────────────────────────────────────
rick@Dell:~$ pstree | grep display-
        |-cron---cron---sh---display-auto-br---sleep
        |         |         |         |                 |-bash---Sudo---display-auto-br---sleep
───────────────────────────────────────────────────────────────────────────────
rick@Dell:~$ ps a | grep cron
16031 pts/2    S+     0:00 grep --color=auto cron
───────────────────────────────────────────────────────────────────────────────
rick@Dell:~$ ps a | grep display
26773 pts/2    S+     0:00 grep --color=auto display
28927 pts/18   S+     0:00 Sudo /usr/local/bin/display-auto-brightness
29174 pts/18   S+     0:00 /bin/bash /usr/local/bin/display-auto-brightness
───────────────────────────────────────────────────────────────────────────────

Ce matin, après le redémarrage du travail cron - /etc/cron.d/display-auto-brightness aurait dû démarrer. Je pensais que cela n'avait jamais commencé c'est sur la base de la première section.

J'ai démarré manuellement le script avec Sudo /usr/local/bin/display-auto-brightness. La deuxième section montre comment ps renvoie deux ID de processus pour un seul travail. Une fois pour l'élévation Sudo qui a démarré le travail et la seconde pour le script lui-même.

Existe-t-il un moyen programmatique d’identifier ces deux identificateurs PID comme un seul travail? La raison en est la prochaine étape de développement lors de la reprise de la suspension pour voir si le seul travail (et non deux processus) est déjà en cours d'exécution et tuez-le lorsque vous redémarrez le même travail. Cela donnera un réglage instantané de la luminosité de l'affichage si la lumière du jour reprend après une suspension dans l'obscurité ou vice versa.

Dans la troisième section, j'ai utilisé la commande pstree et découvert que le travail cron qui n'apparaissait pas avec la commande ps s'affiche ici. Pourquoi est-ce? .

Dans la quatrième section, je pipe ps en sortie à travers grep en utilisant cron comme filtre et rien ne s'affiche. Pourquoi est-ce?

Dans la cinquième et dernière section, je répète la deuxième section ps a | grep display- pour réaffirmer les conclusions précédentes.


Modifier 1

Je pense avoir compris pourquoi la quatrième section ne montre pas cron en cours d'exécution. Cela est dû au statut d'utilisateur normal pendant que cron est exécuté en tant que root. La solution consiste à utiliser:

$ Sudo ps aux | grep cron
root      1122  0.0  0.0  29008  2936 ?        Ss   04:16   0:00 /usr/sbin/cron -f
rick      7273  0.0  0.0  14224  1028 pts/2    S+   17:50   0:00 grep --color=auto cron

Nous pouvons maintenant voir que le redémarrage d'origine à 04h16 est toujours en cours d'exécution sous le travail cron. L'ID de processus 1122 est peut-être celui qui doit être éliminé lors de la reprise de la suspension lors de modifications ultérieures du programme. Cela ne correspond toujours pas au nom de script display-auto-brightness que la commande pstree trouve.


Modifier 2 raccourci sous-système Windows pour le bureau Linux

Lorsque vous configurez une icône pour appeler un script bash à partir du bureau Windows 10, vous obtenez davantage de programmes en cours que sous Ubuntu 16.04 et Unity:

$ ps -ef | grep lock-screen
rick     29243 29242  0 17:13 tty1     00:00:00 /bin/bash -c cd && DISPLAY=0:0 /mnt/e/bin/lock-screen-timer
rick     29244 29243  0 17:13 tty1     00:00:00 /bin/bash /mnt/e/bin/lock-screen-timer

Lorsque vous utilisez pstree, il y a encore plus de PID:

$ pstree -gp | grep lock-screen
          |-init(29242,29242)---bash(29243,29242)---lock-screen-tim(29244,29242)---sleep(29777,29242)

Dans "l'ancienne" méthode, je tuerais lock-screen-timer "29244". En regardant ps -aux Je pense que je devrais tuer "29243". En regardant pstree bien que le processus parent init devrait être éliminé, ce qui correspond à "29242".

Des tests supplémentaires révèlent que vous ne pouvez pas tuer init PID

Cette capture d'écran montre comment vous ne pouvez pas tuer directement init PID. Vous pouvez tuer son enfant, ce qui le fait mourir, mais son petit-fils et son arrière-petit-fils continuent à courir. Il semblerait que vous deviez supprimer trois PID sous Windows 10 WSL lorsqu'un raccourci sur le bureau est utilisé:

rick@alien:/mnt/c/Windows/System32$ pstree -gp | grep lock-screen
          |-init(30554,30554)---bash(30555,30554)---lock-screen-tim(30556,30554)---sleep(30587,30554)
rick@alien:/mnt/c/Windows/System32$ kill 30554
-bash: kill: (30554) - Operation not permitted
rick@alien:/mnt/c/Windows/System32$ Sudo kill 30554
[Sudo] password for rick:
rick@alien:/mnt/c/Windows/System32$ pstree -gp | grep lock-screen
          |-init(30554,30554)---bash(30555,30554)---lock-screen-tim(30556,30554)---sleep(30587,30554)
rick@alien:/mnt/c/Windows/System32$ kill 30555
rick@alien:/mnt/c/Windows/System32$ pstree -gp | grep lock-screen
          |-lock-screen-tim(30556,30554)---sleep(30612,30554)
rick@alien:/mnt/c/Windows/System32$ pstree -gp | grep sleep
          |-lock-screen-tim(30556,30554)---sleep(30633,30554)
rick@alien:/mnt/c/Windows/System32$ kill 30556
rick@alien:/mnt/c/Windows/System32$ pstree -gp | grep sleep
          `-sleep(30633,30554)
rick@alien:/mnt/c/Windows/System32$ kill 30633
3
WinEunuuchs2Unix

Grâce à cette question/réponse ( comment tuer une tâche cron si elle n’apparaît pas dans ps? Ou s’affiche dans ps? ) j’étais sur le bon chemin:

───────────────────────────────────────────────────────────────────────────────
rick@Dell:~$ ps wwuxa |grep display-auto | grep -v grep
root      1584  0.0  0.0   4508   780 ?        Ss   14:02   0:00 /bin/sh -c    /usr/local/bin/display-auto-brightness
root      1592  0.0  0.0  12564  2984 ?        S    14:02   0:00 /bin/bash /usr/local/bin/display-auto-brightness
───────────────────────────────────────────────────────────────────────────────
rick@Dell:~$ pstree -p -g | grep display-auto
             |-cron(1376,1376)---cron(1436,1376)---sh(1584,1584)---display-auto-br(1592,1584)---sleep(16989,1584)
───────────────────────────────────────────────────────────────────────────────
rick@Dell:~$ 

Tuer cron (avec les pid's 1376 et 1436) est probablement une mauvaise idée. Cependant tuer bash Shell (1584) qui est le parent de display-auto-bright (1592) et les grands-parents de dormir (16989) devrait tuer l'enfant et son petit-enfant. Ensuite, deux copies du processus enfant (affichage-auto-luminosité) ne seront pas exécutées en même temps.

Vient maintenant le défi de la programmation du script, mais au moins maintenant je sais comment extraire les informations.

0
WinEunuuchs2Unix

Puisque vous voulez rechercher uniquement les PID du processus en cours, et rien d’associé indirectement (par exemple, le PID de l’appel Sudo, et le grep recherchant le nom du processus), vous pouvez simplement supprimer le mots offensants de la recherche initiale.

$ ps aux | grep display-auto-brightness | grep -vw -e grep -e Sudo | awk '{print $2}'
1
neuro

Effectivement, oui, il existe un moyen de les identifier en tant que processus unique, mais avec une condition.

Supposons que nous ayons ceci:

#!/bin/bash
loop_function(){
    while :
    do
       sleep 3
    done
}

loop_function &

while true
do
    sleep 3
done

Et on le lance en arrière plan:

bash-4.3$ ./simple_example.sh &
[1] 16180

Nous voyons ici que le script lui-même a 16180 PID. Tous ses enfants auraient un différent. Maintenant, ils ont tous un parent commun: le shell spécifié dans la ligne #!, c’est-à-dire le même PID que celui indiqué lors de l’exécution du script en arrière-plan. Ainsi, en utilisant ps avec la spécification de ppid, nous pouvons rechercher tous les processus appartenant au même processus.

bash-4.3$ ps -e  -o ppid,command | grep 16180 | grep -v grep
16180 /bin/bash ./simple_example.sh
16180 sleep 3

Maintenant, évidemment, cela implique deux choses:

  • pour regrouper les processus, vous devez connaître le PID parent
  • les processus enfants des enfants auront un PID parent différent. Par conséquent, si vous avez plusieurs niveaux d'appels de fonction, il sera difficile de suivre tous les processus.

En ce qui concerne pstree une partie de la question, le travail y apparaissait - il était simplement coupé par grep. Vous n'avez également pas besoin de Sudo pour afficher les tâches cron:

$ ps -ef | grep cron | grep -v grep && echo $USER                                                                        
root       896     1  0 09:47 ?        00:00:00 /usr/sbin/cron -f
xieerqi
1