Скрипт рекурсивной функции оболочки - PullRequest
2 голосов
/ 21 ноября 2011
#!/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

Если я выполню этот скрипт, он вызовет себя (рекурсивно). Почему бы не сканировать все каталоги?

(извините, мой английский плохой)

Ответы [ 2 ]

6 голосов
/ 21 ноября 2011
  1. Не вызывайте ls в обратных кавычках, когда подстановочный знак будет работать и является более надежным, то есть:

    for file in "$1"/*; do
    
  2. Расширения переменных должныбыть внутри в кавычках, или все это будет падать на любой специальный символ, включая пробел.Вы должны использовать "$1", "$2" и "$1/$file" "$2/$file".

  3. Переменные являются глобальными в оболочке по умолчанию.Таким образом, рекурсивный вызов перекрывает переменную file внешнего вызова.Существует два возможных обходных пути:

    1. Объявите переменную local с

      local file
      

      в начале функции.Это "bashishm" , то есть он не определен стандартом оболочки POSIX, поэтому у некоторых оболочек его нет.

    2. Оберните функцию в круглые скобки вместофигурные скобки.Это заставит функцию работать в подоболочке, которая не может обрезать переменные своих родителей.

  4. О, вам не нужны param1 и param2.Позиционные параметры ограничены.

  5. Уильям Пьюзель (см. Другой ответ) замечает еще одну вещь. Либо перейдите в каталог аргументов , либо добавьте его к пути, но не делайте оба.

Со всеми исправлениями, которые вы должныдоберитесь до:

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 голос
/ 21 ноября 2011

Если вы делаете:

cd $1
ls $1

вы действительно не должны ожидать никаких выходных данных, если каталог не содержит подкаталог с тем же именем. Вы имели в виду:

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