Linux kernel awk、sed批量制作补丁包和批量拷贝新增文件

1、说明

在开发过程中,新增的内核包与原生的内核包有差异,希望能够批量的制作所有的修改文件补丁包,同时,也拷贝所有的差异文件。本文的内容主要是解决该问题。

2、开发环境

1、软件环境:ubuntu14.04
2、供应商提供可编译的sc9820 内核包。
3、linux官网的 linux-3.10.65原生内核包。

3、操作步骤

3.1 提交原生的内核包

git init kernel_linux_3.10.65

然后将原生内核包拷贝至git 新建的目录

cp  -r  linux-3.10.65 ./

提交代码

git add .
git commit

3.2 拷贝供应商提供的内核包
拷贝供应商提供的sc9820内核包(基于linux-3.10.65版本修改得到)至git目录。

cd linux-3.10.65
cp  -r  sc9820/*  ./

3.3 导出内核包之间的差异

git status > git_diff.txt

3.4 分离补丁文件和新增文件。
对于git的差异,可以发现共有两个部分:modified、Untracked。modified为修改文件, Untracked 为新增的文件和文件夹。
格式大致为

modified:   Documentation/DMA-API-HOWTO.txt
modified:   Documentation/DMA-API.txt
modified:   Documentation/arm64/booting.txt
Untracked files:                                                                                                   
 (use "git add <file>..." to include in what will be committed)

AndroidKernel.mk
Documentation/android.txt

将文件用vi编辑器分为2个部分,注意,如果用windows端,可能会出现行尾增加换行符问题。
其中,modified部分全部提出,新建一个文件modify.txt,内容格式如下,只有modified部分,其余的删除。

modified:   Documentation/DMA-API-HOWTO.txt
modified:   Documentation/DMA-API.txt
modified:   Documentation/arm64/booting.txt

将Untracked 部分,另外拷贝输出到一个文件 untracked.txt,格式如下

AndroidKernel.mk
Documentation/android.txt

3.5 制作补丁包

(1)进入linux 内核目录的上一级目录

#cd  /dir1/
#ls
linux-3.10.65  modify.txt  patch_create.sh

其中modift.txt文件为之前得到的,与原生内核有差异的git记录,格式为

modified:   Documentation/DMA-API-HOWTO.txt
modified:   Documentation/DMA-API.txt
modified:   Documentation/arm64/booting.txt

(2)patch_create.sh 脚本,为批量制作patch补丁包功能。
其中,生成的补丁包在当前目录中,新生成一个文件夹patch_dir,补丁包存放在该文件夹中。如果需要打补丁的文件路径为Documentation/arm64/booting.txt,则补丁包名称为
Documentation-arm64-booting.txt,即 dit1-dir2-src.patch格式。

最终生成补丁包,是采用diff 命令实现:
a. 拷贝原始文件至内核目录
b. 使用diff命令生成补丁文件

diff -uN old_file new_file > patch_file

c. 删除拷贝过去的原始文件
脚本内容如下,根据自己的路径修改脚本即可使用。

#!/bin/bash
echo "input file name is $1"
count=1
org_path=/home/houfei/develop/prolin/firmware_4/kernel/linux-3.10.65
new_path=linux-3.10.65
patch_path=patch_dir
total_count=`awk 'END{print NR}' $1`

rm $patch_path -rf
mkdir $patch_path
#delete the space
sed s/[[:space:]]//g $1 > no_space.txt
cat no_space.txt | while read line
do
    echo "try to create patch file: [$count/$total_count]"
#   echo "line: ${line}"
    file_name=`echo ${line} | awk -F 'modified:' '{print $2}'`
    patch_name=`echo ${file_name} | sed 's/\//-/g'`
    org_file=${org_path}/${file_name}
    new_file=${new_path}/${file_name}
    old_file=${new_file}_org
    patch_file=${patch_path}/${patch_name}.patch
#   echo "file_name: $file_name"
#   echo "path_name: $path_name"
#   echo "org file is: $org_file"
#   echo "new file is: $new_file"
#   echo "path file is: $patch_file"
#   echo "diff -uN $old_file $new_file > $patch_file"
    cp $org_file $old_file
    diff -uN $old_file $new_file > $patch_file
    rm $old_file

    count=$[count+1]
done
rm no_space.txt

(3)运行脚本生成补丁包

./ patch_create.sh  modify.txt

生成后的脚本在patch_dir目录,列表如下

#ls
Documentation-DMA-API.txt.patch
Documentation-arm64-booting.txt.patch
arch-arm-boot-compressed-head.S.patch
fs-fat-fat.h.patch
arch-arm-boot-dts-Makefile.patch
fs-fat-inode.c.patch

3.6 拷贝新增文件和文件夹

对于之前git比较部分,将其中的新增文件和目录信息拷贝到单独的文件untracked.txt,格式如下

AndroidKernel.mk
Documentation/android.txt
android/
drivers/char/dcc_tty.c

进入到需要拷贝的目录

# cd /dir1/
# ls
copy_file_directoyr.sh  untracked.txt

运行脚本,一键拷贝文件和目录

./copy_file_directoyr.sh  untracked.txt

脚本如需更改,只需更改原文件和目的文件的路劲两个变量参数即可

source_kernel_path=/home/houfei/develop/prolin/firmware_4/kernel/git/linux_kernel/linux-3.10.65
error_info=error_info.txt
dest_path=./

脚本内容如下:

#!/bin/bash
echo "input file name is $1"

source_kernel_path=/home/houfei/develop/prolin/firmware_4/kernel/git/linux_kernel/linux-3.10.65
error_info=error_info.txt
dest_path=./

#copy file
echo "try to copy the file"
rm $error_info  -rf
touch $error_info
count=1
total_count=`awk 'END{print NR}' $1`
cat $1 | while read line
do
    echo "try to copy file: [$count/$total_count]"
    source_file=${source_kernel_path}/${line}
    dest_file=${line}
    dir_name=`echo ${line} | awk -F '/' '{$NF="";print}'`
    dest_dir=` echo ${dir_name} | awk -F '/' '{gsub(" ", "/", $NF);print}'`
    dest_dir=$dest_path/$dest_dir
    #echo "make dir: mkdir -p $dest_dir"
    mkdir -p $dest_dir
    #echo "copy file: cp $source_file $dest_file"
    #copy the file and collect the error info
    cp $source_file $dest_file >> $error_info 2>&1
    count=$[count+1]
done
echo "copy file finsh"

# copy the directory
echo "try to copy the directory"
need_copy_dir=need_copy_dir.txt
rm $need_copy_dir -rf
touch $need_copy_dir
# try to copy the diectory have the error info "cp: omitting directory"
grep -r "cp: omitting directory ‘" $error_info > $need_copy_dir # get the directory copy failed information 
sed -i "s/cp: omitting directory ‘//g" $need_copy_dir          # delete the "cp: omitting directory ‘" symboal 
sed -i "s/’//g" $need_copy_dir                                 # delete the "’" symboal
total_count=`awk 'END{print NR}' $need_copy_dir`
count=1
cat $need_copy_dir | while read line
do
    echo "try to copy directory: [$count/$total_count]"
    source_dir=${line}
    dest_dir=`echo ${line} | awk -F 'linux-3.10.65/' '{print $2}'`
    dest_dir=$dest_path/$dest_dir
    #echo "source_dir: $source_dir"
    #echo "dest_dir : $dest_dir"
    #echo "copy file: cp -r ${source_dir}* $dest_dir"
    cp -r ${source_dir}* $dest_dir
    count=$[count+1]
done
rm $error_info
rm $need_copy_dir
echo "copy the directory finish!!!"

猜你喜欢

转载自blog.csdn.net/xhoufei2010/article/details/79014163