Chinaunix

标题: Shell 经典问题之 [ I/O 重定向] [4] [打印本页]

作者: lightspeed    时间: 2004-11-25 12:43
标题: Shell 经典问题之 [ I/O 重定向] [4]
[Q] 对于命令 cmd1, cmd2, cmd3, cmd4. 如何利用单向管道完成下列功能:

1.  所有命令并行执行
2.  cmd1 和 cmd2  不需要 stdin
3.  cmd1 和 cmd2 的 stdout 定向到 cmd3 的 stdin
4.  cmd1 和 cmd2 的 stderr 定向到 cmd4 的 stdin
5.  cmd3  的 stdout 定向到文件 a,  stderr 定向到屏幕
6.  cmd4  的 stdout 定向到文件 b,  stderr 定向到屏幕
7.  cmd1 的返回码赋给变量 s
8.  不能利用临时文件
作者: whtlly    时间: 2004-11-25 23:16
标题: Shell 经典问题之 [ I/O 重定向] [4]
等待解答
作者: 寂寞烈火    时间: 2004-11-26 01:16
标题: Shell 经典问题之 [ I/O 重定向] [4]
不知道我的理解是否正确 ?
1,这样是否算?
bash:
  1. echo abc|tee >(tr a-z A-Z) >(tr a-z 0-9)|rev
复制代码

ksh:

  1. #!/bin/ksh
  2. #this is my exercise about co-process
  3. bc -l|&
  4. echo -n "please input two number:"
  5. read a b
  6. print -p "$a*$b"|print -p "scale=2;$a/$b"|print -p "$a+$b"|print -p "$a-$b"
  7. read -p c;read -p d;read -p e;read -p f
  8. echo "$a*$b=$c\n$a/$b=$d\n$a+$b=$e\n$a-$b=$f"
复制代码

