Несколько «находок» для наблюдателей одновременно - выполняется только первый - PullRequest
0 голосов
/ 03 июля 2019

Я пытаюсь запустить скрипт, который будет наблюдать за другой папкой и файлами и, если они меняются, выполнить команду.Один из путей к папкам принимает динамическую переменную, которая будет меняться в зависимости от того, что введено при запуске сценария в CLI, а другой не изменится.

Однако, в зависимости от пути к файлу, необходимо выполнить другое действие.

#!/usr/bin/env bash

THEME=$1

while true;
do
  echo "inside find"
    find code/themes/$THEME/src -name '*.html' -o -name '*.ts' -o -name '*.scss' | entr -d rsync -avh code/themes/$THEME/*  ./
    find code/base/src -name '*.html' -o -name '*.ts' -o -name '*.scss' | entr -d rsync -avh code/base/*  ./
done

Когда я запускаю сценарий, происходит следующее: он запускается и помещает часы на первоеfind (в приведенном выше примере, только динамический путь).

В настоящее время моя проблема такова:

  • Вызывается только ПЕРВАЯ находка и в коде ставятся только часы.themes / $ THEME / src paths
  • Вторая находка никогда не выполняется

Как мне запустить оба одновременно?Или, как я могу написать все это в одну строку?

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

Моя главная цель:

  1. Я хочу настроить часы для любых изменений в пути / темах / $ THEME / src
  2. я хочу настроить наблюдение за любыми изменениями в пути / base / src
  3. Я хочу, чтобы оба наблюдателя работали одновременно

1 Ответ

1 голос
/ 03 июля 2019

Если ваша задача - просто убедиться, что последующие копии двух (или 1 + количество тем) каталогов всегда актуальны, задание cron, которое синхронизирует их каждые n минут, может быть самым простым и надежным решением. cron имеет поминутную гранулярность, хотя что-то вроде каждые пять минут вполне может быть достаточно для вашего случая использования. rsync по своему замыслу не копирует файлы, которые уже обновлены, поэтому он должен быть достаточно быстрым для выполнения в нерабочем случае.

* * * * * bin/rsyncthemes

(Это один раз в минуту; в Linux вы можете сказать */5 в первом поле для запуска каждые 5 минут, но это не переносимо на все диалекты cron.) ... где rsyncthemes содержит что-то как

#!/bin/sh
# cron jobs always start in your home directory,
# but you want to put an absolute path here
# to run this in the directory where you want rsync to copy these files
cd somewhere

for dir in code/themes/one \
    code/themes/other \
    code/base
do
    rsync -avh "$dir"/*  ./
done

, где, очевидно, это необходимо пометить исполняемым (chmod a+x rsyncthemes) и сохранить в каталоге, указанном в задании cron (а именно bin в вашем домашнем каталоге).

Если вы склонны к использованию entr, чтобы избежать ненужного запуска rsync, я думаю, вы хотите что-то вроде

for dir in code/themes/one \
    code/themes/other \
    code/base
do
    while true; do
        find "$dir"/src -name '*.html' -o -name '*.ts' -o -name '*.scss' |
        entr -d rsync -avh "$dir"/*  ./
    done & # <-- run each loop as a background job
done

Более подробно, мы запускаем три цикла while true в качестве фоновых заданий, по одному для каждого из каталогов, перечисленных в цикле for. Они работают параллельно с вашей интерактивной оболочкой и прекратят работу, когда вы выйдете из системы (если вы отдельно не настроите их для работы с чем-то вроде nohup). Оператор & - это то, что запускает что-то в фоновом режиме, и помещая его после оператора done цикла while, он применяется ко всему циклу.

Полагаю, вам может понадобиться использовать entr -n, чтобы задания выполнялись в фоновом режиме.

Подстановочный знак в команде rsync расширяется оболочкой, поэтому вам может потребоваться изменить его, чтобы не использовать подстановочный знак, или вычислять подстановочный знак только после завершения find, если вы ожидаете, что это возможно для новые файлы появляются в этих каталогах время от времени. (Цитируя всю команду rsync и передавая ее с entr -s, можно легко выполнить это, если я правильно читаю справочную страницу entr.)

...