このカラースクリーンショットで申し訳ありませんが、コピーアンドペースト+コード形式よりも問題を強調するのに役立つと思います:
コード形式の同じ画面を次に示します。
───────────────────────────────────────────────────────────────────────────────
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
とはまだ関係ありません。
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
この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)が同時に実行されなくなります。
スクリプトをプログラミングするという課題がありますが、少なくとも今では、情報を抽出する方法を知っています。
実行中のプロセスのPIDのみを検索し、間接的に関連付けられているもの(つまり、Sudo
呼び出しのPID、およびプロセス名を検索するgrep
)を検索する必要があるため、最初の検索で問題のある単語。
$ ps aux | grep display-auto-brightness | grep -vw -e grep -e Sudo | awk '{print $2}'
事実上、はい、それらを単一のプロセスとして識別する方法がありますが、条件があります。
これがあるとします:
#!/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です。したがって、ps
をppid
を指定して使用すると、同じプロセスに属するすべてのプロセスを検索できます。
bash-4.3$ ps -e -o ppid,command | grep 16180 | grep -v grep
16180 /bin/bash ./simple_example.sh
16180 sleep 3
さて、明らかに、これは2つのことを意味します:
質問の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