给定一个需要一些参数的程序,例如program -in file.in -out file.out
,编写可以使用或不使用任何这些参数来调用并为每个参数使用默认值的 bash 脚本的最简单方法是什么?
script -in otherfile
会跑program -in otherfile -out file.out
,
script -out otherout -furtherswitch
会跑program -in file.in -out otherout -furtherswitch
等等。
答案1
在 Bash 中很容易定义默认值:
foo="${bar-default}" # Sets foo to the value of $bar if defined, "default" otherwise
foo="${bar:-default}" # Sets foo to the value of $bar if defined or empty, "default" otherwise
要处理您的参数,您可以使用一个简单的循环:
while true
do
case "${1-}" in
-in)
infile="${2-}"
shift 2
;;
-out)
outfile="${2-}"
shift 2
;;
*)
break
;;
esac
done
program -in "${infile-otherfile}" -out "${outfile-otherout}" "$@"
有用的读物:
我还建议使用getopt
它,因为它能够处理许多特殊情况,这些情况会很快使您的代码变得复杂和混乱(重要的例子)。
答案2
l0b0 的答案显示了如何通过赋值和检查另一个变量的状态来设置默认值(当然,您也可以对要赋值的同一变量执行此操作),但是有一种更简洁的方法可以完成相同的操作:
: "${foo=bar}" # $foo = bar if $foo is unset
: "${foo:=bar}" # $foo = bar if $foo is unset or empty
答案3
- 将所有参数 (
$*
) 传递script
给program
too - 检查您感兴趣的每个参数,如果它已经在传递的参数中,则忽略它。否则使用默认参数值
示例代码
interested_parameter_names=(-in -out)
default_parameter_values=(file.in file.out)
program=echo
cmd="$program $*"
for ((index=0; index<${#interested_parameter_names[*]}; index++))
do
param="${interested_parameter_names[$index]}"
default_value="${default_parameter_values[$index]}"
if [ "${*#*$param}" == "$*" ] # if $* not contains $param
then
cmd="$cmd $param $default_value"
fi
done
echo "command line will be:"
echo "$cmd"
echo
echo "execute result:"
$cmd
$interested_parameter_names
您可以通过在和中添加更多数组元素来轻松添加更多默认参数/值$default_parameter_values
样本输出
$ ./wrapper.sh -in non-default.txt -other-params
command line will be:
echo -in non-default.txt -other-params -out file.out
execute result:
-in non-default.txt -other-params -out file.out
笔记
当传递包含空格的参数时,应该用 转义\
,而不仅仅是引用它们。例子:
./script -in new\ document.txt
答案4
像往常一样,你有两种方法:简单的和困难的。简单的是使用内部变量,例如
program -in otherfile -out file.out
这里变量是
$0 = 脚本名称
$1 = -in
$2 = otherfile 等。
困难的方法是使用getopt
,您可以找到更多信息这里。