Encontre e execute o script de outro diretório

1

Eu tenho um script, digamos data.sh , que pega muitos arquivos de dados no mesmo diretório e os processa. Eu tenho muitos diretórios com arquivos diferentes, mas eu tenho o mesmo script em todos. Eu posso rotineiramente ir para cada diretório e executar data.sh por ./data.sh , mas é tedioso.

  • Como posso executar data.sh do diretório pai? Meu primeiro palpite sobre ./parent/dir1/data.sh não funciona.

  • Gostaria de executar todos os scripts data.sh simultaneamente. Como? Posso encontrar todos os data.sh pelo comando find no diretório pai: find . -name data.sh . Como -exec com eles? O seguinte tem o mesmo problema do meu primeiro ponto:

    find . -name data.sh -exec ./{} \;
    
por physiker 09.08.2014 / 16:24

1 resposta

0

A solução óbvia seria alterar data.sh e aceitar um ou mais argumentos, sendo estes os arquivos (e talvez diretórios) sendo trabalhados.

Diga que o script contém atualmente:

#!/bin/bash
some-command ./*    # ← this is where it works on all files

Você mudaria para:

#!/bin/bash
some-command "$@"

Aqui, $@ é todos os argumentos passados para data.sh e você só precisa chamá-lo assim:

/path/to/data.sh /path/to/another/directory/*

Em seguida, o script será executado em todos os arquivos no outro diretório. É claro que, sem saber exatamente o funcionamento interno de data.sh , é impossível sugerir como alterá-lo, especificamente.

Se você quiser manter data.sh como está, é necessário alterar o diretório atual sempre que o chamar. Isso fará com que seu script "pense" dentro de outro diretório.

Você pode conseguir isso usando cd (ou pushd / popd ) de um shell lançado por find :

find . -name "data.sh" -exec sh -c 'cd "$(dirname "$0")" && ./data.sh' {} \;

Ou você pode temporariamente cd o diretório em um subshell (são os parênteses em torno de cd ), talvez com globs, então você pode pular usando find (o ** corresponderá recursivamente a todos os diretórios): / p>

shopt -s globstar
for script in **/data.sh; do
    ( cd "$(dirname "$script")" && ./data.sh )
done

Se você não tivesse usado um subshell no comando acima, a segunda chamada cd falharia, pois tentaria cd do primeiro diretório encontrado que contivesse data.sh . Você pode evitar isso com pushd / popd :

for script in **/data.sh; do
    pushd "$(dirname "$script")" && ./data.sh
    popd
done
    
por 09.08.2014 / 17:53