2013-05-29 128 views
4

我學習Linux的命令,我練習,嘗試寫一個基本的shell腳本,列出子文件夾中的所有文件和文件,如ls *,使用遞歸。遞歸在shell腳本

#!/bin/bash 

# list-all: one command to list them all!!!! 

listit() { 
     if [ -d "$1" ] 
     then 
       listit "$1" 
     else 
       echo "$1" 
     fi 
} 

ls | while read items; do 
     listit "$items" 
done 

然而,結果表明:

./list-all: line 16: 1101 Done     ls 
     1102 Segmentation fault: 11 | while read items; do 
    listit "$items"; 
done 

是因爲外殼不允許遞歸?請幫忙,謝謝!

+1

+1到你的學習工作。你是否知道'ls -R'或'find。鍵入-f'? –

+0

@glennjackman,謝謝!我只是意識到你可以使用這些命令。雖然對於第二個,我認爲它應該是「找到」。型F' – Yoland

+0

事實上,由於爲察覺錯字 –

回答

2

外殼當然支持遞歸。但是你的函數需要參數,並且你傳遞它的stdin。除此之外,你真的不應該是parsing the output of ls。試想一下:

listit() { 
    while [ "$1" ]; do 
     if [ -d "$1" ]; then 
      listit "$1"/* 
     else 
      printf '%s\n' "$1" 
     fi 
     shift 
    done 
} 

listit * 

如果你真的要標準輸入讀取,你不得不重寫listit做到這一點。這是棘手的,因爲你只能得到一個標準輸入,並且每次遞歸調用會試圖擁有它。文件名是一個簡單的東西,可以通過globbing訪問,所以我會堅持這一點。

+0

感謝您對本! – Yoland

+0

+1'listit .'也可以。 –

2

你有無限遞歸堆棧溢出。考慮撥打listit /

第一if會看到/是一個目錄,所以它會調用listit /然後將調用listit / ...

this answer for what happens next

+0

括號對於shell中函數應用程序的語法不正確。 '-bash:語法錯誤附近的意外令牌'/'' – kojiro

+0

@kojiro正確的你,修復,謝謝。 – msw