最近突发奇想,想把本机的bash放到docker镜像里面,接下来看操作。
获取bash以及依赖
bash
[root@bogon ~]# cat get_lib_info.sh
#!/bin/bash
# 函数:显示帮助信息
show_help() {
echo "Usage: $(basename "$0") -h -f <file> -b <output_directory>"
echo " -h Display this help message"
echo " -f <file> Specify the binary file to query"
echo " -b <output_directory> Specify the output directory for the compressed file"
}
# 函数:使用 ldd 和 awk 提取库文件路径
extract_library_paths() {
local binary_path="$1"
local paths=()
# 运行 ldd 命令,过滤并提取库文件路径
while IFS= read -r line; do
if [[ "$line" =~ ^/ ]]; then
paths+=("$line")
fi
done < <(ldd "$binary_path" | awk '/=>/ {if ($3 ~ /^\//) print $3}')
while IFS= read -r line; do
if [[ "$line" =~ ^/ ]]; then
paths+=("$line")
fi
done < <(ldd "$binary_path" | awk '{print $1}' | grep '^/')
# 返回路径数组
echo "${paths[@]}"
}
# 函数:解析符号链接路径
resolve_symlinks() {
local path="$1"
# 处理可能存在的符号链接链
while [[ -L "$path" ]]; do
target=$(readlink "$path")
if [[ "${target:0:1}" != "/" ]]; then
target=$(dirname "$path")/"$target"
fi
path="$target"
done
# 输出最终的真实路径
echo "$path"
}
# 主函数:处理二进制文件并生成解析后的路径
process_binary() {
local binary=""
local output_directory="$(dirname "$0")"
# 如果没有提供任何参数,则显示帮助信息
if [ "$#" -eq 0 ]; then
show_help
exit 0
fi
# 解析命令行参数
while getopts "hf:b:" opt; do
case "$opt" in
h) # 显示帮助信息
show_help
exit 0
;;
f) # 指定要查询的文件
binary="$OPTARG"
if [ ! -f "$binary" ]; then
echo "Error: File '$binary' does not exist." >&2
exit 1
fi
;;
b) # 指定输出的目录
output_directory="${OPTARG}"
;;
*) # 处理未知选项
echo "Invalid option: -$OPTARG" >&2
show_help
exit 1
;;
esac
done
# 检查是否提供了二进制文件路径
if [ -z "$binary" ]; then
echo "Error: You must specify a binary file with the -f option." >&2
show_help
exit 1
fi
# 提取库文件路径
library_paths=($(extract_library_paths "$binary"))
# 解析符号链接路径
resolved_paths=()
for path in "${library_paths[@]}"; do
resolved_path=$(resolve_symlinks "$path")
resolved_paths+=("$resolved_path")
done
for path in "${library_paths[@]}"; do
resolved_paths+=("$path")
done
# 打印解析后的路径
# for path in "${resolved_paths[@]}"; do
# echo "$path"
# done
# 创建解析后路径的 tar 压缩包
local binary_name=$(basename "$binary")
tar_filename="${output_directory}/${binary_name##*/}.tar.gz"
tar zcvf "$tar_filename" "${resolved_paths[@]}"
echo "已创建压缩包:$tar_filename"
}
# 主程序开始
process_binary "$@"
[root@bogon ~]# chmod +x get_lib_info.sh
[root@bogon ~]# ./get_lib_info.sh -f /bin/bash
tar: Removing leading `/' from member names
/lib64/libtinfo.so.5.9
/lib64/libdl-2.17.so
/lib64/libc-2.17.so
/lib64/ld-2.17.so
/lib64/libtinfo.so.5
/lib64/libdl.so.2
/lib64/libc.so.6
/lib64/ld-linux-x86-64.so.2
已创建压缩包:./bash.tar.gz
[root@bogon ~]# cp /bin/bash ./
编写Dockerfile
bash
[root@bogon ~]# cat Dockerfile
FROM scratch
ADD bash.tar.gz /
COPY bash /bin/bash
CMD ["/bin/bash"]
[root@bogon ~]# docker build -t mybash .
[+] Building 0.1s (6/6) FINISHED docker:default
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 108B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 1.02MB 0.0s
=> [1/2] ADD bash.tar.gz / 0.0s
=> [2/2] COPY bash /bin/bash 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:86b7d3cc6ffbed8e9c7a921af3d6d671d4692cda8e4fa3924 0.0s
=> => naming to docker.io/library/mybash 0.0s
[root@bogon ~]# docker run -it --rm mybash
bash-4.2# exit
exit
[root@bogon ~]#