2011-11-21 134 views
2
#!/bin/sh 

param1=$1 
param2=$2 

recursive(){ 
    mkdir -p $2 
    cd $1 
    for file in `ls $1`; do 
     [ $file = "." -o $file = ".." ] && continue 
     [ -d $file ] && recursive $1"/"$file $2"/"$file 
     [ -f $file ] && ln -s $1"/"$file $2"/"$file 
    done 
} 

recursive $param1 $param2 

如果我執行這個腳本,它會調用self(遞歸)。爲什麼不掃描所有目錄?遞歸函數shell腳本

(原諒我:我的英語很差)

回答

6
  1. 不要叫ls在反引號時通配符會做的,是更可靠的,那就是:

    for file in "$1"/*; do 
    
  2. 變量擴展必須是裏面的這個引號,否則它會掉落在任何特殊字符上,包括空格。您應該使用"$1""$2""$1/$file" "$2/$file"

  3. 默認情況下,變量在shell中是全局的。因此遞歸調用會暴露外部調用的變量file。有兩種可能的解決方法:

    1. 聲明局部變量與

      local file 
      

      在函數的開始。這是「bashishm」,即它不是由POSIX shell標準定義的,所以有些shell沒有它。

    2. 將函數換成圓括號而不是大括號。這將使該函數運行在一個子shell中,它不能破壞父母的變量。

  4. 哦,你不需要param1param2。位置參數是作用域的。

  5. William Pusell(查看其他答案)注意到一件事。 要麼將​​光盤放入參數目錄將其前綴添加到路徑中,但不要同時執行這兩個操作。

與所有的補丁,你應該去:

recursive() (
    mkdir -p "$2" 
    for file in "$1"/*; do 
     [ "$file" = "." -o "$file" = ".." ] && continue 
     [ -d "$file" ] && recursive "$1/$file" "$2/$file" 
     [ -f "$file" ] && ln -s "$1/$file" "$2/$file" 
    done 
) 

recursive "$1" "$2" 

我沒有測試它,所以有可能還是留下了一些問題。

1

如果你這樣做:

 
cd $1 
ls $1 

你真的不應該期望看到任何輸出,除非目錄中,有一個同名的子目錄。你的意思是:

 
cd $1 
for file in $(ls .) ...