大家继续 ...
作者: lightspeed    时间: 2004-11-26 01:59
标题: Shell 经典问题之 [ I/O 重定向] [4]
原帖由 "寂寞烈火"]echo abc|tee >(tr a-z A-Z) >(tr a-z 0-9)|rev[/quote 发表:


烈火兄, 如果

cmd1: echo abc
cmd2: (tr a-z A-Z)
cmd3: (tr a-z 0-9)
cmd4: rev

这个不满足条件 4, 5, 6, 7

[quote]原帖由 "寂寞烈火" 发表:
#!/bin/ksh
#this is my exercise about co-process
bc -l|&
echo -n "please input two number:"
read a b
print -p "$a*$b"|print -p "scale=2;$a/$b"|print -p "$a+$b"|print -p "$a-$b"
read -p c;read -p d;read -p e;read -p f
echo "$a*$b=$c\n$a/$b=$d\n$a+$b=$e\n$a-$b=$f"


这个也不满足条件 4, 5, 6, 7.
原文要求单向 pipe.  当然写出有  coprocess 的版本也可。不过比原题略易。
作者: 寂寞烈火    时间: 2004-11-26 02:46
标题: Shell 经典问题之 [ I/O 重定向] [4]
原帖由 "lightspeed" 发表:


这个也不满足条件 4, 5, 6, 7.
原文要求单向 pipe.  当然写出有  coprocess 的版本也可。不过比原题略易。

哪找这样的4个命令呢?  
还望指教  
作者: lightspeed    时间: 2004-11-26 03:12
标题: Shell 经典问题之 [ I/O 重定向] [4]
原帖由 "寂寞烈火" 发表:

哪找这样的4个命令呢?  
还望指教  


此题只是测试对重定向的理解。 不用将 cmd1 .. 具体化。

可以这样想像:  cmd1, cmd2 实际上是同一个处理数据的程序,但单进程
运算速度太慢, 因此并行计算。每一个计算一半数据。
cmd3 处理他们的输出。 cmd4 处理他们的出错。
作者: 寂寞烈火    时间: 2004-11-26 12:46
标题: Shell 经典问题之 [ I/O 重定向] [4]
是不是需要先mkpipe???
作者: lightspeed    时间: 2004-11-26 12:57
标题: Shell 经典问题之 [ I/O 重定向] [4]
[quote]原帖由 "寂寞烈火"]是不是需要先mkpipe???[/quote 发表:


本题用普通 pipe。  如果 mkpipe 就变简单了, 而且不满足条件1 -  同时执行。

比如这种形式:

cmd1 | cmd2 |cmd3|cmd4

在加上各种重定向以满足条件 1 - 8。
作者: 寂寞烈火    时间: 2004-11-26 13:23
标题: Shell 经典问题之 [ I/O 重定向] [4]
lightspeed兄还是系统把题给详细的讲解一下,如何? 谢谢!
作者: lightspeed    时间: 2004-11-26 22:07
标题: Shell 经典问题之 [ I/O 重定向] [4]
Answer Key:



  1. exec 3>&1; exec 4>&1
  2. s=$(((((cmd1 1>&3 3>&- 4>&-; echo $? >&4 3>&- 4>&-)| cmd2 3>&- 4>&-) 3>&1 | cmd3 >a 2>&3 3>&- 4>&- ) 2>&1 | cmd4 >b 3>&- 4>&-) 4>&1)
  3. exec 3>&-; exec 4>&-

复制代码


以上是全版本,也可以去掉一部分内容(哪些内容?)而不影响结果, 不过
显得不太完美。
作者: lightspeed    时间: 2004-11-26 22:30
标题: Shell 经典问题之 [ I/O 重定向] [4]
发完本帖,将执行下列语句:

exec  Shell 经典问题之 [ I/O 重定向]  >&-

本坛求道者寥寥, 信哉。
作者: 寂寞烈火    时间: 2004-11-27 00:30
标题: Shell 经典问题之 [ I/O 重定向] [4]
原帖由 "lightspeed" 发表:

以上是全版本,也可以去掉一部分内容(哪些内容?)而不影响结果, 不过
显得不太完美。

看的我已经晕菜啦  
确实经典之极!   
作者: lightspeed    时间: 2004-11-27 02:45
标题: Shell 经典问题之 [ I/O 重定向] [4]
这里是精简版本, 更容易理解。

  1. exec 3>&1; exec 4>&1
  2. s=$(((((cmd1 1>&3 ; echo $? >&4 )| cmd2 ) 3>&1 | cmd3 >a 2>&3 ) 2>&1 | cmd4 >b ) 4>&1)
  3. exec 3>&-; exec 4>&-   
复制代码


下面是测试, 看看各个 cmd 的 stdout 和 stderr 都去了那里

  1. #!/bin/ksh
  2. alias cmd1='(echo cmd1out; echo cmd1err >&2)'
  3. alias cmd2='(echo cmd2out; echo cmd2err >&2)'
  4. alias cmd3='(cat; echo cmd3out; echo cmd3err >&2)'
  5. alias cmd4='(cat; echo cmd4out; echo cmd4err >&2)'
  6. exec 3>&1; exec 4>&1
  7. s=$(((((cmd1 1>&3 ; echo $? >&4 )| cmd2 ) 3>&1 | cmd3 >a 2>&3 ) 2>&1 | cmd4 >b ) 4>&1)
  8. exec 3>&-; exec 4>&-
  9. echo "s=$s"
  10. echo
  11. echo "Data in file a ::"
  12. cat a
  13. echo
  14. echo "Data in file b ::"
  15. cat b               
复制代码

作者: 寂寞烈火    时间: 2004-11-27 13:01
标题: Shell 经典问题之 [ I/O 重定向] [4]
/home/lee/myfile#ksh -x testio.sh
+ alias cmd1=(echo cmd1out; echo cmd1err >&2)
+ alias cmd2=(echo cmd2out; echo cmd2err >&2)
+ alias cmd3=(cat; echo cmd3out; echo cmd3err >&2)
+ alias cmd4=(cat; echo cmd4out; echo cmd4err >&2)
+ exec
+ 3>&1
+ exec
+ 4>&1
+ let ((cmd1 1>&3 ; echo 0 >&4 )| cmd2 ) 3>&1 | cmd3 >a 2>&3 ) 2>&1 | cmd4 >b ) 4>&1
testio.sh[7]: ((cmd1 1>&3 ; echo 0 >&4 )| cmd2 ) 3>&1 | cmd3 >a 2>&3 ) 2>&1 | cmd4 >b ) 4>&1: missing )
+ s=
+ exec
+ 3>&-
+ exec
+ 4>&-
+ echo s=
s=
+ echo

