Script nerf调用script herd,后者调用脚本er。nerf在herd上使用一个标志,该标志显式地接受需要传递给er的参数。
在nerf存在之前,这不是一个问题--当herd刚刚从命令行被调用时,我们可以将参数单引号引用到-p标志,它们永远不会被herd的getopts解释,而是由er的getopts来解释。
但是现在我们已经在标志中生成了值,这些标志最终需要转到er,所以我需要在nerf中扩展变量$file_contents,但在它们到达er之前不让getopts对它们进行解释。
这三个脚本中的任何一个都可以修改。
$ 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解释。
我认为这里没有优雅的解决方案,但如果我错了,请告诉我。我唯一能想到的解决办法是拙劣的:
er显式地公开herd的所有标志。er中删除herd调用,并将其直接放入nerf中。发布于 2014-05-13 21:15:30
许多工具所做的是,当传递-p "-jkl -m something"时,它们使用伪shell语法拆分字符串。这是一个不好的想法,因为它使空间和报价处理不可预测。
相反,更好的方法是有一种将单个单词传递给命令的方法。这就是find -exec所做的--在-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",不会出现任何空间问题(但您将很难嵌套使用;作为参数终止器的多个调用)。
https://stackoverflow.com/questions/23641259
复制相似问题