#!/bin/bash set -e #镜像挂载目录 MOUNT="/mnt" #当前镜像版本 ISO_ROCKY="*4.2* | *6.0.42* | *4.3*" ISO_DEBIN="*6.0.60* | *6.0.80*" ISO_REDHA="*6.0.77* | *6.0.76*" #当前目录 NOWDIR=`pwd` #安装包临时解压目录 PKGDIR="$NOWDIR/pkg" #操作系统存储目录 ISODIR="$NOWDIR/iso" #数据库位置 data_DIR="../datalib" #数据库名 data_NAME="fileinfo.db" data_SQL="fileinfo.sql" data_ADD="$data_DIR/$data_NAME" data_FILE="$data_DIR/$data_SQL" #日志文件 file_LOG="$NOWDIR/filelog" #当前已经安装的文件列表 file_NOW="$NOWDIR/now_pkglist" #当前镜像中未录入的文件列表 file_NEW="$NOWDIR/new_pkglist" #读取镜像issue文件 function data_intoissue(){ echo "获取镜像版本(通过issue)" case $1 in rocky) iso_issue=`cat /etc/issue | sed ':a;N;s/\n/ /g;ta'` sqlite3 $data_ADD "update product set product_issue='$iso_issue' where product_id=$data_isoid;" ;; debian) #iso_base_files=`find $iso_mountname -name base-files*.deb` #if [ -d $PKGDIR ] #then # rm -rf $PKGDIR #fi #PKGDIR=$PKGDIR #echo "解压base-files_8+deb8u9-linx18_amd64.deb" #mkdir -p $PKGDIR #dpkg -X $iso_base_files $PKGDIR iso_issue=`cat /etc/issue | sed ':a;N;s/\n/ /g;ta'` sqlite3 $data_ADD "update product set product_issue=\"$iso_issue\" where product_id=$data_isoid;" ;; redhat) iso_issue=`cat /etc/issue | sed ':a;N;s/\n/ /g;ta'` sqlite3 $data_ADD "update product set product_issue=\"$iso_issue\" where product_id=$data_isoid;" ;; *) ;; esac } function data_intofile(){ local data_file=$1 if [ ! -e $data_file ] then echo "文件不存在" return 0 fi if [ "$2" == "1" ] then local data_filepath=$1 local data_filelevel=1 else local data_filepath=` echo $data_file | awk -F "$PKGDIR" '{ print $2 }' ` local data_filelevel=2 fi if [ "$PKGDIR" == "$data_file" ] then echo "临时目录" return 0 elif [ "$data_filepath" == "/usr" ] || [ "$data_filepath" == "/etc" ] || [ "$data_filepath" == "/bin" ] || [ "$data_filepath" == "/sbin" ] || [ "$data_filepath" == "/lib" ] || [ "$data_filepath" == "/lib64" ] || [ "$data_filepath" == "/var" ] || [ "$data_filepath" == "/opt" ] || [ "$data_filepath" == "/dev" ] || [ "$data_filepath" == "/proc" ] || [ "$data_filepath" == "/sys" ] || [ "$data_filepath" == "/opt" ] || [ "$data_filepath" == "/tmp" ] || [ "$data_filepath" == "/mnt" ] || [ "$data_filepath" == "/usr/share" ] || [ "$data_filepath" == "/usr/bin" ] || [ "$data_filepath" == "/usr/lib" ] || [ "$data_filepath" == "/usr/etc" ] || [ "$data_filepath" == "/usr/lib64" ] || [ "$data_filepath" == "/usr/share" ] || [ "$data_filepath" == "/usr/include" ] || [ "$data_filepath" == "/usr/local" ] || [ "$data_filepath" == "/." ] then echo "无用目录" return 0 fi local data_filename=$(basename $data_file) local data_filepermis=$(stat -c %a $data_file) local data_filetype=$(ls -lad $data_file) local data_filetype=$(echo ${data_filetype:0:1}) local data_filegenus=$(stat -c %g $data_file) local data_fileowner=$(stat -c %u $data_file) local data_filesize=$(stat -c %s $data_file) #发现默认未有文件设置该信息 if [[ $data_filetype == "b" ]] || [[ $data_filetype == "s" ]] || [[ $data_filetype == "-" ]] then local data_filemd5=$(md5sum $data_file | awk '{ print $1 }') local data_filecap=$(getcap "$data_file") local data_filemac=$(getfmac "$data_file") local data_fileacl=$(getfacl --absolute-name "$data_file" 2>/dev/null) elif [[ $data_filetype == "d" ]] then local data_filemd5= local data_filecap=$(getcap "$data_file") local data_filemac=$(getfmac "$data_file") local data_fileacl=$(getfacl --absolute-name "$data_file" 2>/dev/null) fi #当文件为解压收集信息时,cap、mac、acl信息会出现错误。 if [[ $data_filelevel == "2" ]] then local data_filecap="" local data_filemac="" local data_fileacl="" fi local data_fileid=$(expr `sqlite3 $data_ADD "select file_id from file order by file_id desc limit 1;"` + 1) local data_pkgid=$(sqlite3 $data_ADD "select pkg_id from pkg where pkg_name='$pkg_name' and pkg_version='$pkg_version' ;") echo -e " 当前产品:$product_iso \n \ 当前文件:$data_file \n \ 当前文件名:$data_filename \n \ 当前文件绝对路径:$data_filepath \n \ 当前临时文件目录:$PKGDIR \n \ 当前安装包:$pkg_name \n \ 文件id: $data_fileid \n \ 文件类型:$data_filetype \n \ 文件属主:$data_fileowner \n \ 文件属组:$data_filegenus \n \ 文件权限:$data_filepermis \n \ 文件大小:$data_filesize \n \ 文件md5: $data_filemd5 \n \ 文件cap: $data_filecap \n \ 文件acl: $data_fileacl \n \ 文件mac: $data_filemac \n \ 将$1存入数据库" >> $file_LOG if [ -z $data_pkgid ] then echo "文件未经过安装包" else echo "将文件$data_filepath输入数据库" sqlite3 $data_ADD "insert into file values ($data_fileid,\"$data_filename\",$data_pkgid,\"$data_filepath\",\"$data_filemd5\",\"$data_filetype\",\"$data_fileowner\",\"$data_filegenus\",$data_filepermis,$data_filesize,\"$data_fileacl\",\"$data_filecap\",\"$data_filelevel\",\"$data_filemac\")" fi } function data_intopkg(){ local data_pkg=$1 local data_pkgmd5=`md5sum $data_pkg | awk '{ print $1 }'` #要判断pkg表是否有重复包 local pkg_md5=`sqlite3 $data_ADD "select pkg_md5 from pkg where pkg_md5 is '$data_pkgmd5'"` if [ "$pkg_md5" != "$data_pkgmd5" ]; then case $data_pkg in *pkg.tar.gz) local data_pkgname=`echo "$(basename $data_pkg .pkg.tar.gz)" |awk -F "#" '{print $1}'` local data_pkgversion=`echo "$(basename $data_pkg .pkg.tar.gz)" |awk -F "#" '{print $2}'` ;; *.deb) local data_pkgname=`echo "$(basename $data_pkg .deb)" | awk -F "_" '{print $1}'` local data_pkgversion=`echo "$(basename $data_pkg .deb)" | awk -F "_" '{print $2"_"$3}'` ;; *.rpm) local data_pkgversion=`echo "$(basename $data_pkg .rpm)" | awk -F "-" '{for(i=NF-1;i> $file_LOG sqlite3 $data_ADD "insert into pkg values ($data_pkgid,'$data_pkgname','$data_pkgversion','$data_pkgmd5')" #更新product_and_pkg表 echo "更新product_and_pkg表" local data_papid=$(expr `sqlite3 $data_ADD "select pap_id from product_and_pkg order by pap_id desc limit 1;"` + 1) sqlite3 $data_ADD "insert into product_and_pkg values ($data_papid,$data_isoid,$data_pkgid)" echo "$data_pkgname $data_pkgversion" >> ./new #如果为新的安装包则解压扫描包内文件 else local pkg_id=`sqlite3 $data_ADD "select pkg_id from pkg where pkg_md5 is '$data_pkgmd5'"` local iso_pkgid=`sqlite3 $data_ADD "select product_id from product_and_pkg where pkg_id = '$pkg_id' and product_id = '$data_isoid'"` #判断是否有向product_and_pkg输入相同的信息 if [ "$data_isoid" == "$iso_pkgid" ]; then echo "相同安装包id为:$pkg_id">>$file_LOG echo "data_isoid=$data_isoid iso_pkgid=$iso_pkgid 未入库">>$file_LOG else local data_papid=$(expr `sqlite3 $data_ADD "select pap_id from product_and_pkg order by pap_id desc limit 1;"` + 1) sqlite3 $data_ADD "insert into product_and_pkg values ($data_papid,$data_isoid,$pkg_id)" echo "相同安装包id为:$pkg_id">>$file_LOG echo "data_isoid=$data_isoid iso_pkgid=$iso_pkgid 入库">>$file_LOG fi fi } function data_intoiso(){ data_iso=$1 data_isomd5=`md5sum $data_iso | awk '{ print $1 }'` data_isoname=`echo "$(basename $data_iso .iso)" | awk -F "-" '{print $1"-"$2}'` data_isoversion=`echo "$(basename $data_iso .iso)" | awk -F "$data_isoname" '{print $2}'` data_isoid=$(expr `sqlite3 $data_ADD "select product_id from product order by product_id desc limit 1;"` + 1) #获取最后一个id值加1 echo -e "当前镜像:$data_iso\n 镜像名:$data_isoname\n 镜像版本:$data_isoversion\n 镜像md5:$data_isomd5\n 镜像id:$data_isoid\n">>$file_LOG sqlite3 $data_ADD "insert into product values ($data_isoid,'$data_isoname','$data_isoversion','$data_isomd5',' ')" } #整理文件信息获取 function data_get(){ data_stat=$2 echo "入库类型:$data_stat" case $data_stat in iso_stat) data_intoiso $1 ;; pkg_stat) data_intopkg $1 ;; file_stat) data_intofile $1 $3 ;; iso_issue) data_intoissue $1 ;; *) echo "程序出错" return 3 ;; esac } #将镜像挂载到指定目录下 function iso_mount(){ echo "iso_mount" iso_mountname=$MOUNT while [[ `mount | grep $iso_mountname` != "" ]] do umount $iso_mountname done if [ -d $iso_mountname ]; then mount -o loop $iso_name $iso_mountname else mkdir $iso_mountname mount -o loop $iso_name $iso_mountname fi data_get $iso_vis "iso_issue" #将镜像issue信息存入库 } #判断当前镜像版本 #将镜像信息入库 function iso(){ iso_name=$1 case $iso_name in *4.2* | *6.0.42* | *4.3*) echo "42" iso_vis="rocky" ;; *6.0.60* | *6.0.80* ) echo "60|80" iso_vis="debian" ;; *6.0.77* | *6.0.76* ) echo "76|77" iso_vis="redhat" ;; *) echo "镜像不存在" exit ;; esac data_get $product_iso "iso_stat" #将镜像信息入库 } #获取当前系统已经安装的安装包,并将镜像中全部安装包进行排序 function pkg(){ echo "tar:$1" pkg_filename=$1 PKGDIR=$PKGDIR case $iso_vis in #当前已经安装的文件 rocky) pkginfo -i | sort >> $file_NOW ;; debian) awk 'BEGIN{i=0;j=0;k=0}{if($1 == "Package:"){A[i]=$2;i+=1};if($1 == "Version:"){B[j]=$2;j+=1}if($1 == "Architecture:"){C[k]=$2;k=k+1}}END{for(i=0;i> $file_NOW ;; redhat) rpm -qa | awk -F "-" '{for(i=1;i> $file_NOW ;; *) echo "解压选择出错$pkg_filename" ;; esac if [ -e ./new ] then cat ./new | sort >> $file_NEW rm ./new else touch $file_NEW fi } #获取需要收集安装包的文件信息 function file_now(){ #处理带有空格的文件名 MY_SAVEIFS=$IFS IFS=$'\n' #收集虚拟机已经安装的文件 for pkg_list in `comm -12 $file_NEW $file_NOW ` do pkg_name=`echo $pkg_list | awk '{print $1}' ` pkg_version=`echo $pkg_list | awk '{print $2}'` case $iso_vis in rocky) file_listname=$( pkginfo -l $pkg_name | sed "s/\*/\\\*/g" ) #发现有的文件存在*号,会导致文件信息获取出错。 for file_list in $file_listname do if [ -d "/$file_list" ];then file_list=${file_list%?} fi data_get "/$file_list" "file_stat" 1 done ;; debian) for file_list in `dpkg -L $pkg_name | awk -F ":" '{if($1=="软件包将其他的包转移至"){print $2}else{print $1}}'` do data_get $file_list "file_stat" 1 done echo "当前已安装的包收集完毕" ;; redhat) for file_list in `rpm -ql $pkg_name` do data_get $file_list "file_stat" 1 done ;; *) echo "文件收集错误" ;; esac done IFS=$MY_SAVEIFS  } function file_new(){ comm -23 $file_NEW $file_NOW |while read pkg_list do pkg_name=`echo $pkg_list | awk '{print $1}'` pkg_version=`echo $pkg_list | awk '{print $2}'` if [ -d $PKGDIR ] then rm -r $PKGDIR fi PKGDIR=$PKGDIR case $iso_vis in rocky) pkg_filename=`echo $pkg_name"#"$pkg_version"*"` pkg_filename=`find $iso_mountname -name $pkg_filename` pkg_filename=`echo $pkg_filename | awk '{print $1}'` echo "解压tar类型安装包" mkdir -p $PKGDIR tar xf $pkg_filename -C $PKGDIR ;; debian) pkg_filename=`echo $pkg_name"_"$pkg_version"*"` pkg_filename=`find $iso_mountname -name $pkg_filename` pkg_filename=`echo $pkg_filename | awk '{print $1}'` echo "解压deb类型安装包" mkdir -p $PKGDIR dpkg -X $pkg_filename $PKGDIR ;; redhat) pkg_filename=`echo $pkg_name"-"$pkg_version"*"` echo $iso_mountname pkg_filename=`find $iso_mountname -name $pkg_filename` pkg_filename=`echo $pkg_filename | awk '{print $1}'` echo "解压rpm类型安装包" mkdir -p $PKGDIR cp $pkg_filename $PKGDIR cd $PKGDIR rpm2cpio *.rpm | cpio -div rm *.rpm cd - ;; *) echo "解压选择出错$pkg_filename" ;; esac #处理带有空格的文件名 MY_SAVEIFS=$IFS IFS=$'\n' for pkg_file in `find $PKGDIR` do data_get $pkg_file "file_stat" 2 done IFS=$MY_SAVEIFS rm -r $PKGDIR done } #判断输入介质为目录 #输入目录名 function iso_pkg(){ echo "dir:$1" iso_pkgdir=$1 case $iso_vis in rocky) echo "pkg.tar.gz安装包" for iso_pkgfile in `find $iso_pkgdir -name *.pkg.tar.gz` do data_get $iso_pkgfile "pkg_stat" done ;; debian) echo "deb安装包" for iso_pkgfile in `find $iso_pkgdir -name *.deb` do data_get $iso_pkgfile "pkg_stat" done ;; redhat) echo "rpm安装包" for iso_pkgfile in `find $iso_pkgdir -name *.rpm` do data_get $iso_pkgfile "pkg_stat" done esac } function set_env(){ if [ -f $data_ADD ]; then rm $data_ADD fi if [ -f $file_NEW ]; then rm $file_NEW fi if [ -f $file_NOW ]; then rm $file_NOW fi if [ -f $file_LOG ]; then rm $file_LOG fi if [ -f ./new ]; then rm ./new fi cd $data_DIR sqlite3 $data_NAME < $data_FILE cd - echo "重建数据库" #创建数据库 } function main(){ echo " 请选择产品类型" echo "=========================================" echo " 1.操作系统 2.附加产品 3.其他" read product_stat case ${product_stat:0:1} in 1) set_env #设置数据库 product_iso=`find $ISODIR -mindepth 1` iso $product_iso #判断镜像版本 iso_mount $iso_vis #将镜像挂载在指定目录 iso_pkg $iso_mountname #将镜像中未录入的安装包入库,并记录到$file_NEW pkg $data_pkg #获取当前已安装的安装包列表,并记录到$file_NOW file_now #获取已安装的包文件信息 file_new #获取未安装的包文件信息 ;; 2) echo "附加产品" ;; 3) echo "其它产品" ;; *) echo "请输入1/2/3" esac echo "信息录取成功" } main