【问题标题】:How to check if arguments are legit?如何检查论点是否合法?
【发布时间】:2015-04-19 14:25:23
【问题描述】:

我必须编写一个 bash 脚本来计算文本文件中的所有命令。脚本的参数是-p-n num 和一个文件。这意味着像这样的命令:

script.sh -n 3 -p file.txt
script -p -n 3 file.txt

和类似的都是合法的。

但是,对于与此不相似的任何命令,我必须回显错误:例如 script.sh -n -k file.txt

这是link to my code

我设法让它工作,但它太长而且多余。有什么方法可以让我在短时间内做到这一点?

【问题讨论】:

  • 比什么短,究竟是什么?请展示你所拥有的。
  • 您是在使用内置的getopts 还是GNU getopt
  • 好的,就是这样。我发现它不起作用 100% right-script.sh -n 3 -k 可以正常工作,即使 -k 不是一个合法的命令。 pastebin.com/nPict57R
  • 我已经发布了一些关于这两个标准工具的信息。您可能想尝试一下,它们可以为您节省很多时间。一段时间后,您当前的代码将难以阅读。
  • @rok,您对什么是“合法”非常具体。究竟允许哪些选项?他们中的哪一个会争论?哪些是强制性的?没有具体要求,你应该如何得到你想要的?

标签: bash


【解决方案1】:

您可能想查看以下标准命令之一:

  • getopts 是内置的 Bash。它更新且易于使用,但不支持长选项 (--option)。
  • getopt 是一个外部程序,可能涉及更多的胶水代码。有不同的实现。 getopt 通常支持长选项。

这是一个小的getopts 示例(修改了此external site 的示例之一):

#!/bin/bash

flag=off
dir=

# iterate over each option with getopts:
while getopts fd: opt
do
    case "$opt" in
      f)  flag=on;;
      d)  dir="$OPTARG";;
      *)  echo >&2 "usage: $0 [-f] [-d directory] [file ...]"
      exit 1;;
    esac
done

# remove all positional pararmeters we already 
# handled from the command line:
shift $(( expr $OPTIND - 1 ))

# main part of your program, remaining arguments are now in
# $@ resp. $0, $1, ...

【讨论】:

  • 嗯,我认为有一种更简单的方法可以做到这一点。到目前为止我所做的是:pastebin.com/nPict57R 它可以正常工作,唯一的问题是当我这样做时它不会回显错误(示例):script.sh -n 3 -k file.txt ,看起来它只检查第一个参数
  • 你真的认为你的代码更简单吗?这实际上很难理解,因为它使用了 10 个条件,而且所有这些都是因为您试图手动考虑参数的顺序,而标准工具以透明且经过良好测试的方式为您做的事情。
  • 我想说它使用更简单的命令(if 语句,很少的 ands 和很少的 ors)。
  • 好的,我明白你的意思了,我刚刚看到这是一项任务,所以使用标准工具对你来说不如在商业环境中重要。还有一个问题...$1 != *.txt 是什么意思 - 文字字符串 *.txt 还是您的意思是 * 匹配所有字符?
  • 如果参数不以 .txt 结尾,则回显错误。
【解决方案2】:

我想推荐另一个比你的更容易阅读的 sn-p,因为它准确地描述了你在评论中指定的仅有的两个有效案例:

如果我想“调用”我的脚本,它必须如下所示:script.sh -n +number -p file.txtfile.txt 必须是最后一个参数,但-n-p 可以切换。

所以情况是($0$4):

  • script.sh-n+number-pfile.txt
  • script.sh-p-n+numberfile.txt

它只使用if 和 Bash 的逻辑运算符:

#!/bin/bash

if ! { [[ "$1" = "-n" ]] && [[ "$2" =~ ^-[0-9]+$ ]] && [[ "$3" = "-p" ]] && [[ "$4" =~ ".txt"$ ]] ; } &&
   ! { [[ "$2" = "-n" ]] && [[ "$3" =~ ^-[0-9]+$ ]] && [[ "$1" = "-p" ]] && [[ "$4" =~ ".txt"$ ]] ; }
then
    echo "Error" && exit 1
fi

注意事项:

  • 组({})语法要求在其列表末尾有一个;
  • 您必须使用正则表达式来检查*.txt
  • 您提供的数字正则表达式将要求数字以 - 开头,而在您的规范中您说 +

【讨论】:

  • 不幸的是,这两个只是示例,而不仅仅是可能的情况。 script.sh -n +number file.txt script.sh -p file.txt 也有效
  • @RokDolinar:好吧,有了这两个,其他人不会很难写,不是吗?关于您的$0 问题,这听起来不太可能,您是如何发现的?
  • @RokDolinar:如果你粘贴整个脚本,我可以快速浏览一下那个 0 美元的东西。
  • @RokDolinar:是的,对不起,忽略这一点,我修改了我的评论,引用不是问题。
  • @RokDolinar:这是允许的,有一行你只检查-p,你可能想在那里为一个空的$2添加另一个测试。我现在得走了。如果在开头使用set -x,Bash 会打印所有实际执行的语句。如果您需要更多,这可以帮助调试。祝你好运!
猜你喜欢
  • 2015-11-05
  • 1970-01-01
  • 1970-01-01
  • 2019-06-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多