Como criar chamada de função recursiva em unix

1
#!/bin/sh
checking()
{
  cd "$1"
  for D in *;do
    if [ -d "$D" ]; then
      cd "$D"
      for d in *;do
        echo "$d"
        if [ -d "$d" ]
        then
           'checking() $d'
        fi
        if [ -f "$d" ]
        then
                file_name='echo "$d" | cut -d'.' -f1'
                echo $file_name
                file_ext=$(echo $d |awk -F . '{if (NF>1) {print $NF}}')
                echo $file_ext
                if [ $file_ext = bin ]
                then
                        strings $d > $file_name.txt
                        mv $file_name.txt /somepath
                fi
        fi

      done
      cd ..

    fi
  done
}

a=$(pwd)
checking() $a

Estou convertendo arquivos binários de log de sessão em arquivos de texto e armazenando em algum caminho usando a função strings. Para cada diretório que está executando bem, mas não está verificando os arquivos binários para qualquer subdiretório presente.

Eu tentei usar a chamada de função recursiva, mas essa chamada não está sendo disparada..Por favor, ajude

    
por Paras Singh 29.11.2017 / 10:48

1 resposta

3

Observo algumas coisas na sua função:

  • Você se transforma em um diretório e, em seguida, percorre os arquivos e os dois novamente ( cd; for d in *; do cd; for d in * ... ). Isso parece que iria pular todos os outros níveis da árvore de diretórios durante uma caminhada recursiva. Uma iteração sobre os arquivos deve ser suficiente
  • Eu não acho que você precise usar um subshell quando chamar recursivamente a função (há a substituição do comando de backtick em 'checking() $d' ). Isso poderia ser útil se você precisasse de variáveis locais para cada instância da chamada de função, mas muitas shells podem fazer isso diretamente (usando local no Bash, aparentemente typeset in ksh93 )
  • E, claro, a sintaxe para chamar uma função: dado hi() { echo "hello $1"; } , executamos como qualquer outro comando, simplesmente com hi "$name" .
  • Podemos anular o awk e usar a expansão de parâmetro do shell para escolher a extensão do arquivo. (mas verifique o caso limite quando não houver ponto no nome do arquivo). Ou use case "$f" in *.bin) ...

Aqui está uma função bastante simples para percorrer uma árvore de diretórios:

#!/bin/sh

walk() {
        cd "$1"
        for f in *; do 
                if [ -d "$f" ] ; then
                        echo descending into "$f"...
                        walk "$f"
                else
                        ext=${f##*.}
                        if [ "$ext" = "bin" ] ; then
                                echo "found .bin file: $f"
                        fi
                fi

        done
        cd ..
}

walk .

(Embora a estrutura cd "$dir"; ... ; cd .. possa causar problemas se alguém mover um diretório no momento em que o programa estiver processando esse diretório. O link .. será alterado e o retorno por ele continuará do novo local, que pode até estar fora da árvore original. Poderíamos trabalhar em torno disso usando nomes absolutos de caminho o tempo todo, ou com pushd/popd (no Bash), ou colocando toda a função ou chamadas para ele em subshells.)

    
por 29.11.2017 / 11:38