서버관리_06 RPM 패키지명이 적힌 목록 파일에서 각각의 패키지가 설치, 갱신된 날짜를 확인하기

 
  • 출처 : 유닉스 리눅스 쉘스크립트 예제사전_한빛미디어

명령어: cat, rpm
키워드: RPM패키지, 갱신 시각, 설치, 업데이트
사용처: 여러 서버에 패키지 설치 및 업데이트를 진행하는데 서버마다 작업에 실수가 없는지 확인하고 싶을 때

실행 예제

# 설치 후 확인해야 할 패키지 목록을 작성합니다.
$ cat pkg.lst
httpd
zsh
xz
git

$ ./rpm-lastdate.sh pkg.lst
2021/04/19 11:14:11 : httpd
2021/04/20 13:43:23 : zsh
2020/06/03 15:21:09 : xz
2021/03/24 09:33:12 : git

스크립트

#!/bin/sh

# 지정한 목록 파일 존재 확인
if [ ! -f "$1" ]; then  # if문 -------------------------------------------- 1
    echo "대상 패키지 목록 파일이 존재하지 않습니다: $1" >&2        
    exit 1
fi

# 인수로 지정한 파일($1)에서 패키지 목록 얻기
pkglist=$(cat "$1")     # ------------------------------------------------ 2

# 설치된 rpm 갱신일자 출력
rpm -q $pkglist --queryformat '%{INSTALLTIME:date} : %{NAME}\n'  # ------- 3

해설

이 스크립트는 명령행 인수로 지정한 텍스트 파일에서 RPM 패키지명을 읽어서 그 RPM 패키지가 설치 또는 갱신된 날짜를 목록으로 표시합니다.

리눅스 서버를 구축 및 운용하다 보면 수십 대의 서버에 같은 패키지를 설치하거나 보안 패치를 위해 피키지를 갱신하는 서버 점검을 빈번히 하게 됩니다. 이때 ‘10대 서버 중 한대만 갱신하지 않았다’, ‘나중에 설치하려다가 한 대만 설치하는 걸 잊었다’ 같은 작업 실수가 자주있습니다. 이 예제처럼 확인 스크립트를 준비해두면 점검 종료 확인 시 도움이 될 것입니다.

이 스크립트는 우선 1 에서 위치 파라미터 $1으로 지정한 목록 파일이 존재하는지 확인합니다. -f는 대상이 일반 파일인지 확인하는 연산자입니다. 여기에 부정 연산자 !로 일반 파일이 아니면 에러를 표시하고 종료합니다.

2 에서 명령행 인수로 지정한 파일 $1으로 셸 변수 pkglist에 패키지명을 읽어들입니다. 이 실행 예제에서 pkg.lst 파일 내용은 다음과 같습니다.

httpd
zsh
xy
git

즉 여기서는 httpd, zsh, xy, git 패키지를 설치 또는 갱신한 날짜를 확인한다고 가정합니다. 실제 사용할 때는 상황에 맞게 수정하면 됩니다.

2cat 명령어로 pkg.lst 파일 내용을 출력해서 명령어 치환 $()을 이용해서 출력 결과를 셸 변수 pkglist에 대입합니다. cat 명령어 결과를 사용하므로 셸 변수 pkglist에는 여러 줄로된 목록이 그대로 대입됩니다.

3 에서 지정한 RPM 패키지를 설치 및 갱신한 날짜를 rpm 명령어로 표시합니다. 여기서 rpm 명령어에 지정하는 것은 -q 옵션과 표시 포맷을 지정하는 –queryformat 옵션입니다.

rpm 명령어 -q 옵션은 대상 패키지를 지정합니다. 이때 여러 패키지를 지정할 수 있습니다. 여기서는 셸 변수 pkglist에 2 에서 조합한 패키지 목록이 들어 있으므로 이걸 그대로 지정합니다. 셸에서 줄바꿈을 표준 구분자로 해석하므로 3 처럼 $pkglist에 따옴표를 쓰지 않고 작성하면 줄바꿈을 구부낮로 셸 변수 확장을 해서 결과적으로 다음과 같은 명령어가 실행됩니다.

rpm -q httpd zsh xz git --queryformat '%{INSTALLTIME:date} : %{NAME}\n'

이때 3 을 잘못해서 큰따옴표로 “$pkglist”라고 하면 명령어 중간에 줄바꿈이 들어가서 에러가 발생하므로 주의해야 합니다.

–queryformat 옵션은 rpm 명령어를 표시하는 항목을 지정하는 옵션입니다. 서식 지정에서 사용하는 INSTALLTIMENAME은 각각 설치/갱신 시간, 패키지명을 나타냅니다. 또한 기본적으로 INSTALLTIME은 유닉스 시간(1970년 1월 1일부터 경과한 초)으로 표시되므로 :DATE라고 지정해서 년월일시로 표시하도록 합니다. 이 외에도 다양한 항목이 표시 가능하므로 –querytags 옵션으로 확인해보기 바랍니다.

이렇게 해서 점검 대상 서버에서 예제 스크립트를 실행하면 각 패키지 설치/갱신 일시를 표시할 수 있습니다. 어떤 서버만 패키지 갱신 일시가 오래되었으면 패치 업데이트 작업을 안 했다는 걸 알 수 있을 것입니다. 그리고 패키지를 찾지 못했다고 표시되면 설치 작업을 하지 않았다는 것도 알 수 있습니다.

이렇듯 서버 구축 및 운용 시 작업 실수를 줄일 수 있게 됩니다.

  • 설치 실수 했을 때 표시 예
    $ ./rpm-lastdate.sh pkg.lst
    2021/04/19 11:14:11 : httpd
    package zsh is not installed
    2020/06/03 15:21:09 : xz
    2021/03/24 09:33:12 : git
    

주의사항

  • 이 스크립트는 리눅스(CentOS)의 rpm 명령어를 사용하므로 CentOS나 레드햇에서만 동작합니다.
  • 이 스크립트는 확인할 패키지 목록을 지정하는 파일이 비었을 때 rpm 명령어가 실패해 에러를 발생합니다.