1

У меня есть скрипт, скажем data.sh , который берет много файлов данных в одном каталоге и обрабатывает их. У меня много каталогов с разными файлами, но у меня один и тот же скрипт во всех. Я обычно могу перейти к каждому каталогу и выполнить data.sh помощью ./data.sh но это утомительно.

  • Как я могу запустить data.sh из родительского каталога ? Моя первая догадка ./parent/dir1/data.sh не работает.

  • Я хотел бы выполнить все сценарии data.sh одновременно. Как? Я могу найти все data.sh командой find в родительском каталоге dir: find . -name data.sh Как- -exec с ними? Следующее имеет ту же проблему, что и в моем первом пункте:

    find . -name data.sh -exec ./{} \;
    

1 ответ1

0

Очевидным решением будет изменить data.sh и заставить его принимать один или несколько аргументов, над которыми работают файлы (и, возможно, каталоги).

Скажем, скрипт в настоящее время содержит:

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

Тогда вы бы изменили его на:

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

Здесь $@ - это все аргументы, передаваемые в data.sh , и вам нужно всего лишь вызвать его так:

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

Затем скрипт будет запускаться на всех файлах в другом каталоге. Конечно, не зная точной внутренней работы data.sh , невозможно предложить, как конкретно это изменить.


Если вы хотите сохранить data.sh как есть, вам нужно менять текущий каталог каждый раз, когда вы вызываете его. Это заставит ваш скрипт "думать", что он находится в другом каталоге.

Вы можете добиться этого, используя cd (или pushd/popd) из оболочки, запущенной командой find:

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

Или вы можете временно cd каталог в подоболочке (это круглые скобки вокруг cd), возможно, с помощью globs, поэтому вы можете пропустить команду find (** рекурсивно сопоставит все каталоги):

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

Если вы не использовали подоболочку в приведенной выше команде, второй вызов cd завершится неудачно, так как он попытается выполнить cd из первого найденного каталога, содержащего data.sh Вы можете избежать этого с помощью pushd/popd:

for script in **/data.sh; do
    pushd "$(dirname "$script")" && ./data.sh
    popd
done

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .