web-dev-qa-db-ja.com

「cron」と「Sudo」で「ps」と「pstree」を解読するのに役立ちます

このカラースクリーンショットで申し訳ありませんが、コピーアンドペースト+コード形式よりも問題を強調するのに役立つと思います:

ps display-auto-brightness

コード形式の同じ画面を次に示します。

───────────────────────────────────────────────────────────────────────────────
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
───────────────────────────────────────────────────────────────────────────────

今朝、cronジョブを再起動した後、/etc/cron.d/display-auto-brightnessが起動するはずです。私はそれが最初のセクションに基づいて開始されたことはないと思った。

Sudo /usr/local/bin/display-auto-brightnessでスクリプトを手動で開始しました。 2番目のセクションは、psが1つのジョブに対して2つのプロセスIDを返す方法を示しています。ジョブを開始したSudo昇格に1回、スクリプト自体に2回目。

これら2つのPIDを1つのジョブとして識別するプログラム的な方法はありますか?次の開発ステップである理由は、単一のジョブが(2つのプロセスではない)は既に実行されており、同じジョブを再度開始するときにそれを強制終了します。これにより、暗闇でサスペンドした後に昼光で再開した場合、またはその逆の場合、即座にディスプレイの輝度を調整できます。

3番目のセクションでは、pstreeコマンドを使用し、psコマンドで表示されなかったcronジョブがここに表示されていることを発見しました。 それはなぜですか?.

4番目のセクションでは、フィルターとしてpsを使用してgrepを介してcron出力をパイプ処理しますが、何も表示されません。 なぜですか?

5番目の最後のセクションでは、2番目のセクションps a | grep display-を繰り返して、以前の結果を再確認します。


編集1

4番目のセクションにcronが表示されない理由がわかったと思います。これは、cronがrootとして実行されている間の通常のユーザーステータスが原因です。解決策は以下を使用することです:

$ 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

これで、午前4時16分に元の再起動がまだcronジョブで実行されていることがわかります。プロセスID1122は、将来のプログラム変更でサスペンドから再開するときに強制終了する必要がある場合があります。これは、pstreeコマンドが検出するスクリプト名display-auto-brightnessとはまだ関係ありません。


Linuxデスクトップショートカット用の2つのWindowsサブシステムの編集

Windows 10デスクトップからbashスクリプトを呼び出すためのアイコンを設定すると、Ubuntu 16.04および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

pstreeを使用すると、さらに多くのPIDがあります。

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

「古い」方法では、lock-screen-timer "29244"を殺します。 ps -auxを見ると、「29243」を殺すべきだと思います。 pstreeを見ると、init親プロセスは強制終了されます( "29242")。

さらにテストすると、init PIDを殺すことができないことがわかります

このスクリーンショットは、init PIDを直接殺すことができない方法を示しています。あなたはそれが死ぬ原因となる子供を殺すことができますが、孫とgreat孫は走り続けます。デスクトップショートカットを使用する場合、Windows 10 WSLで3つのPIDを削除する必要があるように見えます。

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

このQ&Aのおかげで( psで表示されない場合にcronジョブを強制終了するにはどうすればよいですか?psで表示されるようにするには?

───────────────────────────────────────────────────────────────────────────────
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:~$ 

Cronを(pidの1376と1436で)殺すのはおそらく悪い考えです。ただし、display-auto-brightness(1592)の親であるbashシェル(1584)を殺すsleep(16989)の祖父母は、子と孫を殺すべきです。そうすると、子プロセスの2つのコピー(display-auto-brightness)が同時に実行されなくなります。

スクリプトをプログラミングするという課題がありますが、少なくとも今では、情報を抽出する方法を知っています。

0

実行中のプロセスのPIDのみを検索し、間接的に関連付けられているもの(つまり、Sudo呼び出しのPID、およびプロセス名を検索するgrep)を検索する必要があるため、最初の検索で問題のある単語。

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

事実上、はい、それらを単一のプロセスとして識別する方法がありますが、条件があります。

これがあるとします:

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

loop_function &

while true
do
    sleep 3
done

バックグラウンドで起動します:

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

ここでは、スクリプト自体に16180 PIDがあることがわかります。すべての子には異なる子があります。現在、それらすべてに共通の親があります:#!行で指定されたシェル、つまり、バックグラウンドでスクリプトを実行したときに報告されたものとまったく同じPIDです。したがって、psppidを指定して使用すると、同じプロセスに属するすべてのプロセスを検索できます。

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

さて、明らかに、これは2つのことを意味します:

  • プロセスをグループ化するには、親PIDを知っている必要があります
  • 子の子プロセスは異なる親PIDを持つため、複数レベルの関数呼び出しがある場合、すべてのプロセスをトレースすることは困難です。

質問のpstree部分については、仕事はそこに表示されました-それはgrepによって単純に中断されました。 cronjobsを表示するためにSudoも必要ありません:

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