shell编程——getopt设计实例

简介:

使用getopt设计shell脚本选项示例

这里提供一个和seq命令功能相同的脚本seq.sh,然后设计这个脚本的选项。

先看一下seq命令的各个选项说明:

seq [OPTION]... LAST                  # 语法1
seq [OPTION]... FIRST LAST            # 语法2
seq [OPTION]... FIRST INCREMENT LAST  # 语法3

选项:
-s, --separator=STRING
使用指定的STRING分隔各数值,默认值为"\n"u

-w, --equal-width
使用0填充在前缀使所有数值长度相同

--help
显示帮助信息并退出

--version
输出版本信息并退出

以下是脚本内容:和seq相比,只有两个问题:第一个起点数值FIRST不能为负数;不支持小数功能。其它功能完全相同

#!/usr/bin/env bash
usage(){
cat <<'EOF'
Usage: $0 [OPTION]... LAST
  or:  $0 [OPTION]... FIRST LAST
  or:  $0 [OPTION]... FIRST INCREMENT LAST
EOF
}

# getopt的版本是增强版吗
getopt -T &>/dev/null;[ $? -ne 4 ] && { echo "not enhanced version";exit 1; }

# 参数解析
parameters=`getopt -o +s:w --long separator:,equal-width,help,version -n "$0" -- "$@"`
[ $? -ne 0 ] && { echo "Try '$0 --help' for more information."; exit 1; }

eval set -- "$parameters"

while true;do
    case "$1" in
        -w|--equal-width) ZERO_PAD="true"; shift ;;
        -s|--separator) SEPARATOR=$2; shift 2 ;;
        --version) echo "$0 version V1.0"; exit ;;
        --help) usage;exit ;;
        --)
            shift
            FIRST=$1
            INCREMENT=$2
            LAST=$3
            break ;;
        *) usage;exit 1;;
    esac
done


# 用于生成序列数
function seq_func(){

    # 是否要使用printf填充0位?
    [ "x$1" = "xtrue" ] && zero_pad="true" && shift
    
    # 设置first、step、last
    if [ $# -eq 1 ];then
        first=1
        step=1
        last=$1
    elif [ $# -eq 2 ];then
        first=$1
        step=1
        last=$2
    elif [ $# -eq 3 ]; then
        first=$1
        step=$2
        last=$3
    else
        echo "$FUNCNAME: ARGS wrong..."
        exit 1
    fi
    
    # 最后一个要输出的元素及其长度,决定要填充多少个0
    last_output=$[ last - ( last-first ) % step ]
    zero_pad_len=`[ ${#last_output} -gt ${#first} ] && echo ${#last_output} || echo ${#first}`

    # 生成序列数
    if [ "x$zero_pad" = "xtrue" ];then
        # 填充0
        if [ $step -gt 0 ];then
            # 递增,填充0
            for((i=$first;i<=$last;i+=$step)){
                [ $last_output -eq $i ] && { printf "%0${zero_pad_len}i\n" "$i";return; }
                printf "%0${zero_pad_len}i " $i
            }
        else
            # 递减,填充0
            for((i=$first;i>=$last;i+=$step)){
                [ $last_output -eq $i ] && { printf "%0${zero_pad_len}i\n" "$i";return; }
                printf "%0${zero_pad_len}i " $i
            }
        fi
    else
        # 不填充0
        if [ $step -gt 0 ];then
            # 递增,不填充0
            for((i=$first;i<=$last;i+=$step)){
                [ $last_output -eq $i ] && { printf "%i\n" "$i";return; }
                printf "%i " $i
            }
        else
            # 递减,不填充0
            for((i=$first;i>=$last;i+=$step)){
                [ $last_output -eq $i ] && { printf "%i\n" "$i";return; }
                printf "%i " $i
            }
        fi
    fi
}

# 指定输出分隔符
: ${SEPARATOR="\n"}

# 输出结果
seq_func $ZERO_PAD $SEPARATOR $FIRST $INCREMENT $LAST | tr " " "$SEPARATOR"

上面解析选项的脚本缺陷在于无法解析FIRST为负数的情况,例如./seq.sh -w -5 3将报错。但可以写为标准的./seq.sh -w -- -5 -3语法。

目录
相关文章
|
2月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
2月前
|
Shell Linux
Linux shell编程学习笔记30:打造彩色的选项菜单
Linux shell编程学习笔记30:打造彩色的选项菜单
|
21天前
|
运维 监控 Shell
深入理解Linux系统下的Shell脚本编程
【10月更文挑战第24天】本文将深入浅出地介绍Linux系统中Shell脚本的基础知识和实用技巧,帮助读者从零开始学习编写Shell脚本。通过本文的学习,你将能够掌握Shell脚本的基本语法、变量使用、流程控制以及函数定义等核心概念,并学会如何将这些知识应用于实际问题解决中。文章还将展示几个实用的Shell脚本例子,以加深对知识点的理解和应用。无论你是运维人员还是软件开发者,这篇文章都将为你提供强大的Linux自动化工具。
|
1月前
|
Shell
Shell编程(下)
Shell编程(下)
89 1
|
1月前
|
Shell Linux Windows
Shell编程(上)
Shell编程(上)
40 1
|
1月前
|
Shell 应用服务中间件 网络安全
|
1月前
|
Shell Linux 开发工具
|
1月前
|
监控 Unix Shell
shell脚本编程学习
【10月更文挑战第1天】shell脚本编程
66 12
|
2月前
|
Shell Linux
Linux shell编程学习笔记82:w命令——一览无余
Linux shell编程学习笔记82:w命令——一览无余
|
2月前
|
存储 Unix Shell
shell脚本编程基础
【9月更文挑战第4天】
45 12