前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在Bash中解析命令行参数的两种样例脚本

在Bash中解析命令行参数的两种样例脚本

作者头像
程序熵
发布2024-05-09 15:47:27
950
发布2024-05-09 15:47:27
举报
文章被收录于专栏:技术汇技术汇

问题:

假设,我有一个脚本,它会被这样一行调用:

代码语言:javascript
复制
./myscript -vfd ./foo/bar/someFile -o /fizz/someOtherFile

或者这个:

代码语言:javascript
复制
./myscript -v -f -d -o /fizz/someOtherFile ./foo/bar/someFile

如何解析 v、f 和 d,使它们都被设置为 true,并且 outFile 等于 /fizz/someOtherFile ?

回答:

以空格分隔选项和参数

样例程序如下:

代码语言:javascript
复制
cat >/tmp/demo-space-separated.sh <<'EOF'
#!/bin/bash

POSITIONAL_ARGS=() #初始化一个空数组,用来存储位置参数

while [[ $# -gt 0 ]]; do  #当命令行参数的数量大于0时,进入循环
  case $1 in
    -e|--extension)  #如果参数是这个,脚本会将紧随其后的参数(文件扩展名)保存在变量 EXTENSION 中
      EXTENSION="$2"
      shift # 跳过参数
      shift # 跳过后面的值
      ;;
    -s|--searchpath)  #如果参数是这个,脚本会将紧随其后的参数(搜索路径)保存在变量 SEARCHPATH 中
      SEARCHPATH="$2"
      shift # 跳过参数
      shift # 跳过后面的值
      ;;
    --default)  #如果参数是这个,脚本会将变量 DEFAULT 设置为 YES
      DEFAULT=YES
      shift # 跳过参数
      ;;
    -*|--*)  #如果参数是以 - 或 -- 开头且未知的选项,打印错误信息并退出
      echo "Unknown option $1"
      exit 1
      ;;
    *)  #对于所有其他非选项参数(即位置参数),将它们逐一添加到 POSITIONAL_ARGS 数组中,
      POSITIONAL_ARGS+=("$1") # 保存位置参数
      shift
      ;;
  esac
done

set -- "${POSITIONAL_ARGS[@]}" # 将数组里的参数设置为当前 shell 的位置参数

echo "FILE EXTENSION  = ${EXTENSION}"
echo "SEARCH PATH     = ${SEARCHPATH}"
echo "DEFAULT         = ${DEFAULT}"
echo "Number files in SEARCH PATH with EXTENSION:" $(ls -1 "${SEARCHPATH}"/*."${EXTENSION}" | wc -l)

if [[ -n $1 ]]; then
    echo "The non option arguments are:" $@
fi
EOF

chmod +x /tmp/demo-space-separated.sh

/tmp/demo-space-separated.sh -e log -s /var/log pos1 pos2

复制粘贴上述代码块的输出:

推荐用法:

代码语言:javascript
复制
demo-space-separated.sh -e log -s /var/log pos1

以等号分隔选项和参数

样例程序如下:

代码语言:javascript
复制
cat >/tmp/demo-equals-separated.sh <<'EOF'
#!/bin/bash

for i in "$@"; do  #循环遍历所有的命令行参数
  case $i in
    -e=*|--extension=*)
      EXTENSION="${i#*=}"  #使用 ${i#*=} 来提取等号 = 后面的值(即文件扩展名),并将其保存在变量 EXTENSION 中
      shift # past argument=value
      ;;
    -s=*|--searchpath=*)
      SEARCHPATH="${i#*=}"
      shift # past argument=value
      ;;
    --default)
      DEFAULT=YES
      shift # past argument with no value
      ;;
    -*|--*)
      echo "Unknown option $i"
      exit 1
      ;;
    *)
      ;;
  esac
done  #结束for循环

echo "FILE EXTENSION  = ${EXTENSION}"
echo "SEARCH PATH     = ${SEARCHPATH}"
echo "DEFAULT         = ${DEFAULT}"
echo "Number files in SEARCH PATH with EXTENSION:" $(ls -1 "${SEARCHPATH}"/*."${EXTENSION}" | wc -l)

if [[ -n $1 ]]; then
    echo "The non option arguments are:" $@
fi
EOF

chmod +x /tmp/demo-equals-separated.sh

/tmp/demo-equals-separated.sh -e=log -s=/var/log pos3 pos4

其中${i#*=}用于删除参数$i从左边开始匹配的第一个=及其左边的所有字符。

复制粘贴上述代码块的输出:

推荐用法:

代码语言:javascript
复制
demo-equals-separated.sh -e=log -s=/var/log pos1 pos2

参考:

  • stackoverflow question 192249
  • https://www.gnu.org/software/bash/manual/bash.html#The-Set-Builtin
  • https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-05-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序熵 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题:
  • 回答:
    • 以空格分隔选项和参数
      • 以等号分隔选项和参数
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档