+ echo Data in file a ::
Data in file a ::
+ cat a
cat: a: 没有那个文件或目录
+ echo

+ echo Data in file b ::
Data in file b ::
+ cat b
cat: b: 没有那个文件或目录

作者: lightspeed    时间: 2004-11-28 04:35
标题: Shell 经典问题之 [ I/O 重定向] [4]
原帖由 "寂寞烈火" 发表:
+ let ((cmd1 1>&3 ; echo 0 >&4 )| cmd2 ) 3>&1 | cmd3 >a 2>&3 ) 2>&1 | cmd4 >b ) 4>&1
testio.sh[7]: ((cmd1 1>&3 ; echo 0 >&4 )| cmd2 ) 3>&1 | cmd3 >a 2>&3 ) 2>&1 | cmd4 >b ) 4>&1: missing )


你用的是 pdksh, 相当于 ksh88. 明显对多层嵌套支持不够, 把此句解释为
算术操作了, 它希望在尾端找到 )),  所以报语法错。

下面是 ksh93  及 zsh (version 4.2.0) 的结果:

# test.sh
cmd3err
cmd4err
s=0

Data in file a ::
cmd2out
cmd1out
cmd3out

Data in file b ::
cmd2err
cmd1err
cmd4out         

bash 2.05 对上例中的 alias 语句解释不对, 可改成 function.
则  ksh93, zsh 4.x.x,  bash 2.05b  都得到以上结果:

  1. #!/bin/bash
  2. cmd1 () {
  3. echo cmd1out; echo cmd1err >&2
  4. }
  5. cmd2 () {
  6. echo cmd2out; echo cmd2err >&2
  7. }
  8. cmd3 () {
  9. cat; echo cmd3out; echo cmd3err >&2
  10. }
  11. cmd4 () {
  12. cat; echo cmd4out; echo cmd4err >&2
  13. }
  14. exec 3>&1; exec 4>&1
  15. s=$(((((cmd1 1>&3 ; echo $? >&4 )| cmd2 ) 3>&1 | cmd3 >a 2>&3 ) 2>&1 | cmd4 >b ) 4>&1)
  16. exec 3>&-; exec 4>&-
  17. echo "s=$s"
  18. echo
  19. echo "Data in file a ::"
  20. cat a
  21. echo
  22. echo "Data in file b ::"
  23. cat b
复制代码

作者: 寂寞烈火    时间: 2004-11-28 12:46
标题: Shell 经典问题之 [ I/O 重定向] [4]
[quote]原帖由 "lightspeed"][/quote 发表:

原来如此,谢谢指教
P.S:放入收藏夹
作者: wingger    时间: 2004-11-28 15:09
标题: Shell 经典问题之 [ I/O 重定向] [4]
咔咔,看了几位的回复!

俺是革命尚未成功,同志仍须努力     
作者: 網中人    时间: 2004-11-28 20:17
标题: Shell 经典问题之 [ I/O 重定向] [4]
[quote]原帖由 "lightspeed"]ㄏ
作者: lightspeed    时间: 2004-11-29 00:16
标题: Shell 经典问题之 [ I/O 重定向] [4]
原帖由 "網中人" 发表:

