Usando um loop para gerar argumentos de linha de comando

0

Eu estou tentando usar um loop for para executar argumentos de linha de comando, nunca tentei isso e estou tendo alguns problemas.

Estou usando os seguintes comandos:

for((a=1; a<20; a++)); 
do 
    ./a.out -N 10000 -D .25*a -E 0.7788007831;
done

Estou usando a função getopt em c para ler valores. Eu quero tentar valores diferentes de D (chamado Delta na saída). No entanto, quando eu executo este comando, obtenho:

Acceptance rate is: 0.928400
Estimate is:        0.758704
Error is :          0.020097
Delta used:         0.250000

Acceptance rate is: 0.928400
Estimate is:        0.758704
Error is :          0.020097
Delta used:         0.250000

Acceptance rate is: 0.928400
Estimate is:        0.758704
Error is :          0.020097
Delta used:         0.250000

Acceptance rate is: 0.928400
Estimate is:        0.758704 
Error is :          0.020097
Delta used:         0.250000

...

Acceptance rate is: 0.928400
Estimate is:        0.758704
Error is :          0.020097
Delta used:         0.250000

Não sei qual é o problema.

    
por John Meighan 02.01.2018 / 16:46

1 resposta

2

Por um lado, se você quiser se referir a uma variável shell, você precisa usar a notação $foo . a é apenas a letra "a" (da mesma forma que 10000 é apenas os cinco dígitos), mas $a se expande para o que a variável contém no momento.

Dois, para fazer aritmética no shell, a sintaxe para expansão aritmética é $(( expression )) , então você pode escrever $(( 25 * $a )) para obter o valor de a vezes 25. (como um número base 10).

Embora o problema que você enfrentaria aqui, é que Bash (e o shell POSIX) só pode fazer aritmética em inteiros, então multiplicar com 0.25 não vai funcionar.

Em zsh, a aritmética de ponto flutuante funciona, portanto, você poderia fazer, por exemplo.

for ((a=1; a<20; a++)); do 
    echo $((.25 * $a))
done

Mas no Bash ou shell padrão, você precisará usar um programa externo para fazer as contas:

for ((a=1; a<20; a++)); do 
    echo $( echo ".25 * $a" | bc -l )
done

Ou no seu comando:

for ((a=1; a<20; a++)); do 
    ./a.out -N 10000 -D $( echo ".25 * $a" | bc -l ) -E 0.7788007831;
done

Claro, se o programa que você está executando puder fazer a multiplicação e você quiser apenas passar as strings .25*1 , .25*2 etc para ele, então você usaria

... -D ".25*$a"

com as aspas em torno dele , caso contrário, o * é considerado como uma correspondência de nome de arquivo (glob) . (Na verdade, você geralmente quer colocar aspas na maioria dos lugares onde você usa expansões de variáveis ou substituições de comandos, mas vamos apenas nos referir a Quando está citando aspas duplas necessárias? sobre isso.)

Existem várias maneiras de fazer a matemática de ponto flutuante no shell apresentado aqui: Como fazer inteiro & cálculos de flutuação, em bash ou outras linguagens / frameworks?

    
por 02.01.2018 / 16:58