설치된 최고 버전의 커널 RPM을 프로그래밍 방식으로 확인하는 방법은 무엇입니까?

설치된 최고 버전의 커널 RPM을 프로그래밍 방식으로 확인하는 방법은 무엇입니까?

제가 쓰고 싶은 스크립트는 이렇습니다.

if [ uname -r is not == highest version of kernel RPM installed ]
then
  echo "You need to reboot to use the latest kernel"
fi

문제는 출력이 다음 rpm -q kernel과 유사한 경우입니다.

kernel-2.6.32-358.10.2.el6.x86_64
kernel-2.6.32-358.6.1.el6.x86_64

…어느 것이 더 높은지 어떻게 결정합니까? 나는 간단한 문자열 정렬이 신뢰할 수 없다는 것을 알고 있습니다(이 예에서는 거꾸로 정렬됩니다). rpm에 대한 단축키가 있나요? 아니면 모든 것을 직접 분석하고 비교해야 합니까?

답변1

긴 이야기 짧게

실제로 세 번째 시도에서 성공했습니다! RPM 버전 정보를 구문 분석하고 첫 번째, 두 번째 등의 계보를 결정하는 것이 얼마나 중요한지 문제에 대한 통찰력을 얻기 위해 나중에 이 Q&A를 접할 수 있는 다른 사람들을 위해 처음 두 번의 시도를 여기에 남겨 두겠습니다.

시도 #1(OP가 작동하지 않았다고 말함)

이 명령은 출력을 정렬하고 버전 순서대로 제공합니다.

$ rpm -q kernel --queryformat "%{VERSION} %{RELEASE}\n"|sort -n
2.6.18 238.12.1.el5
2.6.18 238.19.1.el5
2.6.18 274.12.1.el5
2.6.18 308.8.2.el5

작동하지 않는 이유:순진한 사람은 sort이 명령의 변형을 사용하여 이 작업을 수행할 수 있다고 생각할 것입니다. 그러나 특정 RPM에 대한 실제 버전 정보 형식에는 작업에 적합하지 않은 가변성과 불일치가 충분히 있습니다.

시도 #2(OP가 작동하지 않았다고 말함)

$ rpm -q --last kernel | head -n 1 | cut -d' ' -f1
kernel-2.6.35.14-106.fc14

작동하지 않는 이유:나는 OP가 찾고 있는 결과를 생성하기 위해 이 접근 방식을 매우 좋아하지만 @Joel이 주석에서 지적했듯이 이 접근 방식의 문제점은 스위치가 --last단순히 RPM 설치 날짜별로 정렬된 결과를 반환한다는 것입니다.

#3을 시도해 보세요

이것은 확실히 작업을 완료할 것입니다. RPM 개발 도구라는 도구 세트를 발견했습니다. 이 제품군에는 RPM의 한 버전이 다른 버전보다 최신인지, 이전 버전인지 확인할 수 있는 두 가지 도구가 있습니다.

RPM이 아직 설치되지 않은 경우 다음을 수행할 수 있습니다.

yum install rpmdevtools

첫 번째 유용한 도구는 입니다 rpmdev-vercmp. 이 도구는 2개의 RPM 이름을 비교하여 어느 것이 더 새로운 것인지 알려줄 수 있습니다. 예를 들어:

$ rpmdev-vercmp kernel-2.6.35.14-100.fc14.x86_64 kernel-2.6.35.14-103.fc14.x86_64
0:kernel-2.6.35.14-103.fc14.x86_64 is newer

이것을 찾은 후 쉘 스크립트를 작성하려고 했으나 게으르다는 것을 깨닫고 몇 분 더 투자하여 제품군에서 rpmdev-sort.

이 도구는 유료입니다. 다음과 같이 사용할 수 있습니다.

$ rpm -q kernel | rpmdev-sort 
kernel-2.6.35.14-100.fc14.x86_64
kernel-2.6.35.14-103.fc14.x86_64
kernel-2.6.35.14-106.fc14.x86_64

RPM 개발 도구에는 다른 사람들이 살펴볼 가치가 있는 도구가 많이 있으므로 나중에 참조할 수 있도록 여기에 나열합니다.