哈...
陽春白雪, 曲高和寡.
兄又何必在意呢?


Don't worry about it.

这里有引申出另外一个问题, 就是在嵌套的 subshell 中, ((...)) 会解释为
算术操作, 为避免非算术操作语句的错误解释, 可在适当的地方加 ; .  如:

(echo aaa)  # right
((echo aaa))  # wrong
((echo aaa); )  # right
((echo aaa); (echo bbb))  # right
(((echo aaa)) ; (echo bbb))  # wrong
(((echo aaa); ) ; (echo bbb))  # right
(((echo ((1+2)))) ; (echo bbb))  #  wrong
(((echo $((1+2)))); (echo bbb))  #  wrong
(((echo $((1+2))); ); (echo bbb))  #  right
(((echo $((1+2)); ); ); (echo bbb))  #  right
作者: hawkli    时间: 2004-11-30 02:23
标题: Shell 经典问题之 [ I/O 重定向] [4]
看到此贴已经是子夜时分,shell版上寂寞烈火还是在线,果然是求道中人,我等愚民不可及之高。
窃以为自己还只是求知,未到求道之境,lightspeed所问对我而言确如似是而非,似懂非懂之间,无奈红尘缠身,罢了罢了。
作者: 寂寞烈火    时间: 2004-11-30 02:33
标题: Shell 经典问题之 [ I/O 重定向] [4]
无奈水平和理解能力有限 还得多向高手学习!

107780412641a4535d36401.gif (6.97 KB, 下载次数: 64)

107780412641a4535d36401.gif

107780412641a4535d3640111111111.gif (7.01 KB, 下载次数: 50)

107780412641a4535d3640111111111.gif

作者: lightspeed    时间: 2004-11-30 02:42
标题: Shell 经典问题之 [ I/O 重定向] [4]
哈,一句玩笑话,认真不得。

hawkli 已经叫我头晕了,烈火兄还要转上两把.............
作者: 寂寞烈火    时间: 2004-11-30 02:45
标题: Shell 经典问题之 [ I/O 重定向] [4]
原帖由 "lightspeed" 发表:
哈,一句玩笑话,认真不得。

hawkli 已经叫我头晕了,烈火兄还要转上两把.............

哈哈~~~,我看呀,还是结贴吧~~ 有问题的话再另起新贴比较好!    
再转两把

作者: benben_945    时间: 2004-12-10 14:57
标题: Shell 经典问题之 [ I/O 重定向] [4]
我怎么看不懂你们在说什么呀??????晕````````````           
作者: shaoping0330    时间: 2004-12-10 16:11
标题: Shell 经典问题之 [ I/O 重定向] [4]
真是要有悟性啊!

不管何种求道-都要有悟性的!

得道者寥寥!
作者: babyyellow    时间: 2004-12-11 13:30
标题: Shell 经典问题之 [ I/O 重定向] [4]
高手就是高。我的aix r650 如下
cmd4err
cmd3err
s=0

Data in file a ::
cmd2out
cmd1out
cmd3out

Data in file b ::
cmd2err
cmd1err
cmd4out
作者: loufangxin    时间: 2004-12-11 14:47
标题: Shell 经典问题之 [ I/O 重定向] [4]
这种代码,不容易读,可以研究,不主张推扩。
作者: archangle    时间: 2004-12-12 11:49
标题: Shell 经典问题之 [ I/O 重定向] [4]
不知有具体的运用例子没
作者: 李某人    时间: 2004-12-12 16:56
标题: Shell 经典问题之 [ I/O 重定向] [4]
吾乃凡人...
自以為這樣的貼子對我一點用處都沒有!
不是存心和各前輩過不去,是心里話
見諒!
作者: txyxue    时间: 2005-06-29 15:35
标题: Shell 经典问题之 [ I/O 重定向] [4]
有些晕,不知连环镶套的括号如何继承环境,还能解释一下!




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2