免费注册 查看新帖 |

Chinaunix

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

[其他] [找区别] cmd | cmd2 和 cmd > >(cmd2) 的区别 [复制链接]

论坛徽章:
84
每日论坛发贴之星
日期:2015-12-29 06:20:00每日论坛发贴之星
日期:2016-01-16 06:20:00每周论坛发贴之星
日期:2016-01-17 22:22:00程序设计版块每日发帖之星
日期:2016-01-20 06:20:00每日论坛发贴之星
日期:2016-01-20 06:20:00程序设计版块每日发帖之星
日期:2016-01-21 06:20:00每日论坛发贴之星
日期:2016-01-21 06:20:00程序设计版块每日发帖之星
日期:2016-01-23 06:20:00程序设计版块每日发帖之星
日期:2016-01-31 06:20:00数据库技术版块每日发帖之星
日期:2016-01-16 06:20:00程序设计版块每日发帖之星
日期:2016-01-16 06:20:00程序设计版块每日发帖之星
日期:2016-01-14 06:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-11-11 14:26 |只看该作者 |倒序浏览
如题:

  cmd | cmd2
  cmd > >(cmd2)

这两种写法基本功能一样的,但是主要区别在哪里呢?
我先说一个:
    cmd | cmd2  # 运行结束后 $? 是 cmd2 的返回值
    cmd > >(cmd2)  #运行结束后 $? 是 cmd 的返回值


大家看还有什么区别?

论坛徽章:
0
2 [报告]
发表于 2015-11-11 15:03 |只看该作者
本帖最后由 lgfang 于 2015-11-11 15:05 编辑

