Как получить и обработать объект изменения JSON?

Я использую сторож Facebook в Linux под bash для отслеживания изменений файловой системы.

Я не понимаю, как получить объект изменения JSON. Все, что я, кажется, получаю, это список измененных файлов. Я настраиваю часы и триггер, как показано ниже:

watchman watch /Users/osx/Applications/docker/tests watchman --
trigger /Users/osx/Applications/docker/tests 'file-sync' \
             -- /Users/osx/Applications/docker/filewatcher/file-sync.sh

Однако, когда я запрашиваю аргументы, прошедшие через сценарий file-sync.sh, он выглядит как просто текстовое поле, а не объект JSON.

Нужно ли мне делать что-то еще, чтобы получить полную информацию обо всех изменениях, происходящих в корне?

watchman trigger-list shows the following results: {   "version":
"4.9.0",   "triggers": [
    {
      "command": [
        "/Users/osx/Applications/docker/filewatcher/file-sync.sh"
      ],
      "stdin": [
        "name",
        "exists",
        "new",
        "size",
        "mode"
      ],
      "append_files": true,
      "name": "file-sync",
      "empty_on_fresh_instance": true
    }   ] }

Насколько я понимаю, это должно дать мне объект JSON с компонентами имени, существует, новый, размер и режим.

В системном журнале вижу следующее:

2019-01-15T22:28:49,191: [trigger file-sync
/Volumes/UserData/osx/Applications/docker/tests] input_json: sending
json object to stm

Что такое стм?

В системном журнале вижу следующее:

2019-01-15T22:28:49,191: [trigger file-sync 
/Volumes/UserData/osx/Applications/docker/tests] input_json: sending 
`enter code here`json object to stm

В моем сценарии bash я использую jq для вывода вывода JSON на стандартный вывод.

$(echo jq '.' $1)

person Peter Roden    schedule 15.01.2019    source источник


Ответы (1)


Watchman передаст список имен файлов вашей триггерной программе в векторе аргументов, а данные json будут предоставлены ей в ее потоке stdin.

Вы можете изменить свой скрипт bash, чтобы он делал:

jq '.'

и он должен показать вам интересующие данные.

Рассмотрите возможность использования watchman-make, а не триггеров

Я хотел бы отметить, что триггеры немного сложны в использовании и отладке, потому что они регистрируются в журнале сервера-сторожа и их трудно увидеть. По этой причине я подталкиваю людей к использованию watchman-make, который работает на переднем плане и имеет четкие сообщения о том, что происходит. Например, предполагая, что вы собираетесь вызвать rsync, вы, вероятно, можете сделать что-то вроде:

cd /Users/osx/Applications/docker/tests && \
   watchman-make -p '**/*' \
      --run /Users/osx/Applications/docker/filewatcher/file-sync.sh

а затем file-sync.sh может быть чем-то вроде:

#!/bin/bash
rsync /Users/osx/Applications/docker/tests somewhere:else

Обратите внимание, что этот шаблон «теряет» список измененных файлов, но rsync все равно будет сравнивать структуры каталогов, и большинство деревьев каталогов, как правило, достаточно малы, чтобы вы не возражали.

Если вы хотите или вам нужно сделать это инкрементным, вы можете сделать так, чтобы ваш скрипт снова вызывал сторож; что-то вроде этого перечислит файлы, измененные с момента последнего запуска:

watchman since /Users/osx/Applications/docker/tests n:file-sync

n:file-sync — это именованный курсор; сервер будет отслеживать данные внутренних часов от вашего имени каждый раз, когда вы используете их в запросе с тех пор. Дополнительную информацию об этом можно найти здесь: https://facebook.github.io/watchman/docs/clockspec.html

