0

脚本nerf调用脚本herd,脚本调用脚本ernerf使用一个标志herd,明确接受需要传递给的参数er

这在以前不是问题nerf- 当herd刚刚从命令行调用时,我们可以单引号将参数传递给 -p 标志,它们永远不会被herd's解释getopts,而是会被er's解释getopts

但是现在我们已经在最终需要转到的标志中生成了值er,所以我需要在 中扩展变量,但$file_contents在它们到达之前nerf不要让它们被解释。getoptser

这三个脚本中的任何一个都可以修改。

$ cat nerf
#!/bin/bash
file_contents="`cat one_liner_file`"
er_args="-jkl -m $file_contents"
./herd -p "$er_args"              # <-- the problem


$ cat herd
#!/bin/bash
passthru_args=""
while getopts "p:a:b:cde" opt
do
  case $opt in
    p) passthru_args="$OPTARGS" ;;
    ...
  esac
done
./er "$passthru_args"


$ cat er
#!/bin/bash
while getopts "jklm:" opt
do
  case $opt in
    ...
  esac
done

如果我在上面的标记行上使用单引号,我会得到传递的文字字符串 "$er_args"。使用双引号,标志直接由herd. 使用单引号内的双引号,任何 getopts 都不会解释标志。

我认为这里没有优雅的解决方案,但如果我错了,请告诉我。我能想到的唯一解决方案是糟糕的:

  1. 通过 . 显式公开所有er的标志herd
  2. 从 中删除er呼叫herd并将其直接放入nerf.
  3. ???
4

1 回答 1

3

许多工具所做的是在传递时-p "-jkl -m something",它们使用伪 shell 语法拆分字符串。这是一个坏主意,因为它使空间和报价处理变得不可预测。

相反,更好的方法是有一种方法将单个单词传递给命令。这就是find -exec所做的——所有在or之后-exec和之前的参数都作为单独的参数逐字传递。+;

这是一个herd具有相同语义的简单示例:

#!/bin/bash
passthru_args=()
while getopts "pa:b:cde" opt
do
  case $opt in
    p)
      while [[ ${!OPTIND} != ';' ]]
      do
        passthru_args+=("${!OPTIND}")
        let OPTIND++
      done
      let OPTIND++
    ;;
    *) echo "herd: $opt is $OPTARG"
    ;;
  esac
done
./er "${passthru_args[@]}"

您现在可以运行./herd -p -jkl -m "some stuff" \; -a foo

这将./er -jkl -m "some stuff"安全运行而没有任何空间问题(但您将很难嵌套多个;用作参数终止符的调用)。

于 2014-05-13T21:15:30.043 回答