Como criar chamada de função recursiva no Unix

Como criar chamada de função recursiva no Unix
#!/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, ele está funcionando bem, mas não está verificando os arquivos binários de nenhum subdiretório presente.

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

Responder1

Observo algumas coisas em sua função:

  • Você muda para um diretório, itera sobre os arquivos e faz as duas coisasde novo( cd; for d in *; do cd; for d in * ...). Parece que isso iria pular todos os outros níveis da árvore de diretórios durante uma caminhada recursiva. Uma iteração nos arquivos deve ser suficiente
  • Eu não acho que você precise usar um subshell ao chamar recursivamente a função (há a substituição do comando 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 muitos shells podem fazer isso diretamente (usando localno Bash,aparentemente typesetem ksh93)
  • E, claro, a sintaxe para chamar uma função: dado que hi() { echo "hello $1"; }a executamos como qualquer outro comando, simplesmente com hi "$name".
  • Podemos anular o awke usar o shellexpansão de parâmetrospara escolher a extensão do arquivo. (mas verifique o caso limítrofe quando não há ponto no nome do arquivo.) Ou usecase "$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 .

(Observe que a cd "$dir"; ... ; cd ..estrutura pode causar problemas se alguém mover um diretório no momento em que o programa estiver processando esse diretório. O ..link mudaria e o retorno através dele continuaria a partir do novo local, que pode até estar fora da árvore original. Poderíamos contornar isso usando nomes de caminhos absolutos o tempo todo, ou com pushd/popd(no Bash), ou colocando toda a função ou chamadas para ela em subshells.)

informação relacionada