管道符是个顺序点(应该是这么叫吧。 cmd1 | cmd2 2>/dev/null 是吧cmd2的标准错误重定向。 cmd1 > >(cmd2) 2>/dev/null 重定向的是cmd1的stderr。同理,管道符可以 cmd1 | cmd2 | cmd3 ....,后者就不行了吧。

另外,管道符可以

1. cmd1 |& cmd2 把cmd1的stdout/stderr都重定向到cmd2的stdin
2. set -o pipefail 选项使得管道的返回值是管道中出错的进程的返回值(避免出现管道中的程序明明失败了但整个语句返回的是成功)
3. 管道符看起来简单明了啊。

论坛徽章:
84
每日论坛发贴之星
日期:2015-12-29 06:20:00每日论坛发贴之星
日期:2016-01-16 06:20:00每周论坛发贴之星
日期:2016-01-17 22:22:00程序设计版块每日发帖之星
日期:2016-01-20 06:20:00每日论坛发贴之星
日期:2016-01-20 06:20:00程序设计版块每日发帖之星
日期:2016-01-21 06:20:00每日论坛发贴之星
日期:2016-01-21 06:20:00程序设计版块每日发帖之星
日期:2016-01-23 06:20:00程序设计版块每日发帖之星
日期:2016-01-31 06:20:00数据库技术版块每日发帖之星
日期:2016-01-16 06:20:00程序设计版块每日发帖之星
日期:2016-01-16 06:20:00程序设计版块每日发帖之星
日期:2016-01-14 06:20:00
3 [报告]
发表于 2015-11-11 16:54 |只看该作者
回复 2# lgfang


> 另外,管道符可以

> 1. cmd1 |& cmd2 把cmd1的stdout/stderr都重定向到cmd2的stdin
cmd1 &> >(cmd2)  也可以
> 2. set -o pipefail 选项使得管道的返回值是管道中出错的进程的返回值(避免出现管道中的程序明明失败了但整个语句返回的是成功)
> 3. 管道符看起来简单明了啊。


那么 cmd1 > >(cmd2) 的主要应用场景是什么呢?哪些情况下只能用这个 而 不能用管道呢?

论坛徽章:
1
摩羯座
日期:2014-12-29 15:59:36
4 [报告]
发表于 2015-11-11 17:23 |只看该作者
前者cmd是在子shell里运行的,后者不是,这才是关键的区别

论坛徽章:
84
每日论坛发贴之星
日期:2015-12-29 06:20:00每日论坛发贴之星
日期:2016-01-16 06:20:00每周论坛发贴之星
日期:2016-01-17 22:22:00程序设计版块每日发帖之星
日期:2016-01-20 06:20:00每日论坛发贴之星
日期:2016-01-20 06:20:00程序设计版块每日发帖之星
日期:2016-01-21 06:20:00每日论坛发贴之星
日期:2016-01-21 06:20:00程序设计版块每日发帖之星
日期:2016-01-23 06:20:00程序设计版块每日发帖之星
日期:2016-01-31 06:20:00数据库技术版块每日发帖之星
日期:2016-01-16 06:20:00程序设计版块每日发帖之星
日期:2016-01-16 06:20:00程序设计版块每日发帖之星
日期:2016-01-14 06:20:00
5 [报告]
发表于 2015-11-11 17:26 |只看该作者
加一个: 产生的进程组不同:

cat | cat2   #管道线 所有进程在同一个进程组,同一个父进程 (这里默认讨论bash 其他shell不知道)
$ ps axfo tpgid,pgrp,ppid,pid,command| grep -v grep | grep cat -A 3
6130  6130 12712  6130          |   |   |   \_ cat
6130  6130 12712  6131          |   |   |   \_ cat2

cat > >(cat2)  #不再一个进程组, cat2是 cat的子/孙进程
$ ps axfo tpgid,pgrp,ppid,pid,command| grep -v grep | grep cat -A 3
6136  6136 12712  6136          |   |   |   \_ cat
6136 12712  6136  6137          |   |   |       \_ bash
6136 12712  6137  6138          |   |   |           \_ cat2

论坛徽章:
84
每日论坛发贴之星
日期:2015-12-29 06:20:00每日论坛发贴之星
日期:2016-01-16 06:20:00每周论坛发贴之星
日期:2016-01-17 22:22:00程序设计版块每日发帖之星
日期:2016-01-20 06:20:00每日论坛发贴之星
日期:2016-01-20 06:20:00程序设计版块每日发帖之星
日期:2016-01-21 06:20:00每日论坛发贴之星
日期:2016-01-21 06:20:00程序设计版块每日发帖之星
日期:2016-01-23 06:20:00程序设计版块每日发帖之星
日期:2016-01-31 06:20:00数据库技术版块每日发帖之星
日期:2016-01-16 06:20:00程序设计版块每日发帖之星
日期:2016-01-16 06:20:00程序设计版块每日发帖之星
日期:2016-01-14 06:20:00
6 [报告]
发表于 2015-11-11 17:53 |只看该作者
本帖最后由 yjh777 于 2015-11-11 17:55 编辑
ziyunfei 发表于 2015-11-11 17:23
前者cmd是在子shell里运行的,后者不是,这才是关键的区别


可不可以说的更清楚一些,后者不在子shell里运行的话,是在哪里运行?有什么方法查看?

    (我是参照APUE里 stevens 大爷的方法 拷贝一个cat2 这样很方便查看进程之间的关系 见5楼)

论坛徽章:
0
7 [报告]
发表于 2015-11-12 09:05 |只看该作者
回复 4# ziyunfei




   

论坛徽章:
0
8 [报告]
发表于 2015-11-12 09:05 |只看该作者
回复 3# yjh777

对。我忘了

论坛徽章:
60
20周年集字徽章-20	
日期:2020-10-28 14:04:3015-16赛季CBA联赛之北京
日期:2016-07-06 15:42:0715-16赛季CBA联赛之同曦
日期:2016-06-12 10:38:0915-16赛季CBA联赛之佛山
日期:2016-05-27 11:54:56黄金圣斗士
日期:2015-12-02 11:44:35白银圣斗士
日期:2015-11-25 14:32:43白银圣斗士
日期:2015-11-23 12:53:352015亚冠之布里斯班狮吼
日期:2015-10-21 16:55:482015亚冠之首尔
日期:2015-09-01 16:46:052015亚冠之德黑兰石油
日期:2015-08-31 11:39:192015亚冠之萨济拖拉机
日期:2015-08-28 21:06:5315-16赛季CBA联赛之广东
日期:2016-07-12 14:58:53
9 [报告]
发表于 2015-11-12 09:49 |只看该作者
第二种不好理解啊感觉, 用管子挺好的啊

cmd | cmd2, 这种也可以获取cmd的状态啊, 不是有一个 PIPESTATUS 数组嘛, 保存了每个管道命令的状态啊.  

echo {PIPESTATUS[0]} 就是cmd 的返回状态码, echo {PIPESTATUS[1]} 就是cmd2的返回状态码咯

cmd1 > >(cmd2) 这种没见过, 都没用过 解释下这命令咋回事啊.  

>() 生成一个文件描述符, 然后cmd1的输出重定向到那个文件描述符,然后那个文件描述符作为cmd2的标准输入么? 丢, 好绕.

论坛徽章:
84
每日论坛发贴之星
日期:2015-12-29 06:20:00每日论坛发贴之星
日期:2016-01-16 06:20:00每周论坛发贴之星
日期:2016-01-17 22:22:00程序设计版块每日发帖之星
日期:2016-01-20 06:20:00每日论坛发贴之星
日期:2016-01-20 06:20:00程序设计版块每日发帖之星
日期:2016-01-21 06:20:00每日论坛发贴之星
日期:2016-01-21 06:20:00程序设计版块每日发帖之星
日期:2016-01-23 06:20:00程序设计版块每日发帖之星
日期:2016-01-31 06:20:00数据库技术版块每日发帖之星
日期:2016-01-16 06:20:00程序设计版块每日发帖之星
日期:2016-01-16 06:20:00程序设计版块每日发帖之星
日期:2016-01-14 06:20:00
10 [报告]
发表于 2015-11-12 10:29 |只看该作者
reyleon 发表于 2015-11-12 09:49
第二种不好理解啊感觉, 用管子挺好的啊

cmd | cmd2, 这种也可以获取cmd的状态啊, 不是有一个 PIPESTATUS ...

...
>() 生成一个文件描述符, 然后cmd1的输出重定向到那个文件描述符,然后那个文件描述符作为cmd2的标准输入么? 丢, 好绕.


是的就是这样的 直接就猜出来了 厉害,直接 echo >(sleep 1) 就能看出来 ;其实就是:
cmd > /dev/fd/63  然后在林一个进程组里  cmd2 < /dev/fd/63  
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP