Bash 函数调用另一个需要传递用户定义选项的函数

Bash 函数调用另一个需要传递用户定义选项的函数

plist我有一个能够调用head和命令的函数tail。但对于处理区域,我调用了不同的函数pregion

# --- plist ---

  ("-H"|"--head")
    local -r hn="$2" ; shift 2 ;;
  ("-T"|"--tail")
    local -r tm="$2" ; shift 2 ;;

  ("--FS")                           # field separator
    local fs="$2" ; shift 2 ;;
  ("--incl")
    local incl+=("$2") ; shift 2 ;;  # file type suffix
  ("--excl")
    local excl+=("$2") ; shift 2 ;;  # file type suffix

  ("--RP")
    local pn=$2 ; shift 2 ;;
  ("--RQ")
    local qn=$2 ; shift 2 ;;

  ("--dyn"|"--dynamic")
    local dyn="1" ; shift 1 ;;
  ("-C"|"--context")
    local ctx=$2 ; shift 2 ;;

  ("-d"|"--directory")
    local fdir=$2 ; shift 2 ;;

  (--)
    shift;  break  ;;

  ...

  if [[ -v hn ]]; then

     head -v -hn "$n"
    
  elif [[ -v tm ]]; then

    tail -v -n "$tm"

  elif [[ -v dyn ]]; then

    pregion "$@"  # requires original options here

  fi

对于headand tail,我只使用选项-H' -T, --FS, and --incl。因为我在处理选项时使用shift,所以我需要原始plist输入参数的副本,因为我不能简单地传递"$@"pregion.

这将调用headtail

  plist -H 8 ./01cuneus

  plist -T 13 ./01cuneus

调用示例pregion

plist --dyn -C 8 "Martin" ./01cuneus

plist --incl .texi --incl .org --RP 8 --RQ 13 ./01cuneus

plist --incl .texi --incl .org --dyn -C 8 "Martin" ./01cuneus

答案1

将原始参数复制到数组中,并将其与pregion.例如

plist() {
  local -a origargs=("$@")
  ...
  case
    ...
  esac
  ...

  if
    ...
  elif [[ -v dyn ]]; then
    pregion "${origargs[@]}"
  fi

答案2

您确实可以将 的内容保存$@到数组中

plist() {
    local args
    args=("$@")
    case $1 in ...
        # some shifting etc.
    esac
    if something; then
        pregion "${args[@]}"
    fi
}

但是,这意味着pregion需要再次进行整个选项处理。实际上,您可以在两个地方实现相同的过程。那么返回无效选项的错误又如何呢plist?在确定是否要致电之前,您不能这样做pregion,因为它可能接受某些选项,但plist不接受。

相反,我建议仅执行一次选项解析,然后使用pregion已解析为各个参数的适当值进行调用:

plist() {
    local args
    args=("$@")
    local this=default that=otherdefault
    local call_pregion=
    case $1 in ...
        this) this=$2; shift; shift;;
        that) that=$2; shift; shift;;
        dyn) call_pregion=1
    esac
    if [ "$call_pregion" ]; then
        pregion "$this" "$that"
    fi
}

这样pregion就可以从列表中的静态位置获取值,例如$1for$this$2for $that

另外,顺便说一句,使用shift 2那里是有风险的。根据 shell 的不同,它可能会默默地失败,因为没有足够的参数来转换。例如,set a b c; shift 4; echo $1在 Dash 中会出现错误并退出,但在 Bash 中,它会很高兴地只打印a。如果用户给出的选项没有相应的选项参数,这可能会使您的选项解析陷入循环。

相关内容