Como escrever um wrapper muito simples que fornece parâmetros padrão?

5

Dado um programa que requer alguns parâmetros, por ex. program -in file.in -out file.out , qual seria a abordagem mais simples para escrever um script bash que poderia ser chamado com ou sem qualquer um desses parâmetros e usar valores padrão para cada um?

script -in otherfile executaria program -in otherfile -out file.out , e script -out otherout -furtherswitch executaria program -in file.in -out otherout -furtherswitch etc.

    
por Tobias Kienzler 07.02.2013 / 10:58

4 respostas

7

Um valor padrão é fácil de definir no 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

Para processar seus parâmetros, você pode usar um loop simples:

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}" "$@"

Leituras úteis:

Eu também recomendo usar getopt , porque ele é capaz de lidar com muitos casos especiais que complicariam muito rapidamente e bagunçariam seu código ( Exemplo não trivial ).

    
por 07.02.2013 / 11:54
3

A resposta de l0b0 mostra como definir um valor padrão através da atribuição e verificação do estado de outra variável (embora, é claro, você também possa fazer isso operando na mesma variável que você está atribuindo), mas há uma maneira mais concisa de fazer a mesma coisa:

: "${foo=bar}" # $foo = bar if $foo is unset
: "${foo:=bar}" # $foo = bar if $foo is unset or empty
    
por 07.02.2013 / 13:59
1
  • Transmitir todos os parâmetros ( $* ) passados para script para program too
  • Verifique cada parâmetro que você está interessado, se já está nos parâmetros passados, então ignore-o. caso contrário, use o valor do parâmetro padrão

Código de amostra

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

Você pode adicionar facilmente mais parâmetros / valores padrão adicionando mais elementos de matriz em $interested_parameter_names e $default_parameter_values

Exemplo de saída

$ ./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

Nota

Ao passar parâmetros que contenham espaço, ele deve ser escapado por \ , não apenas os citados. Exemplo:

./script -in new\ document.txt
    
por 07.02.2013 / 12:19
1

Você tem duas maneiras, como sempre, simples e difíceis. Simples é usar variáveis internas, por exemplo

program -in otherfile -out file.out

Aqui, as variáveis são

$ 0 = O nome do script
   $ 1 = em    $ 2 = otherfile, etc.

A maneira mais difícil é usar getopt , mais informações você pode encontrar aqui .

    
por 07.02.2013 / 11:19