【问题标题】:Assigning argument to a positional parameter [closed]将参数分配给位置参数[关闭]
【发布时间】:2021-10-17 17:48:13
【问题描述】:

我正在调用具有大量参数的 shell 脚本,例如./train-rnn.sh 0 0 0 "63 512"。是否可以将每个参数分配给特定的位置参数?例如

./train-rnn.sh $1=0 $2=0 $4=0 $3="63 512"

【问题讨论】:

  • XY 问题是询问您尝试的解决方案,而不是您的实际问题。
  • 不是这种形式。您要解决的实际问题是什么?

标签: bash positional-parameter


【解决方案1】:

Bash 没有这方面的机制,但你可以做点什么。

最好的方法是解析脚本中的命令行参数。在这种情况下,您可能希望通过允许option=argument 形式的选项来改善您的用户体验,而不是让用户(和开发人员也一样!)记住$1$2 等的含义。

#! /usr/bin/env bash
declare -A opt
for arg; do
  if [[ "$arg" =~ ^([^=]+)=(.*) ]]; then
    opt["${BASH_REMATCH[1]}"]=${BASH_REMATCH[2]}
  else
    echo "Error: Arguments must be of the form option=..." >&2
    exit 1
  fi
done
# "${opt["abc"]}" is the value of option abc=...
# "${opt[@]}" is an unordered (!) list of all values
# "${!opt[@]}" is an unordered (!) list of all options

示例用法:

script.sh abc=... xyz=...

如果你真的想坚持位置参数,使用

#! /usr/bin/env bash
param=()
for arg; do
  if [[ "$arg" =~ ^\$([1-9][0-9]*)=(.*) ]]; then
    param[BASH_REMATCH[1]]=${BASH_REMATCH[2]}
  else
    echo "Error: Arguments must be of the form $N=... with N>=1" >&2
    exit 1
  fi
done
if ! [[ "${#param[@]}" = 0 || " ${!param[*]}" == *" ${#param[@]}" ]]; then
  echo "Error: To use $N+1 you have to set $N too" >&2
  exit 1
fi
set -- "${param[@]}"
# rest of the script
# "$@" / $1,$2,... are now set accordingly

示例用法:

script.sh $1=... $3=... $2=...

如果您的脚本/程序无法修改,上述方法也可以用作包装器。为此,请将set -- "${param[@]}" 替换为exec program "${param[@]}",然后使用wrapper.sh $1=... $3=... $2=...

【讨论】:

  • 正则表达式需要=~ 运算符,opt[BASH_REMATCH[1]] 应该是opt[${BASH_REMATCH[1]}]
  • @IonuțG.Stan 感谢您的通知。我更正了错字=/=~ 和错误opt[BASH_REMATCH[1]]。我已经习惯于使用常规数组,其[...] 是一个算术上下文,我完全忘记了这里的$
猜你喜欢
  • 2012-11-25
  • 2022-10-12
  • 2013-06-04
  • 1970-01-01
  • 2017-05-11
  • 2019-01-23
  • 2019-12-02
相关资源
最近更新 更多