2013-04-01 35 views
4

的功能(输出功率设定给定输入的)背后bash的功率设定功能

p() { [ $# -eq 0 ] && echo || (shift; p "[email protected]") | 
     while read r ; do echo -e "$1 $r\n$r"; done } 

测试输入逻辑

p $(echo -e "1 2 3") 

测试输出

1 2 3 
2 3 
1 3 
3 
1 2 
2 
1 

我有困难在下面的代码中掌握递归。我试图通过把一些变量的代码来表示递归和执行顺序的水平内去理解它,但我仍然感到困惑。

这里有事情,我可以这么远告诉:

  1. 子shell的输出将不会显示在最终输出,它就会通过管道重定向到读命令
  2. echo命令追加新所有输出

执行我看到的顺序行:

  1. P(1 2 3) - > 1,接着下面输出的所有组合\ n 下面
  2. P(2 3)输出的所有组合 - > 2 3 \ N3 \ n
  3. P(3) - > 3
  4. p() - >

所以我觉得我应该有p(2)而不是p(3)执行#3,但如何发生的呢?由于shift只朝着一个方向。

如果我是用“P(1 2 3 4)”作为输入,它是示出了“1 2 3”,在混淆我输出的部分。

+1

'$(回声-e “1 \ N2 \ N3”)'相当于'1 2 3'。也许只遵循'p 1 2 3'会更简单? –

+0

我适时改变我的问题。这当然可以提高可读性。 – Forethinker

回答

3

echo命令使用的-e在我看来,纯粹的混淆,因为它可能已被写入:

p() { [ $# -eq 0 ] && echo || (shift; p "[email protected]") | 
     while read r ; do 
     echo $1 $r 
     echo $r 
     done 
    } 

换句话说,“为每一套在发电机组所有,但第一个参数(shift; p "[email protected]"),输出既该集合具有和不具有第一个参数“。

bash函数的工作原理是设置一个subhells链,每个从下一个链读取,像这样,每个box都是一个subshel​​l,并且在它下面,当它读取每行的输入:(我用的""做 “无中生有” 可见=>的意思是 “呼”; <-指 “读”。)

+---------+  +-------+  +-------+  +-------+ 
| p 1 2 3 | ==> | p 2 3 | ==> | p 3 | ==> | p | 
+---------+  +-------+  +-------+  +-------+ 
    1 2 3 "" <--+-- 2 3 "" <---+-- 3 "" <-----+-- "" 
    2 3 "" <-/   /   /
    1 3 "" <--+-- 3 "" <-/   /
    3 ""  <-/       /
    1 2 "" <--+-- 2 "" <---+-- "" <-/ 
    2 ""  <-/   /
    1 ""  <--+-- ""  <-/ 
    ""  <-/ 
+0

我认为这确实解决了,我是问部分。 – Forethinker

+0

@Prometheus:也许你的意思,你不觉得吗?如果是这样,请记住每个子shell都有自己的stdin和自己的参数列表,并且|创建一个子shell。 – rici

+0

我想我理解你的文章,也知道你刚刚在评论中写了什么。 (我的理解#2)。只是当我在我的问题中得到执行的上述部分时,我无法关注脚本在树中的执行位置以及脚本如何到达那里。即与前一个执行分支相比,参数的最后一个元素被排除在计算之外的部分。 – Forethinker