неудачное использование bc в математических операциях с плавающей точкой в ​​shel - PullRequest
0 голосов
/ 05 февраля 2019
#!/bin/bash
    step=0.05
    short=0.05
    long=0.95
    for firstloop in {1..20}; do
        ratio=0.05
        for secondloop in {1..20} ; do
            echo $short $long $ratio >> file.txt
            time python3 main.py $short $long $ratio >> file.txt
            ratio= `echo $ratio + $step` | bc
        done
        short= `echo $short + $step`| bc
        long= `echo $long + $step`| bc

    done

когда я выполняю код, вот что я получаю:

./script.sh: line 10: 0.05: command not found

real    0m25.329s
user    0m24.770s
sys 0m0.263s
./script.sh: line 10: 0.05: command not found

real    0m34.666s
user    0m32.319s
sys 0m0.623s
./script.sh: line 10: 0.05: command not found

real    0m31.425s
user    0m29.329s
sys 0m0.588s
./script.sh: line 10: 0.05: command not found

Я перепробовал много вариантов, чтобы я мог увеличивать переменные short , long и коэффициент с плавающей запятой.Я знаю, что не могу иметь дело с математическими точками с плавающей точкой в ​​оболочке, если я не использую bc .Я все еще не преуспел.что я делаю не так?

После исправления ошибок пробелов и формата bc, как указано в ответе ниже.Я остался с этим выводом:

real    0m0.871s
user    0m0.497s
sys 0m0.166s
++ echo '0 + 0.05'
++ bc
+ ratio=.05
+ for secondloop in '{1..20}'
+ echo 0 1 .05
+ python3 main.py 0 1 .05
Traceback (most recent call last):
  File "main.py", line 46, in <module>
    main()
  File "main.py", line 17, in main
    probability = [float(x) for x in sys.argv[:2]]
  File "main.py", line 17, in <listcomp>
    probability = [float(x) for x in sys.argv[:2]]
ValueError: could not convert string to float: 'main.py'

это в основном то, что я получаю неоднократно, в то время как значения переменной 3 изменяются.

1 Ответ

0 голосов
/ 05 февраля 2019

Сначала я сделаю рекомендацию по стилю: используйте $( ) вместо обратных галочек.Они в основном эквивалентны, за исключением того, что они легче для чтения и имеют немного более чистый синтаксис (использование экранированных символов внутри обратных кавычек или вложенных обратных кавычек ... странно).Кроме того, обычно рекомендуется помещать двойные кавычки вокруг ссылок на переменные (например, использовать python3 main.py "$short" "$long" "$ratio" вместо python3 main.py $short $long $ratio).

Теперь реальные проблемы: во-первых, вы не можете ставить пробелы вокруг= в задании, или оно будет проанализировано как нечто совершенно иное.В общем, пробелы являются критическими разделителями в синтаксисе оболочки, и вы не должны ни добавлять, ни удалять их при копировании примеров.

Сравните эти команды:

ratio=0.05
ratio= 0.05
ratio = 0.05

Первый делает то, что выглядитlike - устанавливает переменную ratio в «0.05».Второй эквивалент ratio='' 0.05 - он пытается запустить «0,05» в качестве команды, с переменной, установленной в пустую строку.Это то, что делает ваш скрипт, поэтому вы получаете сообщение об ошибке «0.05: команда не найдена».Третья команда пытается запустить «ratio» в качестве команды и передать ей аргументы «=» и «0,05».

Вторая проблема заключается в том, что у вас есть канал к bc вне захвата.Сравните эти команды:

ratio=$(echo "0.05 + 0.05" | bc)
ratio=$(echo "0.05 + 0.05") | bc

Сначала выполняется echo "0.05 + 0.05" | bc как конвейер, а затем захватывает выходные данные и сохраняет их в переменной ratio.Это то, что вы хотите.Второй устанавливает ratio на «0,05 + 0,05» (выход echo "0.05 + 0.05"), а затем направляет вывод этого (нет) на bc.Вывод bc (если он есть) будет выводиться на терминал, а не захватываться.

Таким образом, вы должны заменить каждую строку следующим образом:

ratio= `echo $ratio + $step` | bc

накак то так:

ratio=$(echo "$ratio + $step" | bc)
...