제가 쓰고 싶은 스크립트는 이렇습니다.
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 -r
rpm 데이터베이스 문자열의 숫자가 uname 문자열보다 큰 경우). 즉시 종료하고 다음을 표시합니다. 메시지.
당신을 돕기 위해 비슷한 질문이 있습니다여기에서 물어보세요. 하지만 이 함수는 순수한 점으로 구분된 십진수 표기법을 가정하므로 하이픈 앞의 숫자 위치를 비교할 수 있습니다(하나만 있으므로). 그런 다음 해당 사람의 bash 함수를 사용하여 패치 버전이 uname
rpm db 문자열의 버전보다 높은지 테스트할 수 있습니다.