Skip to content

getopt解析参数

getopt是一个独立外部工具,常用来解析和整理参数的

-o:短格式选项

-l:长格式选项

--:要解析的参数,也作为结束标记

shell
getopt -o a -l name:,age: -- -a --name zs --age 11
# a                 没有参数的短选项
# name:,age:        有参数的长选项,有参数的后面多个冒号
shell
# 处理接受到的参数
getopt -o a -l name:,age: -- "$@"

# 将结果设置为脚本参数
set -- $(getopt -o a -l name:,age: -- "$@")

# 让脚本遇到非零退出[上面的一行处理,虽然getopt非0了,但是set的结果返回0]
set -e
args=$(getopt -o a -l name:,age: -- "$@")
set -- $args
shell
# 使用getopt解析参数
OPTIONS='ao:h'
LONGOPTIONS='arg,option:help'

ARGS=$(getopt --options $OPTIONS --longoptions $LONGOPTIONS --name "$(basename $0)" -- "$@")
ARGS=$(getopt --options $OPTIONS --longoptions $LONGOPTIONS -n "$(basename $0)" -- "$@")
if [[ $? -ne 0 ]]; then
    # getopt失败
    exit 1
fi

# 解析getopt的输出
eval set -- "$ARGS"

while true; do
    case "$1" in
        -a|--arg)
            shift;
            echo -e "arg: specified"
            ;;
        -o|--option)
            shift;
            if [[ -n "${1}" ]]; then
                echo -e "option: specified, value is ${1}"
                shift;
            fi
            ;;
        -h|--help)
        	echo "help"
            exit 0
            ;;
        --)
            # 所有选项都已处理,剩下的参数是位置参数(如果有的话)
            shift;
            break;
            ;;
        *)
            # 未知选项,显示帮助信息并退出
            echo "help"
            exit 1
            ;;
    esac
done

getopts解析参数

getopts 是 Shell 内建命令,不支持解析长参数

如果命令行中包含了没有在getopts列表中的选项,会有警告信息,如果在整个getopts字符串前面也加上个:,就能消除警告信息了

bash
#!/bin/bash
while getopts 'd:Dm:f:t:' OPT; do
    case $OPT in
        d)
            DEL_DAYS="$OPTARG";;
        D)
            DEL_ORIGINAL='yes';;
        f)
            DIR_FROM="$OPTARG";;
        m)
            MAILDIR_NAME="$OPTARG";;
        t)
            DIR_TO="$OPTARG";;
        ?)
            echo "Usage: `basename $0` [options] filename"
    esac
done
  
shift $(($OPTIND - 1))
shell
#!/bin/bash
echo 初始 OPTIND: $OPTIND
  
while getopts "a:b:c" arg #选项后面的冒号表示该选项需要参数
do
    case $arg in
        a)
            echo "a's arg:$OPTARG" #参数存在$OPTARG中
            ;;
        b)
            echo "b's arg:$OPTARG"
            ;;
        c)
            echo "c's arg:$OPTARG"
            ;;
        ?)  #当有不认识的选项的时候arg为?
            echo "unkonw argument"
            exit 1
        ;;
    esac
done
  
echo 处理完参数后的 OPTIND:$OPTIND
echo 移除已处理参数个数:$((OPTIND-1))
shift $((OPTIND-1))
echo 参数索引位置:$OPTIND
echo 准备处理余下的参数:
echo "Other Params: $@"

制作基础镜像

apline

Alpine Linux 官方的下载页面,找到 MINI ROOT FILESYSTEM ,点击下载 对应架构 的版本就可以开始下载了。

也可以下载历史的版本,在对应版本的releases找到alpine-minirootfs 压缩包即可

https://dl-cdn.alpinelinux.org/alpine/

image-20250218151055050

https://dl-cdn.alpinelinux.org/alpine/v3.9/releases/aarch64/alpine-minirootfs-3.9.6-aarch64.tar.gz
https://dl-cdn.alpinelinux.org/alpine/v3.9/releases/x86_64/alpine-minirootfs-3.9.6-x86_64.tar.gz

下载之后是一个 tar.gz 包,使用 docker import 命令,将 tar 包导入成镜像。

bash
docker import alpine-minirootfs-3.9.6-aarch64.tar.gz apline:temp
docker import alpine-minirootfs-3.9.6-x86_64.tar.gz apline:temp

由于没有指定启动命令,所以需要指定下:

bash
# 法一: 直接指定
docker run -itd alpine:temp /bin/sh

# 法二: 通过Dockerfile完善
FROM  apline:temp
CMD ["/bin/sh"]

docker build -t alpine:3.9.6 .

完善基础软件

alpine包管理基本命令

shell
# 更新最新镜像源列表
apk update

# 搜索软件包:
apk search                        # 查找所以可用软件包
apk search -v                     # 查找所以可用软件包及其描述内容
apk search -v 'acf*'              # 通过软件包名称查找软件包
apk search -v -d 'docker'         # 通过描述文件查找特定的软件包

# 安装软件包
apk add openssh                   # 安装一个软件
apk add openssh openntp vim       # 安装多个软件
apk add --no-cache mysql-client   # 不使用本地镜像源缓存,相当于先执行update,再执行add

# 列出已安装的软件包
apk info                          # 列出所有已安装的软件包
apk info -a zlib                  # 显示完整的软件包信息
apk info --who-owns /sbin/lbu     # 显示指定文件属于的包

# 升级软件版本
apk upgrade                       # 升级所有软件
apk upgrade openssh               # 升级指定软件
apk upgrade openssh openntp vim   # 升级多个软件
apk add --upgrade busybox         # 指定升级部分软件包

# 删除软件包
apk del openssh                   # 删除一个软件

通过alpine系统镜像构建基础镜像

dockerfile
FROM alpine:3.9.6

# 更新最新镜像源列表
RUN apk update

# 设置Docker 时间为上海时区
RUN apk add -U tzdata
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
RUN echo "Asia/shanghai" >> /etc/timezone

# 依次安装命令:curl、scp、telnet
RUN apk add curl
RUN apk add openssh-client
RUN apk add busybox-extras

更换软件源

bash
FROM alpine:3.9.6
# 更新Alpine的软件源为国内的站点(例如清华大学)
RUN echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.4/main/" > /etc/apk/repositories
# 更新软件包列表并安装Bash
RUN apk update && apk upgrade && apk add --no-cache bash bash-doc bash-completion
# 清理缓存以减小镜像体积
RUN rm -rf /var/cache/apk/*
# 设置默认的shell为Bash
RUN echo "/bin/bash" >> /etc/shells
RUN chsh -s /bin/bash root

# 进入Bash环境
CMD ["/bin/bash"]