在 awk 的 BASH shell 中使用 bc 作为守护进程
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/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
谢谢
拉齐
续:
我做了一些进一步的实验并总结了我的结果。
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" 做 accordig 时会出现什么问题? :
# 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
感谢您的关注。
尝试:
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
听起来你在寻找gawk的协同处理能力,见http://www.gnu.org/software/gawk/manual/gawk.html#Getline_002fCoprocess。不过,鉴于 awks 对数学函数的支持,我想知道您为什么要使用 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
谢谢 拉齐
续:
我做了一些进一步的实验并总结了我的结果。 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" 做 accordig 时会出现什么问题? :
# 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
感谢您的关注。
尝试:
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
听起来你在寻找gawk的协同处理能力,见http://www.gnu.org/software/gawk/manual/gawk.html#Getline_002fCoprocess。不过,鉴于 awks 对数学函数的支持,我想知道您为什么要使用 bc
...