Bash: Um argumento por uma variável indefinida

0

Digamos que eu crie um arquivo ~/myScript.sh :

#!/bin/sh

for myVar; do
    echo "Hi"
done

Se eu executar bash myScript sem argumentos, não receberei nada, mas se eu o executar com um ou mais argumentos, obterei a saída pelo número dessas variáveis (a variável parece fazer o script depende de argumentos passados) :

bash ~/myScript.sh arg0 arg1

O loop for, que é baseado na variável indefinida myVar , aplica arg0 e arg1 a si mesmo (desculpe se essa frase é ruim) e eu recebo esta saída:

Hi

Hi

(um "Hi" por argumento).

Originalmente, assumi que um loop for funciona com um argumento, portanto, se eu tivesse myVar_0 e myVar_1 com arg0 e arg1 , então myVar_0 funcionaria com arg_0 e myVar_1 funcionará com arg1 , mas eu testei mais e estava errado --- todos os for loops trabalharam com todos os argumentos:

#!/bin/sh

for myVar_0; do
    echo "Hi"
done

for myVar_1; do
    echo "Hello"
done

retornará em bash myScript arg0 arg1 :

Hi

hello

Hi

hello

Sidenote: Eu suponho que se quiser "1 argumento por 1 para loop" eu só preciso usar uma função Bash para escopo local.

Minha pergunta

Qual é o nome desse "todos os argumentos por todos os loops" correspondente ao Bash?

    
por Arcticooling 14.01.2018 / 13:45

2 respostas

2

myVar não é indefinido se o script for chamado com parâmetros posicionais. Do homem bash:

for name [ [ in [ word ... ] ] ; ] do list ; done
[...] If the in word is omitted, the for command executes list once for each positional parameter that is set

Mas você não usa $myVar .

for myVar; do
    echo "$myVar"
done
    
por 14.01.2018 / 14:05
1

O loop for no shell Bash / POSIX é semelhante a, e. o loop for no Python: a variável loop pega os valores listados, um a um, e o corpo do loop é executado uma vez para cada valor.

Então isso:

for x in foo bar; do
    echo "$x"
done
echo finally x is "$x" 

é semelhante a

x=foo        # assign value
echo "$x"    # loop body
x=bar        # same with the second value...
echo "$x"
echo finally x is "$x"   # this isn't part of the loop body

exceto que você não precisa repetir o corpo do loop. Se tivermos uma variável de matriz A , for x in "${A[@]}"; do... faz um loop sobre os valores da matriz. Da mesma forma, for x in "$@"; do... faz um loop sobre os parâmetros posicionais, ou seja, os argumentos da linha de comando, pois são para os quais "$@" se expande. E for x; do é basicamente uma abreviação para for x in "$@"; do

Então, isso imprimiria todos os argumentos da linha de comando:

for x; do                 # or: for x in "$@"; do
    printf "%s\n" "$x"
done

Para acessar os argumentos diretamente pelo índice, use $1 para o primeiro, $2 para o segundo argumento, etc ...

printf "the first arg is %s and the second is %s\n" "$1" "$2"
    
por 14.01.2018 / 14:25