Проблема bc о длинном выражении

Я хочу вычислить выражение в оболочке. Я использую следующий код:

pi=$(echo "scale=10; 4*a(1)" | bc -l) i=3 d=`expr (1+c($pi*($i/10)+$pi))/2 | bc -l` 

Но это говорит

 bad pattern: (1+c(3.1415926532*(3/10)+3.1415926532))/2 

Зачем?

3 Solutions collect form web for “Проблема bc о длинном выражении”

Потому что вы используете expr в своей последней команде, где вы, вероятно, должны использовать echo .

PS Советую вам использовать форму $(…) в обеих командах bc (а не `…` ).

Если вы примете мой совет, вы не будете использовать “ или $() – это немного глупо. bc – интерактивный, ориентированный на линию интерпретатор. Он читает строку из stdin, проверяет, нужен ли ей другой на основе только что прочитанного входа, а затем либо печатает свои результаты в stdout, либо запрашивает больше для stdin. Как и ваша оболочка, она даже откажется делать что-либо большее, чем вывод линейного буфера, даже если он написан не в терминале. Нет необходимости вообще вызывать новый bc для каждого вычисления – особенно в подстановке команд, которая также включает вызов целой новой оболочки и выделение нового канала.

Лучший способ – создать совместный процесс.

 # in a bash shell exec 8<> >( : ) 9< <( bc <&8 ) echo 'b=5;++b' >&8 read b <&9 echo "$b" 

 6 

И bc будет продолжать работать – все эти переменные значения, которые вы делаете, так много работают, чтобы перемещаться между эфемерными командами, замененными командами bc легче централизованно хранить в центральном bc .

 echo b\*b >&8; read b <&9; echo "$b" 

 32 

И еще лучше, так как я узнал, как это сделать на днях, вы можете поместить процесс bc на сервер сокетов.

 { ncat -l 9000 --allow localhost -k| bc; } <>/dev/fd/1 |:& 

И с оболочкой, которая говорит на языке /dev/tcp :

 { echo 'b=10;b' >&0; read b; echo "$b"; } <>/dev/tcp/localhost/9000 

 10 

Это может стать немного громоздким. Я написал небольшую функцию bchat() чтобы сделать ее проще.

 bchat(){ local IFS=\; ### separate on ; printf ${1+'%s;"\n"\n';}"$*" ### print \0 if no args set -- ### init args while read bchat && ### while read <bc "${bchat:+set}" -- "$@" "${bchat:=$*}" ### append to args do :; done 2>/dev/null ### and done } <>"$BC" >&0 ### $BC must be set 

После настройки сервера сокетов, как показано выше, вы можете использовать эту функцию, например:

 BC=/dev/tcp/localhost/9000 bchat b=5 x='(b--)' '"x="' ++x '"b="' --b echo "$bchat" 

 x=6;b=3 

… и снова это состояние будет сохраняться до тех пор, пока процесс bc …

Остерегайтесь того, что, когда вы устанавливаете масштаб, влияет на расчет.

Этот скрипт:

 bc -l << \EOF scale = 10 pi = 4 * a(1) i = 3 (1 + c(pi * (i / 10) + pi)) / 2 EOF bc -l << \EOF pi = 4 * a(1) i = 3 scale = 10 (1 + c(pi * (i / 10) + pi)) / 2 EOF bc -l << \EOF pi = 4 * a(1) i = 3 r = (1 + c(pi * (i / 10) + pi)) / 2 scale = 10 r/1 EOF bc -l << \EOF scale = 100 pi = 4 * a(1) i = 3 r = (1 + c(pi * (i / 10) + pi)) / 2 scale = 15 r/1 EOF 

выходы:

 .2061073736 .2061073739 .2061073738 .206107373853763 
  • оболочка неожиданный конец ошибки файла
  • Почему программированию на C не нужны сценарии компилятора и оболочки?
  • Сетевой ввод-вывод и дисковый ввод-вывод без установки каких-либо или использования сторонних библиотек
  • Выберите файл на основе количества строк и обработайте результат
  • Как заставить команду diff игнорировать некоторые строки второго файла (bash)?
  • Параллелизация цикла for
  • Проблемные цитаты
  • используя переменную «файл», полученную из «for» файла «in», и перейти к другому скрипту не удалось
  • Установка и размонтирование в том же сценарии оболочки приводит к ошибке
  • Выполнить ./script.sh vs bash script.sh - отклонено разрешение
  • Удаление пространства в начале переменных данных
  • Linux и Unix - лучшая ОС в мире.