在awk的BASH shell中使用bc作为守护进程

时间:2015-02-18 21:42:55

标签: linux bash awk fifo bc

# 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/5\n") >"/dev/fd/3"; exit 1;} '
# read a <&4; echo $a
.800
#
# awk ' BEGIN { printf("4/5\n") >"/dev/fd/3"; exit 1;} '
# awk ' BEGIN { getline a <"/dev/fd/4"; printf("%s\n", a); } '
^C

在BASH环境中,我可以使用fifo与bc程序通信。 但是在awk中我可以写但没有使用getline函数读取。 如何在awk中读取“/ dev / fd / 4”。

我的awk版本是:mawk 1.3.3 1996年11月,版权所有(C)Michael D. Brennan

由于 LACI

(续):

我做了一些进一步的实验,并总结了我的结果。 Awk脚本语言最适合我的任务, 我需要使用“bc”,因为我必须计算很长的数字(大约100位)。 接下来的两个脚本显示使用命名管道比未命名管道快(大约83次)。

1)使用未命名的管道:

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

2)使用命名管道:

# 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)在awk环境中,bc的使用比bash慢一点(约18倍),但它的工作原理如下:

# time awk ' BEGIN {
#               for(i=30000;i;i--){
#                   printf("%d/1\n",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)当我尝试对“man awk”做出回应时会出现什么问题? :

# awk ' BEGIN {
#         for(i=4;i;i--){
#         printf("%d/1\n",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

上面的“awk”脚本只能从管道中获取第一个数字。 其他三个数字仍留在管道中。 当我在上面的awk脚本之后读取管道时,这些将是可见的。

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

感谢gawk。

2 个答案:

答案 0 :(得分:2)

听起来你正在寻找gawk的协同处理能力,请参阅http://www.gnu.org/software/gawk/manual/gawk.html#Getline_002fCoprocess。但是,如果awks支持数学函数,我想知道你为什么要使用bc ...

答案 1 :(得分:0)

尝试:

mkfifo inp out
bc -l  <inp  >out  &
awk ' BEGIN { printf("4/5\n"); exit 0;} ' > inp
read a < out; echo $a

awk ' BEGIN { printf("4/5\n"); exit 0;} ' > inp

awk ' BEGIN { getline a; printf("%s\n", a); exit 0 } ' < out

rm inp 
rm out