person Wez Furlong    schedule 17.01.2019
comment
Большое спасибо Wez за быстрый ответ. - person Peter Roden; 17.01.2019
comment
Просто добавив jq '.' к моему сценарию дал мне доступ к объекту JSON. Мне нужно иметь возможность фиксировать все изменения (новые, обновленные и удаленные), а также мне нужно надежное решение, которое быстро реагирует и способно обрабатывать потенциально большие корни и реагировать на изменения как можно быстрее. Мне нравится, что триггер дает мне немедленное уведомление, на которое я могу действовать. - person Peter Roden; 17.01.2019
comment
Вы упомянули, что watchman-make потеряет список изменений. Похоже, что rsync снова будет выполнять некоторую форму отслеживания изменений. Так не будет ли дублироваться работа, и не потеряю ли я часть способности отслеживания сторожа? - person Peter Roden; 17.01.2019
comment
Существуют ли какие-либо рекомендации по возможным подходам или вариантам использования, а также когда использовать каждый подход? - person Peter Roden; 17.01.2019
comment
Можете ли вы также объяснить JSON, который вы получаете при обновлении файла: [ {mode: 0, new: true, size: 0, exists: false, name: file.log.sb-f5914475-w3lcsW}, {mode: 33188 , новое: ложь, размер: 71, существует: правда, имя: file.log }, {режим: 0, новое: правда, размер: 0, существует: ложь, имя: файл.log.sb-f5914475-JN2nat } ] - person Peter Roden; 17.01.2019
comment
Похоже, что для каждого изменения файла вы получаете измененный файл плюс, я думаю, информацию до и после? Как бы я интерпретировал информацию .sb-....... JSON? - person Peter Roden; 17.01.2019
comment
Запись `{mode: 0, new: true, size: 0, exists: false, name: file.log.sb-f5914475-w3lcsW}, — это сторож, сообщающий вам о временном файле, который был создан и удален; его значение exists равно false, поэтому он больше не существует. Обычный шаблон - запись во временный файл, а затем атомарное переименование его в желаемое имя файла, которое в данном случае выглядит как file.log. Я бы рекомендовал не размещать файлы журналов для синхронизации/просмотра в каталоге, который вы просматриваете, чтобы избежать зацикливания и загрузки системы. - person Wez Furlong; 17.01.2019
comment
Что касается триггеров, дающих вам немедленную обратную связь: часто в сценарии синхронизации файлов вам нужно подождать, пока запись не установится, прежде чем запускать синхронизацию, в противном случае вы рискуете запустить синхронизацию несколько раз, пока файл записывается в отслеживаемый каталог. watchman-make имеет удобный флаг --settle для этой цели, тогда как триггеры имеют более грубую настройку установки для всего сервера, которую можно настроить через .watchmanconfig: facebook.github.io/watchman/docs/config.html#settle - person Wez Furlong; 17.01.2019
comment
Что касается руководящих принципов: если каталог, который вы просматриваете, содержит менее 100 000 файлов/каталогов, глупо звучащий подход watchman-make + rsync, о котором я упоминал, вероятно, подойдет и будет самым простым в управлении, понимании и обслуживании. Если ваша система постоянно выполняет много операций ввода-вывода и у вас много файлов, то вам может понадобиться более сложная система. Я бы предложил вариант watchman-make + именованный курсор в этой ситуации как простое решение для создания мелкозернистого и инкрементного. - person Wez Furlong; 17.01.2019
comment
Если вам действительно нужна реакция на изменения в реальном времени и точный программный контроль, я бы предложил игнорировать все это и использовать либо pywatchman, либо клиент fb-watchman nodejs и вместо этого использовать subscriptions. watchman-make использует pywatchman таким образом; вот его код: github.com/facebook/watchman/blob/ master/python/bin/ Вы можете найти примеры использования клиента nodejs в документации здесь: facebook.github.io/watchman/docs/nodejs.html - person Wez Furlong; 17.01.2019
comment
Еще раз спасибо, Вез. Изначально я думал об использовании bash-скриптов. Практически мне интересно, какие варианты у меня есть, если я хочу использовать watchman-make и pywatchman, как вы предлагаете. Означает ли это, что я вынужден использовать nodejs или python? - person Peter Roden; 22.01.2019
comment
Меня интересует отлов новых, измененных, переименованных и удаленных файлов/каталогов. Как я могу поймать изменение имени файла или каталога? - person Peter Roden; 22.01.2019
comment
Я заинтересован в том, чтобы все поля возвращались как в stdin в триггерах. Смотреть на watchman-make python было очень полезно, за исключением того, что он возвращает только поле имени в запросе. Можно ли это расширить или мне придется в основном клонировать watchman-make и добавлять другие поля, которые меня интересуют? - person Peter Roden; 22.01.2019