【问题标题】:Bash Script with Parsing Argument in LinuxLinux 中带有解析参数的 Bash 脚本
【发布时间】:2015-12-25 21:30:22
【问题描述】:

我想写一个 bash 脚本:

schedsim.sh [-h] [-c x] -i pathfile

地点:

• -h:打印当前用户名。

• -c x :获取选项参数 x 并打印出 (x + 1)。如果没有找到参数,则打印默认值为 1。

• -i pathfile:打印路径文件的大小。路径文件是必需的参数。如果未找到参数,则打印错误消息。

这是我到目前为止所做的:

x=""
path=""
while getopts ":hc:i:" Option
do
case $Option in
h) echo -e "$USER\n"
;;
c) x=$optarg+1
;;
i) path=$(wc -c <"$optarg")
;;
esac
done

if [ -z "$x"] 
then
 echo -e "$x\n"
else
 echo 1
fi

if [ -z "$path"] 
then
 echo $path
else
 echo "Error Message"
 exit 1
fi

如何完成option-argument、required-argument部分和error message部分?

【问题讨论】:

  • 也许您可以获取所有值并首先将它们设置为变量,而不是循环。然后你可以检查 i 是否通过,然后再进行任何其他处理:if [ -z "$i" ]...,如果没有通过,则打印使用情况。
  • 我编辑了,对吗?

标签: linux bash arguments


【解决方案1】:

我认为您正在寻找的是 bash 中的“参数解析”。请看看这个优秀的答案:https://stackoverflow.com/a/14203146/3380671

关于这个必需/可选部分:用空字符串初始化变量,并在参数解析后检查字符串的长度。

FILE_PATH=""
# Do the argument parsing here ...
# And then:
if [ -z "$FILE_PATH" ]
then
  echo "Please specify a path. Aborting."
  exit 1
fi

【讨论】:

    【解决方案2】:

    重写:

    while getopts ":hc:i:" Option; do
        case $Option in
            h)  echo "$USER"
                ;;
            c)  x=$(($OPTARG + 1))
                ;;
            i)  if [[ -f $OPTARG ]]; then
                    size=$(wc -c <"$OPTARG")
                else
                    echo "error: no such file: $OPTARG"
                    exit 1
                fi 
                ;;
        esac
    done
    
    if [[ -z $x ]]; then
        echo "you used -c: the result is $x"
    fi
    
    if [[ -z $size ]]; then
        echo "you used -i: the file size is $size"
    fi
    

    注意事项:

    • OPTARG 必须大写。
    • 你需要 $((...)) 来进行 bash 算术
    • 使用前检查文件是否存在
    • 使用合理的文件名(path 不代表文件的大小)
    • ] 之前必须有一个空格
    • echo -e "value\n" 工作量太大:你只需要echo "value",除非你想处理值中的转义序列:

      $ var="foo\tbar\rbaz"
      $ echo "$var"
      foo\tbar\rbaz
      $ echo -e "$var\n"
      baz bar
      
      $ 
      

    更新:响应 cmets:简化和更完整的选项处理;扩展错误处理。

    #!/bin/bash
    declare -A given=([c]=false [i]=false)
    x=0
    path=""
    
    while getopts ":hc:i:" Option; do
        case $Option in
            h)  echo "$USER"
                ;;
            c)  x=$OPTARG
                given[c]=true
                ;;
            i)  path=$OPTARG
                given[i]=true
                ;;
            :)  echo "error: missing argument for option -$OPTARG"
                exit 1
                ;;
            *)  echo "error: unknown option: -$OPTARG"
                exit 1
                ;;
        esac
    done
    
    # handle $x
    if [[ ! $x =~ ^[+-]?[[:digit:]]+$ ]]; then
        echo "error: your argument to -c is not an integer"
        exit 1
    fi
    if ! ${given[c]}; then
        printf "using the default value: "
    fi
    echo $(( 10#$x + 1 ))
    
    # handle $path
    if ! ${given[i]}; then
        echo "error: missing mandatory option: -i path"
        exit 1
    fi
    if ! [[ -f "$path" ]]; then
        echo "error: no such file: $path"
        exit 1
    fi
    echo "size of '$path' is $(stat -c %s "$path")"
    

    【讨论】:

    • 请注意,您应该检查-c 的参数是否是一个数字(否则它会受到任意代码执行),并且可能会在前面加上10# 以避免August 错误。
    • @gniourf_gniourf 那么如何检查呢?
    • @DươngAnhKhoa:类似于[[ $OPTARG = +([[:digit:]]) ]] || { echo "Argument to -c is not a number"; exit 1; }。
    • “如果未找到参数,则打印默认值为 1。”部分在哪里?感谢您的帮助!
    猜你喜欢
    • 2021-12-03
    • 1970-01-01
    • 2013-04-21
    • 2014-06-05
    • 2013-10-09
    • 2021-06-09
    • 2017-11-29
    • 2018-08-27
    • 2019-02-08
    相关资源
    最近更新 更多