如何编写一个提供默认参数的非常简单的包装器?

如何编写一个提供默认参数的非常简单的包装器?

给定一个需要一些参数的程序,例如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

  • 将所有参数 ( $*) 传递scriptprogramtoo
  • 检查您感兴趣的每个参数,如果它已经在传递的参数中,则忽略它。否则使用默认参数值

示例代码

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,您可以找到更多信息这里

相关内容