如何在 Bash shell 脚本中解析命令行选项
创始人
2024-03-02 08:22:22
0

给你的 shell 脚本添加选项。

终端命令通常具有 选项或开关,用户可以使用它们来修改命令的执行方式。关于命令行界面的 POSIX 规范 中就对选项做出了规范,这也是最早的 UNIX 应用程序建立的一个由来已久的惯例,因此你在创建自己的命令时,最好知道如何将选项包含进 Bash 脚本 中。

与大多数语言一样,有若干种方法可以解决 Bash 中解析选项的问题。但直到今天,我最喜欢的方法仍然是我从 Patrick Volkerding 的 Slackware 构建脚本中学到的方法,当我第一次发现 Linux 并敢于冒险探索操作系统所附带的纯文本文件时,这些脚本就是我的 shell 脚本的引路人。

Bash 中的选项解析

在 Bash 中解析选项的策略是循环遍历所有传递给 shell 脚本的参数,确定它们是否是一个选项,然后转向下一个参数。重复这个过程,直到没有选项为止。

#!/bin/bash

while [ True ]; do
if [ "$1" = "--alpha" -o "$1" = "-a" ]; then
    ALPHA=1
    shift 1
else
    break
fi
done

echo $ALPHA

在这段代码中,我创建了一个 while 循环,它会一直进行循环操作,直到处理完所有参数。if 语句会试着将在第一个位置($1)中找到的参数与 --alpha-a 匹配。(此处的待匹配项是任意选项名称,并没有特殊意义。在实际的脚本中,你可以使用 --verbose-v 来触发详细输出)。

shift 关键字会使所有参数位移一位,这样位置 2($2)的参数移动到位置 1($1)。处理完所有参数后会触发 else 语句,进而中断 while 循环。

在脚本的末尾,$ALPHA 的值会输出到终端。

测试一下这个脚本:

$ bash ./test.sh --alpha
1
$ bash ./test.sh

$ bash ./test.sh -a
1

可以看到,选项被正确地检测到了。

在 Bash 中检测参数

但上面的脚本还有一个问题:多余的参数被忽略了。

$ bash ./test.sh --alpha foo
1
$

要想捕获非选项名的参数,可以将剩余的参数转储到 Bash 数组 中。

#!/bin/bash

while [ True ]; do
if [ "$1" = "--alpha" -o "$1" = "-a" ]; then
    ALPHA=1
    shift 1
else
    break
fi
done

echo $ALPHA

ARG=( "${@}" )
for i in ${ARG[@]}; do
    echo $i
done

测试一下新版的脚本:

$ bash ./test.sh --alpha foo
1
foo
$ bash ./test.sh foo

foo
$ bash ./test.sh --alpha foo bar
1
foo
bar

带参选项

有一些选项需要传入参数。比如,你可能希望允许用户设置诸如颜色或图形分辨率之类的属性,或者将应用程序指向自定义配置文件。

要在 Bash 中实现这一点,你仍然可以像使用布尔开关一样使用 shift 关键字,但参数需要位移两位而不是一位。

#!/bin/bash

while [ True ]; do
if [ "$1" = "--alpha" -o "$1" = "-a" ]; then
    ALPHA=1
    shift 1
elif [ "$1" = "--config" -o "$1" = "-c" ]; then
    CONFIG=$2
    shift 2
else
    break
fi
done

echo $ALPHA
echo $CONFIG

ARG=( "${@}" )

for i in ${ARG[@]}; do
    echo $i
done

在这段代码中,我添加了一个 elif 子句来将每个参数与 --config-c 进行比较。如果匹配,名为 CONFIG 的变量的值就设置为下一个参数的值(这就表示 --config 选项需要一个参数)。所有参数都位移两位:其中一位是跳过 --config-c,另一位是跳过其参数。与上节一样,循环重复直到没有匹配的参数。

下面是新版脚本的测试:

$ bash ./test.sh --config my.conf foo bar
my.conf
foo
bar
$ bash ./test.sh -a --config my.conf baz
1
my.conf
baz

Bash 让选项解析变得简单

还有一些其他方法也可以解析 Bash 中的选项。你可以替换使用 case 语句或 getopt 命令。无论使用什么方法,给你的用户提供选项都是应用程序的重要功能,而 Bash 让解析选项成为了一件简单的事。


via: https://opensource.com/article/21/8/option-parsing-bash

作者:Seth Kenlon 选题:lujun9972 译者:unigeorge 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

相关内容

创建投票(方法教程)
Hello!大家好啊,这里是每天分享一点办公技巧的的西瓜! 投票评...
2026-01-20 18:24:05
微软Edge将升级交互:截...
IT之家 11 月 22 日消息,科技媒体 Windows Rep...
2025-11-22 16:46:57
原创 ...
北京时间2025年9月16日,名记Shams谈到了勇士与乔纳森-库...
2025-09-16 09:43:56
开启“零门槛”AI视频创作...
随着移动端的普及和数字化技术的成熟,短视频创作内容不仅逐渐向各行各...
2025-07-11 14:12:34
编写CentOS系统下的B...
面对重复繁琐的服务器操作,手动输入命令效率低下且易出错。为了解决这...
2025-06-15 08:43:24
怎么用AI做短视频赚钱?小...
嘿,你是不是也刷到过那些爆火的短视频,心想:“这玩意儿咋这么赚钱?...
2025-06-06 22:12:18

热门资讯

如何在 Github 上创建一... 学习如何复刻一个仓库,进行更改,并要求维护人员审查并合并它。你知道如何使用 git 了,你有一个 G...
《Apex 英雄》正式可在 S... 《Apex 英雄》现已通过 Steam Deck 验证,这使其成为支持 Linux 的顶级多人游戏之...
Helix:高级 Linux ... 说到 基于终端的文本编辑器,通常 Vim、Emacs 和 Nano 受到了关注。这并不意味着没有其他...
JStock:Linux 上不... 如果你在股票市场做投资,那么你可能非常清楚投资组合管理计划有多重要。管理投资组合的目标是依据你能承受...
Textual:为 Pytho... 快速入门使用 TextualPython 在 Linux 上有像 TkInter 这样的优秀 GUI...
硬核观察 #1245 Open... #1 OpenAI 悄然删除禁止将 ChatGPT 用于 “军事和战争” 的禁令在 1 月 10 日...
使用时间序列数据,用开源工具助... InfluxData 是一个开源的时间序列数据库平台。下面介绍了它是如何被用于边缘应用案例的。收集到...
使用 KRAWL 扫描 Kub... 用 KRAWL 脚本来识别 Kubernetes Pod 和容器中的错误。当你使用 Kubernet...
硬核观察 #1249 LG 洗... #1 LG 洗衣机每天上传近 4GB 的数据?一个名为 Johnie 的 LG 洗衣机用户发现,他的...
2024 年 Linux 和开... 让我们尝试预测未来吧!新的一年快乐,朋友们 ✨2024 年的钟声已经敲过,我们有必要去预见一下将塑造...