假设我有一些可以接受多个选项的实用程序,每个选项后跟一个文件名。例如,我可以将其称为 myutil
、 myutil -o somefile
、 myutil -p anotherfile
、 myutil -o somefile -p anotherfile
等......我想编写一个包装器 POSIX shell 脚本,它能够使用任意选项组合调用 myutil
(取决于包装器脚本内部的某些条件) ,与此问题无关)。
我想过做这样的事情:
#!/bin/sh
file1=somefile
file2=anotherfile
if [ somecriteria = true ]; then
OPT1="-o $file1"
fi
if [ othercriteria = true ]; then
OPT2="-p $file2"
fi
myutil $OPT1 $OPT2
这很好用——只要两个文件名都没有空格:假设两个
if
都为真,myutil
得到 $1 = [-o]、$2 = [somefile]、$3 = [-p] 和 $4 = [anotherfile]。但是,如果有空格,例如,如果 file1="some file"
, $1 = [-o], $2 = [some], $3 = [file] 等。当然,我想要的是 $2 = [some file]。在 OPT1 和 OPT2 中的文件名周围加上另一组引号无济于事;例如,如果我将其更改为
OPT1="-o \"$file1\""
,那只会让我得到 $2 = ["some] 和 $3=[file"]。在调用 myutil
时在 $OPT1 和 $OPT2 周围加上引号也不起作用:如果我这样做,$1 = [-o some file]。那么,是否有一些技巧可以让这个工作,或者其他一些可以做我想要的方法?我希望它坚持标准 shell 功能,因此 没有 bash-isms 或 ksh-isms,请使用 :) 有关标准中的内容的描述,请参阅 this。
最佳答案
似乎您找到了一个不错的 POSIX 解决方案。但是,您可以使用 set
将程序调用维护为 myutil "$@"
。随着可能参数数量的增加,您的解决方案变得有点笨拙。
#!/bin/sh
file1=somefile
file2=anotherfile
if [ somecriteria = true ]; then
set -- "-o" "$file1"
fi
if [ othercriteria = true ]; then
set -- "$@" "-p" "$file2"
fi
myutil "$@"
例子
#!/bin/sh
file1="some file"
file2="another file"
# Default to '1' if not overwritten
: ${x:=1}
: ${y:=1}
if [ $x -eq 1 ]; then
set -- "-o" "$file1"
fi
if [ $y -eq 1 ]; then
set -- "$@" "-p" "$file2"
fi
printf "[%s]" "$@"
echo
输出
$ x=0 y=0 ./opt.sh
[]
$ x=0 y=1 ./opt.sh
[-p][another file]
$ x=1 y=0 ./opt.sh
[-o][some file]
$ x=1 y=1 ./opt.sh
[-o][some file][-p][another file]
关于shell - Bourne/POSIX shell 参数拆分,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4745108/