0

我正在尝试编写一个可以将 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

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 进行检查,并确定哪个更新或是否更新相同。

如果我尝试安装的 pkg 相同,则输出到已安装 pkg 的日志文件并结束

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

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

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

4

2 回答 2

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 )

那么让我们看看发生了什么。我们假设我们在 repo 中有不止一个候选人的副本。

我们列出所有文件/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: where-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

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

排序和尾部

由于我们的 repo 中可能有多个文件,以上将是它们的列表,并且因为我们有幻数,我们可以使用它来获取最新的文件。用于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 脚本,因为它是一个非常强大的工具。

于 2013-04-29T07:41:43.877 回答
-2

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

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

#!/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
于 2013-04-29T07:25:10.510 回答