странное поведение при использовании рекурсии в ksh93 - PullRequest
3 голосов
/ 30 ноября 2009

Я сталкиваюсь с некоторыми проблемами в ksh93 при рекурсивном просмотре каталогов.

создайте несколько файлов и каталогов.

base=/tmp/nonsens

for i in {1..3}
do
    mkdir -p ${base}/dir${i}
    for j in {1..2}
    do
        mkdir ${base}/dir${i}/dir${j}
        touch ${base}/dir${i}/dir${j}/file${j}
        touch ${base}/dir${i}/file${j}
    done
done

Теперь пройдемся по сценарию ksh93.

rdir ()
{
    typeset dir=$1

    for file in `ls $dir`
    do
        if [ -d $dir/$file ]
        then
            echo "Directory: $dir/$file"
            rdir $dir/$file
        else
            echo "File     : $dir/$file"
        fi
    done
}   

rdir /tmp/nonsens

создаст этот вывод в ksh93

cheko@chwiclu1:~> rdir /tmp/nonsens
Directory: /tmp/nonsens/dir1
Directory: /tmp/nonsens/dir1/dir1
File     : /tmp/nonsens/dir1/dir1/file1
File     : /tmp/nonsens/dir1/dir1/dir2
File     : /tmp/nonsens/dir1/dir1/file1
File     : /tmp/nonsens/dir1/dir1/file2
File     : /tmp/nonsens/dir1/dir1/dir2
File     : /tmp/nonsens/dir1/dir1/dir3

при использовании pdksh / bash создаст это

cheko@redcube:~$ rdir /tmp/nonsens
Directory: /tmp/nonsens/dir1
Directory: /tmp/nonsens/dir1/dir1
File     : /tmp/nonsens/dir1/dir1/file1
Directory: /tmp/nonsens/dir1/dir2
File     : /tmp/nonsens/dir1/dir2/file2
File     : /tmp/nonsens/dir1/file1
File     : /tmp/nonsens/dir1/file2
Directory: /tmp/nonsens/dir2
Directory: /tmp/nonsens/dir2/dir1
File     : /tmp/nonsens/dir2/dir1/file1
Directory: /tmp/nonsens/dir2/dir2
File     : /tmp/nonsens/dir2/dir2/file2
File     : /tmp/nonsens/dir2/file1
File     : /tmp/nonsens/dir2/file2
Directory: /tmp/nonsens/dir3
Directory: /tmp/nonsens/dir3/dir1
File     : /tmp/nonsens/dir3/dir1/file1
Directory: /tmp/nonsens/dir3/dir2
File     : /tmp/nonsens/dir3/dir2/file2
File     : /tmp/nonsens/dir3/file1
File     : /tmp/nonsens/dir3/file2

Кто-нибудь знает обходной путь? Или существует переключатель, который заставляет ksh93 вести себя как следует?

Ответы [ 2 ]

3 голосов
/ 01 декабря 2009

Я следовал за мыслью об этом - и имел правильную идею, но неправильную причину. pdksh следует семантике ksh88, и быстрый Google показывает, что существуют различия между ksh88 и ksh93 при определении функций.

В этом разделе часто задаваемых вопросов для ksh93 говорится в части III (сценарии оболочки):

Q18. В чем разница между именем функции и именем ()?

A18. В кш88 они были одинаковыми. Тем не менее, стандарт POSIX выбрать foo () для функций и определенной системы V Release 2 семантика для них, чтобы нет локальных переменных и так что ловушки не ограничены. ksh93 сохраняет семантику ksh88 для функции, определенные как имя функции, и изменил семантику имени () чтобы соответствовать семантике POSIX. Очевидно, что Имя функции более полезно.

У меня нет доступа к оболочке ksh93, чтобы проверить это, но подразумевается, что когда вы вызываете функцию rdir из себя, переменная dir перезаписывается. Исходя из вышеизложенного, попробуйте объявить вашу функцию как function rdir, чтобы получить семантику ksh88 с переменными локальной области видимости.

1 голос
/ 01 декабря 2009

отлично!

function rdir
{
    typeset dir=$1

    for file in `ls $dir`
    do
        if [ -d $dir/$file ]
        then
            echo "Directory: $dir/$file"
            rdir $dir/$file
        else
            echo "File     : $dir/$file"
        fi
    done
}

rdir /tmp/nonsens

делает работу. Спасибо.

...