때때로 프로그램이 백그라운드에서 잠겨 CPU 사용량이 높아지는 경우가 있습니다. 현재 가장 높은 CPU 부하를 유발하는 프로세스를 프로그래밍 방식으로 확인하고 종료할 수 있는 방법이 있습니까?
답변1
이러한 유형의 작업에 적합하다는 것을 안다면 더 나은 서비스를 제공할 수 있는 일련의 Unix 명령이 있습니다.
- 정규식
- 삭제
- 그들 모두를 죽일
특히 오작동하는 프로세스의 이름을 알고 있는 경우 이러한 도구를 사용하여 "공격"을 더욱 표적화할 수 있습니다.
그들 모두를 죽일
Chrome을 종료하여 결국 해결해야 하는 문제가 계속 발생합니다. 나는 보통 그들을 모두 죽이기 위해 이 명령을 사용합니다.
$ killall chrome
pgrep 및 pkill
하지만 이렇게 할 수도 있으며 최신 프로세스만 처리할 수도 있습니다.
# to list
$ pgrep -n chrome
23108
# to kill
$ pkill -n chrome
명령줄을 기반으로 죽이기
-f
실행 파일 이름뿐만 아니라 일치시키려는 긴 경로 매개 변수가 있는 프로세스에 액세스하기 위해 스위치를 추가할 수도 있습니다 .
예를 들어 다음과 같은 프로세스가 있다고 가정해 보겠습니다.
$ ps -eaf | grep some
saml 26624 26575 0 22:51 pts/44 00:00:00 some weird command
saml 26673 26624 0 22:51 pts/44 00:00:00 some weird command's friend
saml 26911 26673 8 22:54 pts/44 00:00:00 some weird command's friend
그들은 단지 Bash 쉘일 뿐입니다.ARGV0다음 이름으로 설정하세요. 그건 그렇고, 나는 다음 프로세스에 이 트릭을 사용했습니다.
$ (exec -a "some weird command name's friend" bash)
친구를 쫓아다니다
하지만 이러한 사람들이 많이 있고 명령줄에 "친구"가 있기 때문에 이들 중 특정 집합만 추적하고 싶다고 가정해 보겠습니다. 나는 이것을 할 수 있다:
$ pgrep -f friend
26673
26911
막내친구를 구해요
여러 개가 있고 최신 항목을 선택하려면 -n
스위치를 믹스에 다시 추가하세요.
$ pgrep -fn friend
26911
-f
스위치를 등록할 때 정규식을 사용할 수도 있으므로 다음과 같이 작동합니다.
$ pgrep -f "weird.*friend"
26673
26911
이름을 보여줘
스위치를 사용하여 프로세스 이름을 다시 확인할 수 있습니다 -l
.
$ pgrep -f "weird.*friend" -l
26673 some weird command's friend
26911 some weird command's friend
제어 출력
또는 pgrep
쉼표( ) ,
로 구분된 프로세스 ID를 나열하도록 지시합니다.
$ pgrep -f "weird.*friend" -d,
26673,26911
다음과 같은 멋진 일을 할 수 있습니다.
$ ps -fp $(pgrep -f weird -d,)
UID PID PPID C STIME TTY TIME CMD
saml 26624 26575 0 22:51 pts/44 00:00:00 some weird command
saml 26673 26624 0 22:51 pts/44 00:00:00 some weird command's friend
saml 26911 26673 0 22:54 pts/44 00:00:00 some weird command's friend
그렇다면 높은 CPU 프로세스를 종료하는 방법은 무엇입니까?
나는 위의 내용을 사용하여 높은 CPU 프로세스를 보다 선택적으로 추구할 것입니다. 다음을 사용하여 죽일 수 있습니다:
# newest guys
$ pkill -nf vlc ; pkill -nf opensnap
# kill all of these
$ killall vlc; killall opensnap
CPU 로드를 살펴보세요.
$ top -b -n 1 | grep -E $(pgrep -f "weird.*friend" -d\|) | grep -v grep
26911 0.1 112m 106m 6408 848 4900 1512 0 0 S 20 0 0.0 some weird command's friend
26673 0.1 112m 106m 6392 848 5020 1504 0 0 S 20 0 0.0 some weird command's friend
여기서 ,
구분 기호를 쉼표( )로 변경했습니다. 이 스위치는 -d,
파이프( |
)라고도 합니다. 이 스위치를 -d\|
사용하면 grep
다음과 같이 프로세스 ID가 반환됩니다.
$ pgrep -f "weird.*friend" -d\|
26673|26911
grep -E ...
그런 다음 특정 프로세스 ID를 기반으로 출력을 필터링 할 수 있도록 명령에 삽입합니다 .top
이는 큰 진전처럼 보일 수 있지만 이제 우리가 사용하는 프로세스 ID는 "weird.*friend"라는 특정 프로세스와 연관된 프로세스 ID일 뿐이라는 것을 확실히 알 수 있습니다.
여기에서 CPU가 가장 높은 프로세스를 찾아 정말로 원할 경우 종료할 수 있습니다.
높은 CPU 처리에 대한 보다 목표화된 접근 방식
$ top -b -n 1 | grep -E $(pgrep -f "weird.*friend" -d\|) | \
grep -v grep | sort -nk14,14 | tail -1
26911 0.1 112m 106m 6408 848 4900 1512 0 0 S 20 0 0.0 some weird command's friend
top
위에 표시된 출력은 CPU 열(열 14)을 기준으로 정렬된 출력입니다. 가장 낮은 것부터 높은 것까지 정렬되므로 tail -1
"weird.*friend" 프로세스 중에서 가장 높은 CPU가 될 마지막 행( )을 선택합니다.
답변2
이를 위해 "and" 프로그램 Auto-Nice Daemon을 설정할 수 있습니다.
몇 가지 알려진 문제 요인 목록과 세 가지 재처리 수준(점점 더 가혹하게 재처리할 수 있도록)을 설정했지만 그 중 하나라도 프로세스를 종료할 수 있었지만 이는 일반적으로 최후의 수단으로 예약되어 있습니다.
원하는 특정 CPU 로드 수준을 달성하기 위해 조정하는 것이 항상 쉬운 것은 아니지만, 도움이 될 수 있는(그리고 공격을 방지하여 문제가 되는 프로세스를 종료하는 것을 방지하는 데 도움이 되는) cpulimit와 같이 Nice 및 ionice로 프로그램을 시작한 다른 도구가 있습니다.
답변3
스크립트 편집
@msw, @sim 및 기타 사용자는 내 스크립트 개념에 대해 정당한 우려를 제기했습니다. @sim의 답변과 msw의 의견에 영감을 받아 앉아서 특정 문제(가끔 문제를 일으키는 여러 알려진 프로세스)를 해결하는 방법을 다시 생각해 보았습니다. 이것이 내가 생각해낸 것입니다:
#!/bin/bash
# tries to kill process with highest CPU load
# (if it is part of a specified list of troublemakers)
TROUBLEMAKERS="vlc opensnap glxgears stress"
sleep 1 # wait a few seconds (just as a precaution)
TOPPROCESS=$(top -b -n 1 | sed 1,6d | sed -n 2p)
TOPPID=$(echo "$TOPPROCESS" | awk '{print $1}')
TOPNAME=$(echo "$TOPPROCESS" | awk '{print $12}')
if [[ "$TROUBLEMAKERS" == *"$TOPNAME"* ]]
then
echo "Cause of high CPU load: "$TOPNAME" ("$TOPPID")"
echo "In troublemaker list. Killing..."
kill -9 $TOPPID
else
echo "Cause of high CPU load: "$TOPNAME" ("$TOPPID")"
echo "Not in troublemaker list. Exiting..."
exit 1
fi
exit 0
이전 스크립트와 달리 이 스크립트는 이름이 알려진 많은 문제 발생자(시스템을 잠그기 쉬운 프로세스) 중 하나와 일치하는 경우 CPU 로드가 가장 높은 프로세스만 종료합니다.
원본 스크립트
다음은 시스템에서 가장 높은 순간 CPU 로드를 유발하는 프로세스를 식별하고 이를 종료하는 간단한 스크립트입니다(GUI를 충돌시키는 Xorg 제외).
#!/bin/bash
# tries to kill process with highest CPU load
# (if it isn't Xorg)
sleep 1 # wait a few seconds (just as a precaution)
TOPPROCESS=$(top -b -n 1 | sed 1,6d | sed -n 2p)
TOPPID=$(echo "$TOPPROCESS" | awk '{print $1}')
TOPNAME=$(echo "$TOPPROCESS" | awk '{print $12}')
if [ "$TOPNAME" != "Xorg" ]
then
kill -9 $TOPPID
else
echo "CPU load caused by Xorg. Exiting."
exit 1
fi
exit 0
이 TOPPROCESS
스니펫은 다음을 기반으로 합니다.이 항목commandlinefu.com에서.
답변4
#!/bin/bash
pid=$(ps -eo %cpu,pid --sort -%cpu | head -n 2 | awk '{print $1 " " $2}')
if [[ -n $pid ]]; then
kcpu=$(echo $pid | awk '{print $3}')
kpid=$(echo $pid | awk '{print $4}')
ift=$(echo "90"'<'$kcpu | bc -l)
if [ $ift -eq "0" ]; then
echo "kpid = $kpid"
kill $kpid
fi
else
echo "Does not exist"
fi