Skip to content
Advertisement

Using bc as daemon in BASH shell from awk

# mkfifo inp out
# bc -ql  <inp  >out  &
[1] 6766
#
# exec 3>inp  4<out
# echo "scale=3; 4/5;" >&3
# read a <&4; echo $a
.800
#
# awk ' BEGIN { printf("4/5n") >"/dev/fd/3"; exit 1;} '
# read a <&4; echo $a
.800
#
# awk ' BEGIN { printf("4/5n") >"/dev/fd/3"; exit 1;} '
# awk ' BEGIN { getline a <"/dev/fd/4"; printf("%sn", a); } '
^C

In BASH environment I can communicate with bc program using fifo. But in awk I can write but no read with getline function. How can I read from “/dev/fd/4” in awk.

My awk version is: mawk 1.3.3 Nov 1996, Copyright (C) Michael D. Brennan

Thanks Laci

Continued:

I did some further experiment and I summarize my result. Awk script language suits best for my task, and I need to use “bc” because I have to count with very long numbers (about 100 digits). The next two scripts show that using named pipe is faster than unnamed (about 83 times).

1) With unnamed pipe:

# time for((i=6000;i;i--)); do a=`echo "$i/1"|bc -ql`; done
real    0m13.936s

2) With named pipe:

# mkfifo in out
# bc -ql <in >out &
# exec 3>in 4<out
#
# time for((i=500000;i;i--)); do echo "$i/1" >&3; read a <&4; done
real    0m14.391s

3) In the awk environment the bc usage is a bit slower (about 18 times) than in bash but it works this way:

# time awk ' BEGIN {
#               for(i=30000;i;i--){
#                   printf("%d/1n",i) >"/dev/fd/3";
#                   system("read a </dev/fd/4; echo $a >tmp_1");
#                   getline a <"tmp_1"; close("tmp_1");}
#                  } '
real    0m14.178s

4)What can be the problem when I try to do accordig to “man awk” ? :

# awk ' BEGIN {
#         for(i=4;i;i--){
#         printf("%d/1n",i) >"/dev/fd/3"; system("sleep .1");
#        "read a </dev/fd/4; echo $a" | getline a ;print a;}
#      } '
4.000
4.000
4.000
4.000

The above “awk” script was able to pick up only the first number from the pipe. The other three numbers remained in the pipe. These will be visible when I’m reading the pipe after the above awk script.

# for((;;)); do read a </dev/fd/4; echo $a; done
3.000
2.000
1.000

Thanks for gawk.

Advertisement

Answer

It sounds like you’re looking for gawk’s co-process ability, see http://www.gnu.org/software/gawk/manual/gawk.html#Getline_002fCoprocess. Given awks support of math functions, though, I wonder why you’d want to use bc

User contributions licensed under: CC BY-SA
1 People found this is helpful
Advertisement