2013-04-01 63 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