Linux - 如何比较shell脚本安装的包新版本安装

时间:2013-04-29 06:18:39

标签: linux shell centos redhat rpm

我正在尝试编写一个可以将Avamar客户端安装到Redhat或Centos盒子上的shell脚本。我将要安装的pkg放入repo dir / ava / repo

脚本需要执行以下操作:

  1. 检查/ ava / repo中是否有最新的pkg。在这种情况下,最新的是AvamarClient-linux-sles11-x86_64-6.1.100-802.rpm(已编辑)

  2. 检查服务器以查找以前安装的Avamar Client。我可以用

    进行检查

    rpm -qa | grep AvamarClient

  3. AvamarClient-6.1.100-402.x86_64

    1. 一旦检查了版本,我需要将其与我正在安装的版本进行比较。例如,如果我添加的pkg(/ ava / repo中的最新版本)是AvamarClient-6.1.200-102.x86_64,我需要针对AvamarClient-6.1.100-402.x86_6进行检查,并确定哪个更新或是否更新同样。
    2. 如果我尝试安装的pkg是相同的,输出到已安装pkg的日志文件并结束

      如果我尝试安装的pkg较旧,则输出到已安装pkg的日志文件更新并结束

      如果我尝试安装的pkg较新,请卸载旧的pkg然后安装新的pkg并输出到logfile,该软件包已升级,然后结束

      我只有基本的贝壳技能,所以这个任务对我来说很难对付!任何帮助,将不胜感激。 感谢

2 个答案:

答案 0 :(得分:2)

这将向您展示如何在相当多的细节上进行文本提取和操作。我们将基本上从/ ava / repo中的候选文件中提取版本,并将它们转换为可用于使用公式进行比较的数字:

AVAMAR_INSTALLED_MAGIC=$((1000000 * $AVAMAR_INSTALLED_VER_MAJ + 10000 * $AVAMAR_INSTALLED_VER_MIN + $AVAMAR_INSTALLED_VER_REL))

我们将使用此数字表格首先找出/ ava / repo中的最新版本,然后将其与我们安装的版本进行比较,看看是否要替换它。

所以我们走了:

这是复杂的

首先是整个事情:

AVAMAR_CANDIDATE=$(ls -1 /ava/repo/AvamarClient* |   \ 
           sed -e 's/.*/&:&/'                                       \
               -e 's/-[0-9]*-x86_64//1'                             \
               -e 's/AvamarClient-//'                               \
               -e 's/\./:/1' -e 's/\./:/1' |                        \
           awk -F: '{ print 1000000 * $1 + 10000 * $2 + $3 " " $4 }' | \
           sort -n | tail -n1 )

让我们来看看发生了什么。我们假设我们在回购中有一个以上的候选副本。

我们列出/ava/repo中的所有文件并将其传输到sed + awk脚本,该脚本会找出它们的版本号并对它们进行排序,以便最后一个是最新的。

让我们看看每个部分

SED

第1步:

       -e 's/.*/&:&/'

创建由:分隔的名称的两个副本。 (我们将拆分第一个并使用步骤2和3将其减少到版本号。保留第二个完整的rpm命令以便稍后使用)

第2步:

      -e 's/-[0-9]*-x86_64[^:]*//1'

从文件名的第一个副本中删除单词-NNN-x86_64.rpm,以便精确地删除前导到我们之前插入的:(但不是冒号)的尾随位。

第3步:

     -e 's/AvamarClient-//' 

从文件名的第一个副本

中删除单词AvamarClient-

第4步:

     -e 's/\./:/1' -e 's/\./:/1'

将提取的版本号中的.转换为:

例如:

     ls -1 /ava/repo/AvamarClient-6.4.200-400-x86_64.rpm  | sed -e 's/.*/&:&/' -e 's/-[0-9]*-x86_64[^:]*//1' -e 's/AvamarClient-//' -e 's/\./:/1' -e 's/\./:/1'

会输出:

     6:4:200:AvamarClient-6.4.200-400-x86_64.rpm

AWK

现在要将提取的版本转换为神奇的东西,我们通过awk推送它:其中-F:使用:作为分隔符拆分上面的字符串。所以$ 1 = MAJ,$ 2 = MIN,$ 3 = REL,$​​ 4 =文件名;例如,上面它将是$ 1 = 6; $ 2 = 4; $ 3 = 200; $ 4 = AvamarClient-6.4.200-400-x86_64.rpm

