LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1263|回复: 1

实用第一 linuxhowto Redhat-CD howto 更换更新的RPM包

[复制链接]
发表于 2003-11-28 10:57:31 | 显示全部楼层 |阅读模式
5.2 更换更新的RPM包



下面的这个脚本叫做 updateCD ,其功能为从更新目录中复制所有的文件到 RPMS 目录。这个脚本用了一些巧妙的RPM技巧来确定在UPDATES目录下的哪个包更新。就的包被移到 ${OLD} 目录中。



#! /bin/bash
# This script updates rpms in a RedHat distribution found in $RPMDIR.
# The old rpms will be placed in $OLDDIR.
# The new rpms should be located in $UPDDIR.
# The new images are in $IMGDIR
# The images to be updated are in $OMGDIR
# The architechture is $ARCH.

RHVERSION=6.0
ARCH=i386

CDDIR=/jaz/redhat-${RHVERSION}
RPMDIR=${CDDIR}/${ARCH}/RedHat/RPMS
UPDDIR=${CDDIR}/updates/${ARCH}
IMGDIR=${CDDIR}/updates/images/${ARCH}
OMGDIR=${CDDIR}/${ARCH}/images
OLDDIR=${CDDIR}/old

if [ ! -d $OLDDIR ] ; then
   echo making directory $OLDDIR
   mkdir $OLDDIR
fi

allow_null_glob_expansion=1

for rpm in ${UPDDIR}/*.rpm ; do
  NAME=`rpm --queryformat "%{NAME}" -qp $rpm`
  unset OLDNAME
  for oldrpm in ${RPMDIR}/${NAME}*.rpm ; do
    if [ `rpm --queryformat "%{NAME}" -qp $oldrpm` = "$NAME" ]; then
      OLDNAME=$oldrpm;
      break
    fi
  done
  if [ -z "$OLDNAME" ]; then
    echo $NAME is new
    cp -pv $rpm $RPMDIR
  else
    if [ `basename $rpm` != `basename $OLDNAME` ]; then
      mv $OLDNAME $OLDDIR
      cp -pv $rpm $RPMDIR
    fi
  fi
done


# Copy new boot image files to the right place...
for newfile in ${IMGDIR}/* ; do
  file=${OMGDIR}/$(basename ${newfile})
  if [ $newfile -nt $file ] ; then
     cp -pv $newfile $file
  fi
done

exit 0






RedHat 6.0的重要注意事项:




一些RPM包,特别是kernel和kernel-smp包,需要文件名但不是在包名中包括文件的平台域名,例如,“kernel”包需要如下所示:



kernel-2.2.5-22.i386.rpm
kernel-2.2.5-22.i586.rpm
kernel-2.2.5-22.i686.rpm



但是对于所有这三个执行rpm -qp 返回的都是"kernel"作为包名。


如你所看到,这种情况“迷惑”了 updateCD 脚本,其结果是只有最后一个得到正确的拷贝。先前的两个虽然被拷贝了,但是被移到了 $OLD 目录中。另外,RedHat还应当给予其不同的域名。现在最好的解决办法就是在运行了updateCD 之后手工地移动这些包。(感谢Kyle B. Ferrio kyle@U.Arizona.EDU)


Joshua Sarro <mthed@shore.net> 提供了一个PERL脚本叫做updateMirror.pl可以用来处理这种情况。你可以从 http://imsb.au.dk/~mok/linux/doc ... 得这个脚本。
 楼主| 发表于 2003-11-28 11:13:47 | 显示全部楼层
updateMirror.pl
这段脚本,看不懂,匹配不好
看看我的结果
#!/usr/bin/perl
#
# From mthed@shore.net Fri Aug  6 10:30:05 1999
# Date: Fri, 30 Jul 1999 18:18:29 -0400 (EDT)
# From: Joshua Sarro <mthed@shore.net>
# To: mok@imsb.au.dk
# Cc: pahe+rhcd@daimi.au.dk
# Subject: Burning a RedHat CD mini-HOWTO
#
# Hello,
#
# I have a few comments in case your still maintaining this
# howto. First of all the updateMirror script you have listed doesn't
# seem to work correctly with the new version of the distribution. It
# get's a little stuck up because of some of the kernel files being
# built for different architectures. (For instance in the i386 distro
# there are i386, i586, and i686 versions of the kernel).  Included at
# the end of this message is a version of the script i wrote which
# seems to do the trick.
#
# Next off, it also seems that your old updateHdlist has some problems
# when used for an architecture other than the machine you are on. For
# instance a person on an i386 machine couldn't correctly build the
# sparc hdlist. At the end of this file I include the script you wrote
# with the slight modifications I made.
#
# That's about it. If you plan on putting those updates in, let me
# know, otherwise I may venture to try it myself if I have the
# time. Thanks for your time.

use strict;

my $version="6.0";
my $arch=$ARGV[0];

my $basedir="/misc/redhat";
my $redhatdir="$basedir/redhat-$version";
my $rpmdir="$redhatdir/$arch/RedHat/RPMS/";
my $updatedir="$basedir/updates/$version/$arch/";

###########################################################################

# Main Program

if(! $arch) {
    print "updateCD usage - updateCD.pl <ARCHITECTURE>\n";
    exit();
   }

my %update;
my %rpm;
my $regex;

# Open updates directory for listing

opendir(UPDATES,$updatedir) || die("Could not open $updatedir.\n");

while($update{FN}=readdir(UPDATES))
{
   if($update{FN} !~ /\.rpm$/)
   {
      next; # Skip any non-rpm files
   }

   ($update{NAME},$update{VERSION},$update{RELEASE},$update{ARCH})=
      get_info("$updatedir$update{FN}"); # Call on get_info to get rpm info

   # Open rpm directory for listing

   opendir(RPMS,$rpmdir) || die("Could not open $rpmdir.\n");

   while($rpm{FN}=readdir(RPMS))
   {
      $regex="\Q$update{NAME}";

      if($rpm{FN} !~ /^$regex/ || $rpm{FN} !~ /\.rpm$/)
      {
         next; # Skip non-rpm's and unrelated files
      }

      ($rpm{NAME},$rpm{VERSION},$rpm{RELEASE},$rpm{ARCH})=
         get_info("$rpmdir$rpm{FN}"); # Call on info to get rpm info

      # Make sure file is the same package, but a different version. Erase
      # The old file and copy the new one in its place

      if($rpm{NAME} eq $update{NAME} && $rpm{ARCH} eq $update{ARCH} &&
         "$rpm{VERSION}$rpm{RELEASE}" ne "$update{VERSION}$update{RELEASE}")
      {
         system("cp $updatedir$update{FN} $rpmdir") &&
            die("Could not copy $updatedir$update{FN} -> $rpmdir.\n");
         print "cp $updatedir$update{FN} -> $rpmdir\n";

         unlink("$rpmdir$rpm{FN}") ||
            die("Could not remove $rpmdir$rpm{FN}.\n");
         print "rm $rpmdir$rpm{FN}\n";
      }
   }

   closedir(RPMS);
}
closedir(UPDATES);

###########################################################################

# Use an rpm  query to find information on an rpm file

sub get_info
{
   my($filename)=@_;

   my $info;
   my @dummy;

   $info=`rpm --queryformat \'\%{NAME} \%{VERSION} \%{RELEASE} \%{ARCH}\' -qp $filename`;

  @dummy=split(/ /,$info); # Seems if we don't assign to an array, the
                           # variables aren't passed correctly. So we use
                           # dummy here.
}

# Local Variables:
# mode: font-lock
# End:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表