ps -C 동작이 Centos 6과 Centos 8 사이에서 변경되었습니다.

ps -C 동작이 Centos 6과 Centos 8 사이에서 변경되었습니다.

우리 시스템은 종종 ps -C cmdName프로세스가 실행 중인지 확인하고 그렇지 않은 경우 다시 시작하는 데 사용됩니다.

Centos 6에서 Centos 8로 마이그레이션할 때 동작에 변화가 있는 것 같았는데 ps -C, 이로 인해 시스템이 많이 손상되었습니다.

센토스 6(32비트)

예, 프로세스가 있습니다.

# ps aux | grep DvBuildSegmentList
root     16223  4.0  0.1  16064 11272 pts/0    S    14:14   0:00 ./DvBuildSegmentList
root     16264  0.0  0.0   4416  1880 pts/0    S+   14:14   0:00 grep DvBuildSegmentList

그리고 ps -C전체 명령 이름에서 프로세스를 감지합니다.

# ps -C DvBuildSegmentList
  PID TTY          TIME CMD
16223 pts/0    00:00:00 DvBuildSegmentL

(출력에서 잘린 명령줄에 유의하세요)

센토스 8(64비트)

예, 프로세스가 있습니다.

# ps aux | grep DvBuildSeg
root     15282  0.9  0.2  99796 42424 pts/1    S    14:18   0:04 ./DvBuildSegmentList
root     16989  0.0  0.0 221900  1104 pts/1    S+   14:26   0:00 grep --color=auto DvBuildSeg

전체 명령 이름을 사용하는 출력은 없습니다.

# /bin/ps -C DvBuildSegmentList
  PID TTY          TIME CMD

그러나 단축된 명령 이름을 사용하면 프로세스가 감지됩니다.

# /bin/ps -C DvBuildSegmentL
  PID TTY          TIME CMD
15282 pts/1    00:00:06 DvBuildSegmentL

32비트 Centos 6과 64비트 Centos 8을 모두 유지해야 하며 많은 코드를 다시 작성하지 않는 것이 가장 좋습니다.

  1. ps버전 간에 동일한 동작을 얻을 수 있는 방법이 있습니까 ? (명령 이름은 이름 충돌로 인해 처음 15자까지 잘리지 않을 수 있습니다.)

  2. 이 프로세스를 감지하는 다른 방법이 있습니까? ( ps -CC++, Perl, PHP 및 Bash에 걸쳐 많은 코드와 메소드가 퍼져 있습니다 )

나를 편집하다

그만한 가치가 있는 내용은 /proc/<pid>/stat잘린 파일 이름을 표시합니다.

cat /proc/4605/stat
4605 (DvBuildSegmentL) S 25769 4605 25769 34817 4605 1077936384 10536 304 0 0 225 119 0 0 20 0 1 0 6717759 103620608 10945 18446744073709551615 4194304 4339868 140734307933616 0 0 0 0 4096 16901 1 0 0 17 4 0 0 0 0 0 6438088 6440229 11730944 140734307937640 140734307937666 140734307937666 140734307938275 0

그러나 /proc/<pid>/cmdline앞에는 전체 경로가 있지만 전체 명령 이름은 있습니다.

cat -v /proc/4605/cmdline
/usr/local/blah/blah/blah/DvBuildSegmentList^@-d^@2^@

답변1

이 차이점을 해결하는 한 가지 방법은 procps패키지의 CentOS 6 버전을 다시 빌드하고 거기서 yum swap부터 시작하는 것입니다 procps-ng. 가장 안전한 방법은 아니지만 상당수의 시스템 프로그램을 이전 버전으로 대체합니다.

procps따라서 완전히 다른 이름으로 다시 빌드하고 설치하기를 원할 수도 있습니다 ps. 그런 다음 도구를 사용하여 포함 디렉터리가 시스템에 있는지 확인할 /opt/el6-rebuilds/bin/ps수 있습니다 . 결과는 CentOS 8에서 사용되는 "CentOS 6 동급" 버전이 됩니다 .PATH/etc/profile.dps

그런데 이렇게 말하면 확실히 그런 차이가 있는 걸까요? 방금 RHEL 8에서 이것을 시도했는데 ps -C <program name>정확히 지정하면 제대로 작동합니다. (실제로 말씀하신 내용은 반대입니다. 부분 문자열을 통해 지정할 때만 작동합니다.)

답변2

이 두 가지 방법은 서로 다른 OS 버전에서 작동하는 것 같습니다.

grep은 프로세스 이름을 얻습니다.

ps aux | grep myLongProcessName | grep -v

프로세스가 실행 중이면 0을 반환하고, 프로세스를 찾을 수 없으면 1을 반환합니다. 두 번째 명령이 grep -v필요한 이유는 때때로(항상은 아니지만) grep명령 자체가 의 출력에 나타나기 때문입니다 grep myLongProcessName.

killall을 통해 신호 0 보내기

killall -0 myLongProcessName

0프로세스가 존재하는지, 1아니면 발견되지 않았는지 반환합니다.

"double" 메소드는 실제로 다른 프로세스의 하위 문자열인 경우 grep실패합니다 . myLongProcessName예를 들어. 세 가지 프로세스가 있는 경우:

  • longProcessDBAccess(실행되지 않음)
  • longProcessDBAccessManager(달리기)
  • longProcessDBAccessClient(달리기)

grep실행 중인지 확인하기 위해 "double" 메소드를 사용하는 것은 longProcessDBAccess다른 두 메소드의 존재도 감지하기 때문에 실패합니다.

그러나 이 killall방법이 작동하려면 uid실행 중인 프로세스에 killall해당 작업을 수행할 수 있는 권한이 있어야 합니다.

죽이다:

kill()함수는 지정된 프로세스나 프로세스 그룹에 신호를 보내야 합니다 pid. 전송될 신호는 로 지정되며 sig 에 제공된 목록의 1 또는 0입니다 <signal.h>. 0(널 신호) 인 경우 sig오류 검사가 수행되지만 실제로 신호가 전송되지 않습니다. 빈 신호를 사용하여 유효성을 확인할 수 있습니다 pid.

프로세스가 지정된 프로세스에 신호를 보낼 수 있는 권한을 가지려면 pid전송 프로세스에 적절한 권한이 없는 한 전송 프로세스의 실제 또는 유효 사용자 ID가 수신 프로세스의 실제 또는 저장된 set-user-ID와 일치해야 합니다.

관련 정보