所以我们应用我们的魔术公式并在awk中打​​印文件名:

    '{ print 1000000 * $1 + 10000 * $2 + $3 " " $4 }' 

所以对于上面的例子,它会输出:

    6040200 AvamarClient-6.4.200-400-x86_64

瞧,我们有一个神奇的可比数字

SORT和TAIL

由于我们的仓库中可能有多个文件,因此以上将是它们的列表,因为我们有神奇的数字,我们可以用它来获取最新的文件。使用sort -n排序并使用tail -n1抓取最后一个(排序为升序)。

所以现在在AVAMAR_CANDIDATE我们会有6040200 AvamarClient-6.4.200-400-x86_64

让我们让生活更轻松,并将其分为两个变量:

      AVAMAR_CANDIDATE_FILE=$(echo $AVAMAR_CANDIDATE | cut -f2 -d' ')
      AVAMAR_CANDIDATE_MAGIC=$(echo $AVAMAR_CANDIDATE | cut -f1 -d' ')

让我们对安装的版本做同样的事情:

AVAMAR_INSTALLED=$(rpm -qa | grep AvamarClient)

AVAMAR_INSTALLED_MAGIC=$(echo $AVAMAR_INSTALLED | \
      sed -e 's/^AvamarClient-//'  \ 
          -e 's/-[0-9].*x86_64$//' \
          -e 's/\./:/g' | \
      awk -F: '{ print 1000000 * $1 + 10000 * $2  + $3 }' )

现在你所要做的就是比较两个幻数的值:

if [ $AVAMAR_INSTALLED_MAGIC -lt $AVAMAR_CANDIDATE_MAGIC ] ; then
         rpm -ivU /ava/repo/$AVAMAR_CANDIDATE_FILE 
fi

我希望这会让你学习shell脚本,因为它是一个非常强大的工具。

答案 1 :(得分:-2)

您必须从已安装的软件包中获取主要号码,次要号码和内部版本号。 同样,您需要知道要安装的软件包中的主要编号,次要编号和内部版本号。 首先比较Major number,然后是Minor,然后是Build number

我已经按照我的解释编写了逻辑

#!/bin/bash

INSTALLED_VERSION="AvamarClient-6.1.100-402.x86_64"
CURRENT_VERSION="AvamarClient-6.1.90-102.x86_64"

#get the Major numbe,Minor number and build number from the Installed version string
INST_MAJOR=`echo $INSTALLED_VERSION | cut -d'-' -f2 | cut -d'.' -f1`
INST_MINOR=`echo $INSTALLED_VERSION | cut -d'-' -f2 | cut -d'.' -f2`
INST_BUILD=`echo $INSTALLED_VERSION | cut -d'-' -f2 | cut -d'.' -f3`
echo "INST_MAJOR=$INST_MAJOR,INST_MINOR=$INST_MINOR,INST_BUILD=$INST_BUILD"

#get the Major numbe,Minor number and build number from the Current version string
CUR_MAJOR=`echo $CURRENT_VERSION | cut -d'-' -f2 | cut -d'.' -f1`
CUR_MINOR=`echo $CURRENT_VERSION | cut -d'-' -f2 | cut -d'.' -f2`
CUR_BUILD=`echo $CURRENT_VERSION | cut -d'-' -f2 | cut -d'.' -f3`
echo "CUR_MAJOR=$CUR_MAJOR,CUR_MINOR=$CUR_MINOR,CUR_BUILD=$CUR_BUILD"

if [ $CUR_MAJOR -gt $INST_MAJOR ]
then
    echo "Starting with Installation..."
elif [ $CUR_MAJOR -eq $INST_MAJOR ]
then
    if [ $CUR_MINOR -gt $INST_MINOR ]
    then
        echo "Starting with Installation..."
    elif [ $CUR_MINOR -eq $INST_MINOR ]
    then
        if [ $CUR_BUILD -gt $INST_BUILD ]
        then
            echo "Starting with Installation..."
        elif [ $CUR_BUILD -eq $INST_BUILD ]
        then
            echo "Package already installed..."
        else
            echo "You are trying to install older package...Exiting"
        fi
    else
        echo "You are trying to install older package...Exiting"
    fi
else
    echo "You are trying to install older package...Exiting"
fi