注:此文涉及实际项目源码截图,查看时可不关注处理逻辑!
根据测试与实际的使用过程中发现:BASH中管道内都为子进程,而KSH中最后一个管道为父进程其他为子进程!(简单的测试过程放在最后)。
因此KSH与BASH转换时,在使用管道的地方,有以下几种情况时,需要注意:(一) 管道+read的方式:主进程读取不了值
例如:
![](https://i-blog.csdnimg.cn/blog_migrate/758e3c7a74092e119d2fee0b7741b498.png)
建议修改:
1. 这里可以读取多个值(推荐这种方式修改):
![](https://i-blog.csdnimg.cn/blog_migrate/642ab1398a4df10d157495e3e7212e55.png)
2. 这里只可以读取一个值:
例如:
1. 通过”()”强制将输出数据语句与管道最后一个保持在一个进程内
![](https://i-blog.csdnimg.cn/blog_migrate/333c54cf3c36fabb7ab7cf0548095128.png)
2. 通过<<<这个进行处理
修改为:
While read test1 test2
Do
Done<<<”`cat *.txt`”
(三) Cat 文件+while read:需要读取while read中的值;读取不了管道中的值
例如:
Cat file.txt|while read
Do
文件操作
Done
取文件操作中的值(可能为文件计算总和)
建议方式:
while read
Do
文件操作
Done< file.txt
取文件操作中的值(可能为文件计算总和)
#####这里不使用管道就避免了这种情况!
(四) 管道+while:需要从while中退出脚本;退出管道后,脚本继续运行
例如:
建议修改:
a. 子进程输出返回信息,主进程判断管道最后的退出状态!(也可以管道返回状态码,主进程判断)
(五) 管道+while &+wait;不会等待;
例如:
echo |..|while read file
do
(
……
)
done
wait
这种写法本身也是有点错误,因为我们的本意是等待while中的&,那么wait就应该和它待在一起,而由于bash中的最后管道为子进程,因此,才造成了bash与ksh不同;
建议修改:
echo |..|(while read file
do
(
……
)
done
wait)
使用()将其强制放到一个进程中。
(六) 测试证明过程
![](https://i-blog.csdnimg.cn/blog_migrate/dd437628506ac3935256fd952b565e8c.png)
这里只是进行了简单的测试进行证明,如需要详细了解,可以通过观察进程号等信息,或者查询官方手册。我目前看到网上有这方面问题的指出,但都不太全面;因此把项目过程中遇到的问题在这里总结一下。