【问题标题】:bash script options parser failsbash 脚本选项解析器失败
【发布时间】:2021-04-05 16:30:13
【问题描述】:

我有一个bashscript.sh,我将$ chmod +x bashscript.sh 移动到$ mv bashscript.sh ~/.local/bin/,以便它像系统命令一样可执行。

我希望能够调用它

bashscript [<-w|-working|--working>[=|:]] <y|yes|n|no> 

如果调用不被尊重,则返回用法/帮助/错误(我们想要的任何调用)。

为此,我编写了这个解析部分:

usage(){
  echo "you're wrong."
  exit 1
}
[[ $# -lt 1 ]] && usage
options=$(getopt -o y,n,h,w: -l yes,no,help,working: -- "$@")
set -- $options
while true; do
  case "$1" in
    -h|--help|*) usage
      shift;;
    y|yes)
      #do something
      shift;;
    n|no)
      #..
      shift;;
    -w|-working|--working)
      shift;;
    --) #this is just syntax
      shift
      break;;
  esac
done

但是当我测试它并没有按预期工作时*,你知道为什么/有一个样本来处理我的选项可能性吗?

*edit : 我总是触发使用显示

edit 2:删除了选项“=”周围的空格,正如@costaparas3 指出的那样,谢谢,但仍然坚持使用()

【问题讨论】:

  • 你观察到什么行为?
  • 它总是让我回到使用输出。示例:$ bashscript -w n
  • edit您的问题添加所需的信息或澄清。将大小写-h|--help|*) 移到末尾,因为它包含*,shell 将使用第一个匹配的大小写。
  • @bodo 达到了重点……第一个case 语句包括* => 匹配所有内容;如果删除 * 不能解决问题...请提供一个示例,说明您如何调用脚本,以便我们查看命令行中传递的内容

标签: linux bash shell unix command-line


【解决方案1】:

以下是我发现的问题:

  1. 如果没有参数则退出
  2. 使用options=$(...(无空格)设置选项
  3. -h|--help|*) 匹配所有内容,因此您有一个无限循环。您不需要在 * 上进行匹配,因为如果 getopt 发现无效参数,它将返回非零值,而在 -- 上的匹配通常会终止循环。
  4. getopt 为无效参数返回非零值,然后退出 1
  5. 使用 -n|--no 指定短选项和长选项
  6. --工作需要一个参数,但你只移位 1。
  7. -工作无效(使用 getopt)。使用 -w 或 --working。

这里是修正版:

#!/bin/bash

usage() {
  echo "you're wrong."
  exit $1
}

[ $# -lt 1 ] && usage

options=$(getopt -o y,n,h,w: -l yes,no,help,working: -- "$@")
[ $? -ne 0 ] && usage 1

# default values
yes=
working=

set -- $options
while :
do
  case "$1" in
    -h|--help)
      usage
      ;;
    -y|--yes)
      yes=1
      shift
      ;;
    -n|--no)
      yes=0 # or no=1
      shift
      ;;
    -w|--working)
      working=$2
      shift 2
      ;;
    --)
      break
      ;;
  esac
done

【讨论】:

  • 谢谢您,可能会将您的答案设置为解决问题。退出后为什么不设置一个值?为什么我必须为需要参数的选项 w 移动 2 次? (理论上,当我使用 bashscript -w y 时会发生什么?)我也想在调用错误时立即显示使用情况,即使那个人没有要求 -h|--help
  • @dockerwonderer 你可以像bash -x ./scriptname -w foo 这样运行脚本来查看选项参数会发生什么。
  • @dockerwonderer 你的意思是以非零状态退出?使用将是一个正常的情况,但我添加了一个出口 1 当 getopt 发现无效的语法。 -w y 表示 $1 是“-w”,$2 是“y”。您通常将事物分配给变量。 working=$2; shift 2。将出口替换为 usage(1) 和 exit $1 in usage 以满足您的最后一个要求。我用这个变化更新了答案。
  • 谢谢我学到了很多。最后两个问题:如果我只想为是/否的情况做点什么? (您还可以在脚本中的 case -w 中执行一些操作)。是否存在一种同时包含 1-dash-full-"working"/1-dash-full-"help" 以及 no-dash-short-"y/n"/no-dash-long-" 的方法是/否”?
  • 好吧,它现在所做的就是设置变量。处理完所有参数后,您决定如何处理这些if [ "$yes" = 0 ] then ...。在我的 getopt 版本中,您可以使用 getopt -a 获得 -long-option 功能。如果您还争论处理参数(没有 -,-),那么您必须在处理选项后遍历它留下的任何内容。也许更改为 while [ $# -gt 0 ] 和 -- 只会做一个转变,让循环决定何时完成。然后为每种情况添加-n|--no|n。参数是位置参数,通常是必需的,因此它是一种非标准语法。
猜你喜欢
  • 2012-09-12
  • 2014-03-13
  • 1970-01-01
  • 2022-08-06
  • 1970-01-01
  • 2018-05-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多