小黑的日常折腾-复制外部命令的可执行文件和依赖库文件到指定目录下的对应目录

清明三天假期基本都是在写脚本中度过了,今天又折腾了一个新的脚本,该脚本的作用是快速复制一个或多个命令的可执行文件和依赖库文件到一个模拟的根文件系统下的相应目录下,这个脚本平时运维估计用不到,只有自己制作一个小的Linux发行版时才有可能使用该脚本。

脚本具体的功能如下:

1)提示用户选择要从文本中读取要复制的命令名还是从当前终端中交互式输入命令名。

2)用户选择前者,会自动使用vim打开一个文件,用户根据格式说明填入要复制的命令的名称,可以是多个命令,保存退出后自动执行复制操作。

3)用户选择后者,在终端交互式的输入单个命令的名称,回车后执行复制操作。

注意:如果目标目录没有对应的子目录则自动创建,如/bin对应的/tmp/sysroot/bin。

具体实现脚本如下(渣渣英语,百度翻译的,请见谅):

#!/bin/bash
#Program:
#      This program is used to cpoy executable file and dependency Library  
#      to the specified folder
#History:
#2016/4/4    xiaohei   v1.0
#blog:http://zww577593841.blog.51cto.com/6145493/1750689
#
LANG=zh_CN.UTF8
PATH=./:$PATH
export PATH
#要复制的命令的名字
declare cmd
#命令的可执行文件路径
declare cmdfile
#依赖库文件的路径
declare libfile
#要复制到的目标目录
declare sysroot="/tmp/sysroot"
#信号捕捉
trap ‘mytrap‘ INT
mytrap(){
        clean_temp
        exit 1
}
#清理脚本运行过程中生成的临时文件和变量
clean_temp(){
        unset -v cmd
        unset -v cmdfile
        unset -v libfile
        unset -v sysroot
        rm -rf  ./libfile.txt
        rm -rf ./cmdlist.txt
        rm -rf ./cmdfile.txt
        rm -rf ./cmdlist.txt.bak

}
#判断是否输入一个参数,输入的参数是不是一个命令,该命令的可执行文件是否存在
analyse_cmd(){
        if [ $# -ne 1 ];then
                echo  -e "\033[31mThe parameter error\033[0m"
                return  1
        fi
        if  ! type "$1" &> /dev/null;then
                echo -e  "\033[31mnot a command\033[0m"
                return 1
        fi
        if ! which  "$1" &> /dev/null ;then
                echo -e  "\033[31mcmdfile does not exist\033[0m"
                return 1
        fi
        return 0
}
analyse_dir_file(){
        #判断要复制的文件是否存在
        if ! [ -a $1 ];then
                echo -e  "\033[31m$1  does not exist\033[0m"
                return 1
        fi
        #取文件路径名
        local  dir_file=${1%/*}
         [ -d $dir_file   ]
        #如果目录不存在则创建
        if ! [ -d $sysroot$dir_file  ];then
                mkdir -p $sysroot$dir_file
                echo -e "\033[32mcreat $sysroot$dir_file\033[0m"
                return 0
        fi
        #如果要复制到的目录已存在该文件则报错
        if  [ -a $sysroot$1 ];then
                echo -e  "\033[31m$sysroot$1 has exist\033[0m"

                return 1
        fi
        return 0
}
cp_file(){
        #调用函数分析给定的参数
        analyse_cmd $1 || return 1
        #获取命令的可执行文件的路径
        cmdfile=$(which $1)
        echo "cmdfile is:$cmdfile"
        #调用函数分析获取的路径和文件,正常则执行复制,异常则退出函数
        analyse_dir_file $cmdfile &&  cp  -a  "$cmdfile"  "$sysroot$cmdfile"   || return 1
        echo -e  "\033[32mcp $cmdfile  successful\033[0m"
        #获取命令的依赖库文件名,并保存至至文件中
        ldd $cmdfile | grep -o -E  "/[^[:space:]]+"  > ./libfile.txt
        #循环遍历文件,内容为上一条命令查找到的依赖库文件名
        while read libfile ;do
                #对库文件的绝对路径名进行分析,正常执行下一步,异常退出本次循环。
                analyse_dir_file $libfile  || continue
                #复制文件到目标路径下
                cp   "$libfile"  "$sysroot$libfile"
                echo -e "\033[32mcp $libfile successful\033[0m"
        done < ./libfile.txt
}
#手动按照固定格式在文件中添加多个命令名称
cmdlist_creat(){
        #判断文件是否存在,存在则将其改名
        if [ -f ./cmdlist.txt  ];then
                mv -f ./cmdlist.txt  ./cmdlist.txt.bak
        fi
        #给文件添加格式说明
        cat  > ./cmdlist.txt <<end
#Each line is a command 
#ls
#pwd    
end
        #编辑文件,添加要复制的命令的名字
        vim ./cmdlist.txt
}
#遍历文件,该文件保存要复制的命令的名称,复制每个命令的可执行文件和依赖库到指定的目录的相应目录中
cp_file_text(){
        #局部变量,保存命令名称
        local cmdf
        #循环遍历文件,查找没有#号开头的行的命令,调用函数执行复制操作
        while read cmdf ;do
                #排查格式说明的举例
                if [[  "$cmdf"  =~ ‘#‘  ]];then
                        continue
                fi
                echo "$cmdf"
                cp_file $cmdf
        done < ./cmdlist.txt
}
while true ;do
cat <<end
######################################
a)Read from the text                #  
b)Read from the terminal            #
quit)quit                           #
#####################################
end
read -p "enter you choice:" option
case $option in
[aA])
        cmdlist_creat
        cp_file_text
        ;;
[bB])
        read -p "enter a cmd:"  cmd
        cp_file $cmd
        ;;
quit)
        break
        ;;
*)
        continue
        ;;
esac
done
#清理脚本生成的临时文件和变量
clean_temp

程序运行测试:

1)脚本运行效果

2)选择从文本添加要复制的命令

3)选择从终端交互式输入要添加的命令

4)查看是否真确复制

5)测试各种错误输入的报错信息,注意该脚本只能识别外部命令,bash内置命令会报错。

本脚本基本是用来练习的,是为了后期自制Linux小系统准备的工具脚本。

时间: 2024-10-03 04:08:16

小黑的日常折腾-复制外部命令的可执行文件和依赖库文件到指定目录下的对应目录的相关文章

linux学习之路之使用脚本来复制二进制程序和所需的库文件

首先介绍bash的特殊语法 ${parameter#*word} 其中parameter为变量,word为分隔符,表示从变量最边左字符开始到第一匹配到分隔符(word)之间的字符串都去掉 ${parameter##*word}:表示从变量最左边字符开始到最后一次匹配到该分隔符之间的字符串都去掉 注意:其中变量不要加$符号 当*在分隔符(word)前面时,表示从左开始匹配 当*在分隔符(word)后面时,表示从右开始匹配 ${parameter%word*}:表示从最右边字符开始到第一次匹配到的分

php目录下的ext目录中,执行的命令

php的目录下的ext目录,如果你只需要一个基本的扩展框架的话,执行下面的命令: ./ext_skel --extname=module_name module_name是你自己可以选择的扩展模块的名字,例如我选择的my_module.执行工具后会自动在ext目录下建立你选择的module_name名字的目录,里面已经生成了相关的代码,这些代码中只需要调整config.m4文件中的三行注释就可以正常的编译带这个自定义扩展模块的php了.在php的根目录执行下列操作就可以得到. ./buildco

Linux系统裁减之,制作一个极度精简的Linux-用脚本实现自动拷贝命令和依赖库文件

第2章 用脚本实现自动拷贝命令和依赖库文件 这篇文章主要是对我上一篇博文http://blog.51cto.com/linuxprince/2045703加以完善的,前一篇文章中拷贝命令和依赖库文件的过程是完全手工方式的,显得特别LOW,这章把该过程完善一下,用脚本方式实现. 2.1命令具体实现方法 创建脚本文件bincp.sh输入一下内容: #!/bin/bash # DESPATH=/mnt/sysroot libcp() { LIBPATH=${1%/*} [ ! -d $LIBPATH

使用strace命令解决linux服务器依赖库问题

使用strace命令解决linux服务器依赖库问题 简单说明:strace的另一个用处是解决和动态库相关的问题.当对一个可执行文件运行ldd时,它会告诉你程序使用的动态库和找到动态库的位置.但是如果你正在使用一个比较老 的glibc版本(2.2或更早),你可能会有一个有bug的ldd程序,它可能会报告在一个目录下发现一个动态库,但是真正运行程序时动态连接程序 (/lib/ld-linux.so.2)却可能到另外一个目录去找动态连接库.这通常因为/etc/ld.so.conf和 /etc/ld.s

小黑的日常折腾-快速建立私有CA的shell脚本

小黑又开始折腾新的东西了,上周刚学习完openssl建设私有CA,周六就花了点时间写了这个脚本,时间仓促,搞完就去撸DNS了,如果有啥BUG请见谅,本脚本纯属练习,用来练openssl.awk.sed等知识点. 先来介绍下建设私有CA的简单步骤(以下路劲为默认安装路径): (1) 生成私钥: ~]# (umask 077; openssl genrsa -out /etc/pki/CA/private/cakey.pem 4096) (2) 生成自签证书: ~]# openssl req -ne

Linux tar (打包.压缩.解压缩)命令说明 | tar如何解压文件到指定的目录?

打包举例:将 /usr/local/src/zlib-1.2.5目录下的文件打包成 zlib-1.2.5.tar.gz cd /usr/local/src tar -czvf ./zlib-1.2.5.tar.gz ./zlib-1.2.5/* # 压缩到制定目录下(如:/root/2/ ) tar -czvf /root/2/zlib-1.2.5.tar.gz ./zlib-1.2.5/* #压缩 tar  -czvf   ***.tar.gz tar  -cjvf   ***.tar.bz2

小黑的日常折腾-网段在线地址扫描shell脚本

学习Linux已经一个月了,不知不觉shell脚本的基本用法已经学习完了,为了检验自己的学习情况,在清明小长假期间花了点时间折腾出了这个脚本.该作品只是练手之作,如果有BUG,请留言指明,我会尽力完善. 该脚本需要用户给定两个参数,第一个参数是网段的起始ip地址,第二个参数是网段的结束ip地址.起始地址的ip地址最后一段必须是1,如192.168.0.1,结束ip地址的最后一位必须是254,如192.168.10.254.另外,起始和结束ip地址的第一段必须相同. 注意: 1.地址范围越大运行程

Perl调用外部命令的方式和区别

主要的方式简述如下:1. system("command");使用该命令将开启一个子进程执行引号中的命令,父进程将等待子进程结束并继续执行下面的代码. 2. exec("command");效果同system命令类似,区别是不会开启子进程,而是取代父进程,因此执行完引号中的命令后进程即结束.一般和fork配合使用. 3. `command`;使用反引号调用外部命令能够捕获其标准输出,并按行返回且每行结束处附带一个回车.反引号中的变量在编译时会被内插为其值. 4. o

&#39;mysql&#39; 不是内部或外部命令,也不是可运行的程序或批处理文件的解决办法

前言: 本文的解决方法来自http://www.cnblogs.com/xionghui/archive/2012/04/11/2442404.html --感谢! 问题描述:新电脑装mysql后在cmd面板输入:mysql -uroot -p ,出现:'mysql' 不是内部或外部命令,也不是可运行的程序或批处理文件. 原因:没有配置环境变量! 解决方法:配置环境变量 在Path中加入mysql的安装目录下的bin目录 OK! 再次打开cmd: 后记:如有类似问题直接打开本文的感谢网址即可.