Ao executar um shell script, é possível passar parâmetros posicionais específicos sem precisar inseri-los todos em ordem?

13

Por exemplo, se eu tiver o script ./foo, isso leva 10 parâmetros, e eu só quero passar o 8º parâmetro. A única maneira de saber como fazer isso atualmente é:

./foo '' '' '' '' '' '' '' 'bar'

Existe uma maneira mais fácil / melhor?

    
por Kerry Randolph 07.09.2014 / 14:22

2 respostas

4

Outra maneira de fazer isso é nomear o parâmetro que você deseja declarar e, em seguida, faça isso:

{   cat >./foo 
    chmod +x ./foo
    eight=declared ./foo
    eight=declared_and_preferred \
        ./foo 1 2 3 4 5 6 7 8
    ./foo 1 2 3 4 5 6 7 8
    ./foo
} <<\SCRIPT
#!/usr/bin/sh
: ${eight:=${8:-some_default}}
printf '$eight = %s\n' "$eight"
#END
SCRIPT

OUTPUT

$eight = declared
$eight = declared_and_preferred
$eight = 8
$eight = some_default

No exemplo acima, a variável de ambiente explicitamente declarada é preferível ao argumento da linha de comando, mas o argumento da linha de comando é usado quando a variável de ambiente está vazia ou não definida. Quando a 8ª posição e a variável de ambiente $eight estiverem vazias ou o valor padrão some_default for atribuído a $eight . Em ambos os casos, o : pode ser removido das declarações :- ou := se vazio deve ser um valor aceitável.

A variável $eight também poderia ter sido definida como:

printf '$eight = %s\n' "${eight:=${8:-some_default}}"

... e a linha anterior foi omitida completamente, mas eu queria demonstrar que declarar uma variável dessa maneira resulta em um valor persistente, e assim eu fiz isso em dois comandos. De qualquer forma, $eight é definido para o valor final da expansão desse parâmetro composto.

getopts - para scripts robustos - geralmente é a melhor maneira de manipular o comando opções . Os parâmetros posicionais, por outro lado, são quase sempre os meios mais simples de lidar de maneira robusta com operandos em um script.

Por exemplo:

touch file$(seq -ws\ file 100)
./foo *

OUTPUT

$eight = file008

Lá, vemos apenas o oitavo operando, mas há 101 deles no meu diretório de teste.

    
por 08.09.2014 / 06:57
18

Supondo que você possa alterar o script, considere o uso de parâmetros opcionais (opções) em vez dos parâmetros obrigatórios (argumentos).

Se você tiver cada um dos sete primeiros sete parâmetros como opções e tê-los como padrão para a sequência vazia, você poderá fazer:

./foo bar

Se você usar um shell compatível com POSIX , poderá usar o getopts ou o programa getopt . bash - como a maioria dos shells - oferece getopts como um built-in. De qualquer maneira é mais fácil do que rolar seu próprio analisador de linha de comando.

A menos que você implemente algo como os últimos X argumentos não-opcionais, são os valores para os últimos argumentos Y e argumentos da opção XY você deve fornecer strings de opção antes de cada uma das 7 (agora vazias) strings se você quiser Essa. No entanto, isso não é uma prática comum, normalmente, uma opção é sempre uma opção e um argumento é um argumento, e a ordem da opção "inserção" é gratuita.

    
por 07.09.2014 / 14:37