$ rpm -q --queryformat '[%{NAME} %{FILEMODES:perms} %{FILENAMES}\n]' rpmdevtools \
    | grep -E "^.* -..x..x..x " \
    | awk '{print $3}'          \
    | sed 's#/usr/bin/##'       \
    | paste - - -               \
    | column -t

annotate-output   checkbashisms    licensecheck
manpage-alert     rpmargs          rpmdev-bumpspec
rpmdev-checksig   rpmdev-cksum     rpmdev-diff
rpmdev-extract    rpmdev-md5       rpmdev-newinit
rpmdev-newspec    rpmdev-packager  rpmdev-rmdevelrpms
rpmdev-setuptree  rpmdev-sha1      rpmdev-sha224
rpmdev-sha256     rpmdev-sha384    rpmdev-sha512
rpmdev-sort       rpmdev-sum       rpmdev-vercmp
rpmdev-wipetree   rpmelfsym        rpmfile
rpminfo           rpmls            rpmpeek
rpmsodiff         rpmsoname        spectool

#3의 대안

의견에서 OP가 언급한 또 다른 옵션은 sort -V.that's a capital 을 사용하는 것입니다 -V. 나도 이 스위치에 대해 들어본 적이 없다. sort매뉴얼 페이지 에서 :

-V, --version-sort
       natural sort of (version) numbers within text

sort버전 번호를 정렬하는 기능을 제공하므로 다음과 같이 정렬을 수행할 수도 있습니다 .

$ rpm -q kernel | sort -V
kernel-2.6.35.14-100.fc14.x86_64
kernel-2.6.35.14-103.fc14.x86_64
kernel-2.6.35.14-106.fc14.x86_64

답변2

좋은 결과를 얻으려면 RPM 라이브러리를 사용해야 합니다. 버전 비교 알고리즘은... 정말 복잡합니다. 셸에서 다시 구현하는 것은 쉽지 않지만 Python을 사용하여 실제 비교를 수행할 수 있으면 비교적 간단해집니다. 바라보다https://stackoverflow.com/questions/3206319/how-do-i-compare-rpm-versions-in-python이를 수행하는 방법에 대한 예입니다.

답변3

rpm -q kernel --queryformat="%{buildtime}\t%{name}-%{version}-%{release}.%{arch}\n" | sort -nr | head -1 | cut -f2

빌드 시간을 기준으로 정렬하면 설치 시간과 달리 코너링 실패 사례가 발생할 가능성이 적다고 생각합니다. 그러나 --last가 더 간결합니다.

답변4

--last가장 높은 버전 번호는 알려주지 않지만 설치 날짜별로 정렬됩니다. 이렇게 하면 가장 최근에 설치된 버전을 볼 수 있습니다.

[root@xms_apps ~]# rpm -qa kernel-xen --last
kernel-xen-2.6.18-348.1.1.el5                 Tue 29 Jan 2013 02:18:52 PM EST
kernel-xen-2.6.18-308.11.1.el5                Fri 20 Jul 2012 04:00:26 PM EDT
kernel-xen-2.6.18-308.8.2.el5                 Wed 20 Jun 2012 03:32:47 PM EDT

대부분의 경우(커널을 수동으로 설치하지 않는 한) 둘은 동일해야 합니다.

100% 정확하려면 두 커널 버전을 모두 포맷 2.6.*한 다음 2.6부터 분해해야 합니다(RHEL은 단일 릴리스에서 대폭 리베이스하지 않으며 RHEL5는 항상 2.6 커널입니다). rpm 출력의 각 라인을 반복하고(아마도 --last성능에 따라 정렬됨) 각 위치를 얻은 커널 버전의 유사한 위치와 비교합니다( uname -rrpm 데이터베이스 문자열의 숫자가 uname 문자열보다 큰 경우). 즉시 종료하고 다음을 표시합니다. 메시지.

당신을 돕기 위해 비슷한 질문이 있습니다여기에서 물어보세요. 하지만 이 함수는 순수한 점으로 구분된 십진수 표기법을 가정하므로 하이픈 앞의 숫자 위치를 비교할 수 있습니다(하나만 있으므로). 그런 다음 해당 사람의 bash 함수를 사용하여 패치 버전이 unamerpm db 문자열의 버전보다 높은지 테스트할 수 있습니다.

관련 정보