Linux 制作某命令的离线运行包

简介

在 linux 可以正常运行的命令。如果直接复制到另一台 linux 的话,不一定能运行,是因为这个命令依赖了动态库。

如果想在一台新机器上不安装的情况下也能运行需要将其命令的依赖的动态库都加载过来。可以使用 ldd 命令查看一个命令的依赖动态库。

ldd 用法

举例说明mysql

  1. 首先找到 mysql命令的位置
# which mysql
/usr/bin/mysql
复制代码
  1. 查看mysql依赖的动态库
ldd /usr/bin/mysql
复制代码
  1. 一条命令搞定
ldd $(which mysql)
复制代码

以下为 mysql 的依赖动态库

	linux-vdso.so.1 =>  (0x00007ffc26f99000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f098f9e9000)
	libz.so.1 => /lib64/libz.so.1 (0x00007f098f7d3000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007f098f5cf000)
	libssl.so.10 => /lib64/libssl.so.10 (0x00007f098f35d000)
	libcrypto.so.10 => /lib64/libcrypto.so.10 (0x00007f098eefa000)
	libncurses.so.5 => /lib64/libncurses.so.5 (0x00007f098ecd3000)
	libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007f098eaa9000)
	libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f098e7a2000)
	libm.so.6 => /lib64/libm.so.6 (0x00007f098e4a0000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f098e0d3000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f099016a000)
	libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007f098de86000)
	libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007f098db9d000)
	libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007f098d999000)
	libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007f098d766000)
	libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f098d550000)
	libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007f098d340000)
	libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007f098d13c000)
	libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f098cf23000)
	libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f098ccfc000)
	libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f098ca9a000)

复制代码

脚本源码

本着脚本搞定一切,制作了绿色安装包的脚本。开箱即用。

将以下命令保存名为 make-green-command.sh

touch make-green-command.sh
复制代码
#!/bin/env bash
#############################
# 制作某命令的离线运行包
# 版本: 2021.06.29 v1
#############################

# 命令名
command=$1

# lib 目录
lib_dir="${command}_lib"

# pkg 目录
pkg="${command}-pkg"

# pkg run 小脚本
pkg_run="${pkg}/run"

# 0. 创建临时目录
if [ ! -d "${lib_dir}" ];then
    mkdir -p "${lib_dir}"
    echo "${lib_dir} fold create successed!"
fi 

# 1. 查找命令所在路径
command_path=$(which "${command}")
if [ ! -f "${command_path}" ];then
    echo "${command} command does not exist"
    exit 1
fi
# 2. 查找 ldd 命令所在路径
ldd_path=$(which ldd)
if [ ! -f "${ldd_path}" ];then
    echo "ldd command does not exist"
    exit 1
fi

# 3. 检索 ldd 依赖的库文件
so_list=$(${ldd_path} "${command_path}" |awk '{print $3}')

# 4. 拷贝依赖库文件到临时目录
for so in ${so_list}
do 
    if [ -f "${so}" ];then 
        echo "Coping ${so} file..."
        cp "${so}" "${lib_dir}/"
    fi 
done

# 5. 制作可移动包
mkdir -p "${pkg}"
# 拷贝 lib 依赖
cp -a "${lib_dir}" "${pkg}"
# 拷贝命令文件
cp "${command_path}" "${pkg}"
# 制作一个 LD_LIBRARY_PATH 小脚本
cat <<EOF > "${pkg_run}" 
#!/bin/env bash
##############################################
# Load LD_LIBRARY_PATH
#${lib_dir} 加载到 LD_LIBRARY_PATH 环境变量
# 即可使用 ${command} 命令。
# version: $(date +%F) v1
##############################################
lib=\$PWD/${lib_dir}/
export LD_LIBRARY_PATH=\${lib}:\$LD_LIBRARY_PATH
EOF
# 添加执行权限
chmod +x "${pkg_run}"

# 6. 显示出如何使用离线安装包
function usage() {
    cat <<EOF
# ${command}

# usage method
1. \`sh run\`
1. \`./${command}\`

# LD_LIBRARY_PATH
export LD_LIBRARY_PATH=\$PWD/${lib_dir}/:\$LD_LIBRARY_PATH
EOF
}
usage > "${pkg}/README.md"

# 7. 打包

tar -zcvf "${pkg}-$(uname -s)-$(uname -m).tar.gz" "${pkg}/"

# 8. 清理不必要的临时目录
if [ -d "${lib_dir}" ];then 
    rm -rf "${lib_dir}"
fi
if [ -d "${pkg}" ];then 
    rm -rf "${pkg}"
fi 

echo "make ${command} successfully!"
复制代码

用法

查看 readme.md

  1. 执行上面的命令,如
sh make-green-command.sh mysql 
复制代码

会生成一个 mysql-pkg 压缩包。将其拷贝到一台新机器上。

tar -zxvf mysql-pkg.tar-linux-x86_64.tar.gz 
cd  mysql-pkg
sh run 
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享