免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 5322 | 回复: 4
打印 上一主题 下一主题

[日期时间] 请教一个关于管道的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-12-27 15:32 |只看该作者 |倒序浏览
  1 #!/bin/bash
  2
  3 while true
  4 do
  5
  6     echo -e "Time: $SECONDS\n"
  7
  8     { echo '1'; sleep 5; echo '3'; } | { cat; echo '2'; sleep 1; } # 有cat执行6s 无cat 5s;
  9
10     echo -e "Time: $SECONDS\n"
11 done

大神 我想请教 有cat; 这个{ echo '1'; sleep 5; echo '3'; } | { cat; echo '2'; sleep 1; } 执行时间为6s  无cat则为5s  
很困惑 求大神指点

论坛徽章:
93
2015年辞旧岁徽章
日期:2019-10-10 10:51:15CU大牛徽章
日期:2014-02-21 14:21:56CU十二周年纪念徽章
日期:2020-10-15 16:55:55CU大牛徽章
日期:2014-02-21 14:22:07羊年新春福章
日期:2019-10-10 10:51:39CU大牛徽章
日期:2019-10-10 10:55:38季节之章:春
日期:2020-10-15 16:57:40ChinaUnix元老
日期:2019-10-10 10:54:42季节之章:冬
日期:2019-10-10 10:57:17CU大牛徽章
日期:2014-02-21 14:22:52CU大牛徽章
日期:2014-03-13 10:40:30CU大牛徽章
日期:2014-02-21 14:23:15
2 [报告]
发表于 2013-12-27 18:00 |只看该作者
没找到相关的资料,推测管道两边的进程如果没有依赖的话,它们会并行运行,比如没有 cat 的话,后面的管道就不需要等待前面的输出,所以它们可以完全并行地运行,从而这时候运行时间是两边进程更长的那个时间。如果有 cat 的话,后面的管道要等待前面的进程结束,所以它就要串行运行了。
通过更改你那个命令前后的sleep时间测试像是这么回事。

然后再试试把cat放到末尾的效果,则 cat前面的内容也会并行,从而最终的时间也是两者较长的一个。看起来和上述推测吻合:
  1. echo -e "Time: $SECONDS\n";  { echo '1'; sleep 2; echo '3'; } | { echo "a"; sleep 3; cat; };  echo -e "Time: $SECONDS
复制代码
下班了没心思查找资料,回头有大牛分享学习学习。

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
3 [报告]
发表于 2013-12-27 21:59 |只看该作者
回复 1# allen08pm


    cat 接受管道前的标准输出之后,才执行后面的echo和sleep。
   如果管道前的{}后面加上 1>&2 或 >/dev/null 或任何改变其输出方式的操作,管道后加不加cat,最终时间差都是一样的

论坛徽章:
0
4 [报告]
发表于 2013-12-28 19:53 |只看该作者
The process will block on the read end (i.e. cat) since someone has the write side open.
  1.       1794  -bash
  2.         3842  /bin/bash ./test.sh  --------------> Main shell script
  3.           3880  /bin/bash ./test.sh ------> Left side of the pipe (write end) in subshell
  4.             3881  sleep 5
  5.           3882  /bin/bash ./test.sh ------> Right side of the pipe (read end) in subshell
  6.             3883  cat
复制代码
If the stdout is closed, the 'cat' is returned immediately instead of waiting.
But of course, as we have already closed stdout, "echo 3" will fail.
  1. { echo '1'; exec 1>&-; sleep 5; echo '3'; } | { cat; echo '2'; sleep 1; }

  2. root@server:~$ ./test.sh
  3. Time: 0

  4. 1
  5. 2
  6. ./test.sh: line 6: echo: write error: Bad file number
  7. Time: 5
复制代码
To make "echo 3" to print output, one way is to save the stdout first and then restore it later.
(There may be better ways to do it.)
  1. exec 3>&1
  2. { echo '1'; exec 1>&-; sleep 5; exec 1>&3 3>&-; echo '3'; } | { cat; echo '2'; sleep 1; }
  3. exec 3>&-

  4. root@server:~$ ./test.sh
  5. Time: 0

  6. 1
  7. 2
  8. 3
  9. Time: 5
复制代码

论坛徽章:
0
5 [报告]
发表于 2013-12-30 10:38 |只看该作者
回复 4# icyfish28
谢谢 简洁明了 明白了

   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP