Извините за этот цветной снимок экрана, но я думаю, что он помогает выделить проблему лучше, чем copy & amp; paste + code format:
Вот такой же экран в формате кода:
───────────────────────────────────────────────────────────────────────────────
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. Во втором разделе показано, как ps возвращает два идентификатора процесса для одного задания. Один раз для повышения sudo, который запустил задание, а второй для самого скрипта.
Существует ли программный способ идентификации этих двух PID как одно задание? Причиной следующего шага разработки является возобновление с приостановки, чтобы проверить, не запущено ли одно задание (а не два процесса) и убить его при повторном запуске одной и той же работы. Это даст мгновенную настройку яркости дисплея, если возобновится при дневном свете после приостановки в темноте или наоборот.
В третьем разделе я использовал команду pstree и обнаружил задание cron, которое не появилось с ps показывает здесь. Существует ли программный способ идентификации этих двух PID как одно задание? .
В четвертом разделе I труба ps выводится через grep с использованием cron в качестве фильтра и ничего не появляется. Почему это?
В пятом и последнем разделе я повторю второй раздел ps a | grep display-, чтобы подтвердить предыдущие выводы.
Почему это ?
Думаю, я понял, почему четвертый раздел не показывает 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. Идентификатор процесса 1122 может быть тем, который должен быть убит при возобновлении с приостановления в будущих изменениях программы. Это все еще не связано с именем скрипта display-auto-brightness, которое находит команда pstree.
Когда создавая значок для вызова сценария bash с рабочего стола Windows 10, вы получаете больше запущенных программ, чем при простых 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 напрямую. Вы можете убить своего ребенка, который заставляет его умереть, но внук и правнук продолжают работать. Казалось бы, вам нужно убить три PID в Windows 10 WSL, когда используется ярлык на рабочем столе:
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
Эффективно, да, есть способ идентифицировать их как один процесс, но с условием.
Предположим, что мы имеем это:
#!/bin/bash
loop_function(){
while :
do
sleep 3
done
}
loop_function &
while true
do
sleep 3
done
И запустим его в background:
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
Теперь, очевидно, это подразумевает две вещи:
чтобы группировать процессы вместе, вы должны знать, что дочерние дочерние процессы родительских дочерних PID будут иметь различный родительский PID, поэтому, если у вас есть более одного уровня вызовов функций, будет сложно отслеживать все процессы.Что касается pstree части вопроса, работа там появилась - она была просто отрезана grep. Вам также не нужно sudo для просмотра cronjobs:
$ ps -ef | grep cron | grep -v grep && echo $USER
root 896 1 0 09:47 ? 00:00:00 /usr/sbin/cron -f
xieerqi
Поскольку вы хотите найти только PID процесса, а не что-то косвенное (т. е. PID вызова sudo и grep для поиска имени процесса), вы можете просто отключить нарушающий слова из начального поиска.
$ ps aux | grep display-auto-brightness | grep -vw -e grep -e sudo | awk '{print $2}'