it-swarm-ru.tech

Как выполнить команду при изменении файла?

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

В настоящее время я использую это:

while read; do ./myfile.py ; done

И тогда мне нужно пойти в этот терминал и нажать Enterвсякий раз, когда я сохраняю этот файл в моем редакторе. Я хочу что-то вроде этого:

while sleep_until_file_has_changed myfile.py ; do ./myfile.py ; done

Или любое другое решение, столь же простое.

Кстати: я использую Vim, и я знаю, что могу добавить автокоманду для запуска чего-либо на BufWrite, но сейчас это не то решение, которое мне нужно.

Обновление: Я хочу что-то простое, если возможно, отказаться. Более того, я хочу, чтобы что-то запускалось в терминале, потому что я хочу видеть вывод программы (я хочу видеть сообщения об ошибках).

Об ответах: Спасибо за все ваши ответы! Все они очень хороши, и каждый из них отличается от других. Поскольку мне нужно принять только один, я принимаю тот, который я фактически использовал (это было просто, быстро и легко запомнить), хотя я знаю, что это не самый элегантный.

418
Denilson Sá Maia

Просто, используя inotifywait (установите пакет inotify-tools вашего дистрибутива):

while inotifywait -e close_write myfile.py; do ./myfile.py; done

или же

inotifywait -q -m -e close_write myfile.py |
while read -r filename event; do
  ./myfile.py         # or "./$filename"
done

Первый фрагмент проще, но у него есть существенный недостаток: он пропустит изменения, выполненные, когда inotifywait не запущен (в частности, когда myfile работает). Второй фрагмент не имеет этого дефекта. Однако следует помнить, что предполагается, что имя файла не содержит пробелов. Если это проблема, используйте параметр --format, чтобы изменить вывод, не включая имя файла:

inotifywait -q -m -e close_write --format %e myfile.py |
while read events; do
  ./myfile.py
done

В любом случае есть ограничение: если какая-то программа заменяет myfile.py другим файлом, а не записывает в существующую myfile, inotifywait умрет. Многие редакторы работают таким образом.

Чтобы преодолеть это ограничение, используйте inotifywait в каталоге:

inotifywait -e close_write,moved_to,create -m . |
while read -r directory events filename; do
  if [ "$filename" = "myfile.py" ]; then
    ./myfile.py
  fi
done

В качестве альтернативы используйте другой инструмент, который использует те же базовые функции, например, incron (позволяет регистрировать события при изменении файла) или fswatch (инструмент, который также работает на многих других вариантах Unix, используя каждый вариантный вариант Linux inotify).

383
Gilles

entr ( http://entrproject.org/ ) предоставляет более дружественный интерфейс для inotify (а также поддерживает * BSD и Mac OS X).

Это позволяет очень легко указать несколько файлов для просмотра (ограничено только ulimit -n), избавляет от необходимости иметь дело с заменяемыми файлами и требует меньше синтаксиса bash:

$ find . -name '*.py' | entr ./myfile.py

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

Флаги, такие как -c (очистить экран между запусками) и -d (выход при добавлении нового файла в контролируемый каталог), добавляют еще больше гибкости, например, вы можете сделать:

$ while sleep 1 ; do find . -name '*.py' | entr -d ./myfile.py ; done

По состоянию на начало 2018 года он все еще находится в активной разработке, и его можно найти в Debian & Ubuntu (apt install entr); Строительство из репо автора было в любом случае безболезненным.

148
Paul Fenney

Я написал программу на Python, чтобы сделать именно это, называемый при изменении .

Использование простое:

when-changed FILE COMMAND...

Или посмотреть несколько файлов:

when-changed FILE [FILE ...] -c COMMAND

FILE может быть каталогом. Смотреть рекурсивно с -r. Используйте %f для передачи имени файла команде.

105
joh

Как насчет этого сценария? Он использует команду stat для получения времени доступа к файлу и запускает команду всякий раз, когда происходит изменение времени доступа (при каждом обращении к файлу).

#!/bin/bash

### Set initial time of file
LTIME=`stat -c %Z /path/to/the/file.txt`

while true    
do
   ATIME=`stat -c %Z /path/to/the/file.txt`

   if [[ "$ATIME" != "$LTIME" ]]
   then    
       echo "RUN COMMAND"
       LTIME=$ATIME
   fi
   sleep 5
done
48
VDR

Решение с использованием Vim:

:au BufWritePost myfile.py :silent !./myfile.py

Но я не хочу этого решения, потому что набирать его немного раздражает, довольно сложно вспомнить, что именно печатать, и немного сложно отменить его эффекты (нужно запустить :au! BufWritePost myfile.py). Кроме того, это решение блокирует Vim до завершения выполнения команды.

Я добавил это решение здесь только для полноты, так как оно может помочь другим людям.

Чтобы отобразить вывод программы (и полностью прервать процесс редактирования, поскольку вывод будет записываться в ваш редактор в течение нескольких секунд, пока вы не нажмете Enter), удалите команду :silent.

30
Denilson Sá Maia

Если у вас установлена ​​ npm , nodemon , вероятно, самый простой способ начать работу, особенно в OS X, которая, очевидно, не имеет инструментов inotify. Он поддерживает запуск команды при изменении папки.

23
davidtbernal

rerun2 ( на github ) - это 10-строчный Bash-скрипт вида:

#!/usr/bin/env bash

function execute() {
    clear
    echo "[email protected]"
    eval "[email protected]"
}

execute "[email protected]"

inotifywait --quiet --recursive --monitor --event modify --format "%w%f" . \
| while read change; do
    execute "[email protected]"
done

Сохраните версию github как 'rerun' в вашей переменной PATH и вызовите ее, используя:

rerun COMMAND

Он запускает COMMAND каждый раз, когда в вашем текущем каталоге происходит событие изменения файловой системы (рекурсивно.)

Вещи, которые могут понравиться об этом:

  • Он использует inotify, поэтому более отзывчив, чем опрос. Потрясающе для запуска юнит-тестов с точностью до миллисекунды или рендеринга файлов графических точек каждый раз, когда вы нажимаете «сохранить».
  • Поскольку это так быстро, вам не нужно беспокоиться о том, чтобы игнорировать большие подкаталоги (например, node_modules) только из соображений производительности.
  • Это очень супер-отзывчивый, потому что он вызывает inotifywait только один раз, при запуске, вместо того, чтобы запускать его, и на каждой итерации возникает дорогостоящий удар по созданию часов.
  • Это всего лишь 12 строк Bash
  • Поскольку это Bash, он интерпретирует команды, которые вы передаете, точно так же, как если бы вы вводили их в Bash Prompt. (Предположительно, это менее круто, если вы используете другую оболочку.)
  • Он не теряет события, которые происходят во время выполнения команды COMMAND, в отличие от большинства других решений inotify на этой странице.
  • При первом событии он вводит «мертвый период» на 0,15 секунды, в течение которого другие события игнорируются, прежде чем COMMAND будет запущен ровно один раз. Это происходит из-за того, что поток событий, вызванных танцем create-write-move, который Vi или Emacs делает при сохранении буфера, не вызывает много трудоемких выполнений, возможно, медленного набора тестов. Любые события, которые затем происходят во время выполнения COMMAND, не игнорируются - они вызовут второй мертвый период и последующее выполнение.

Вещи, которые могут не понравиться об этом:

  • Он использует inotify, поэтому не будет работать за пределами Linuxland.
  • Поскольку он использует inotify, он будет пытаться просмотреть каталоги, содержащие больше файлов, чем максимальное количество пользовательских наблюдений inotify. По умолчанию на разных компьютерах, которые я использую, установлено, что оно составляет от 5000 до 8000, но его легко увеличить. См. https://unix.stackexchange.com/questions/13751/kernel-inotify-watch-limit-reached
  • Не удается выполнить команды, содержащие псевдонимы Bash. Я могу поклясться, что раньше это работало. В принципе, поскольку это Bash, который не выполняет COMMAND в подоболочке, я ожидал, что это сработает. Я хотел бы услышать, если кто-нибудь знает, почему это не так. Многие другие решения на этой странице также не могут выполнять такие команды.
  • Лично я хотел бы нажать клавишу в терминале, в котором он работает, чтобы вручную вызвать дополнительное выполнение команды. Могу ли я добавить это как-нибудь, просто? Параллельно работающий цикл while read -n1, который также вызывает execute?
  • Прямо сейчас я кодировал его, чтобы очистить терминал и печатать выполненную КОМАНДУ на каждой итерации. Некоторые люди могут захотеть добавить флаги командной строки, чтобы отключить подобные вещи и т.д. Но это увеличит размер и сложность во много раз.

Это уточнение ответа @ cychoi.

15
Jonathan Hartley

Для тех, кто не может установить inotify-tools, как я, это должно быть полезно:

watch -d -t -g ls -lR

Эта команда завершится при изменении выходных данных, ls -lR перечислит каждый файл и каталог с указанием его размера и даты, поэтому, если файл будет изменен, он должен выйти из команды, как говорит man:

-g, --chgexit
          Exit when the output of command changes.

Я знаю, что этот ответ не может быть прочитан никем, но я надеюсь, что кто-то достигнет его.

Пример командной строки:

~ $ cd /tmp
~ $ watch -d -t -g ls -lR && echo "1,2,3"

Откройте другой терминал:

~ $ echo "testing" > /tmp/test

Теперь первый терминал будет выводить 1,2,3

Простой пример скрипта:

#!/bin/bash
DIR_TO_WATCH=${1}
COMMAND=${2}

watch -d -t -g ls -lR ${DIR_TO_WATCH} && ${COMMAND}
13
Sebastian

Вот простой сценарий Shell Bourne Shell, который:

  1. Принимает два аргумента: файл для мониторинга и команду (с аргументами, если необходимо)
  2. Копирует файл, который вы отслеживаете, в каталог/tmp
  3. Проверяет каждые две секунды, чтобы увидеть, является ли файл, который вы отслеживаете, более новым, чем копия
  4. Если он новее, он перезаписывает копию новым оригиналом и выполняет команду
  5. Убирает за собой при нажатии Ctr-C

    #!/bin/sh  
    f=$1  
    shift  
    cmd=$*  
    tmpf="`mktemp /tmp/onchange.XXXXX`"  
    cp "$f" "$tmpf"  
    trap "rm $tmpf; exit 1" 2  
    while : ; do  
        if [ "$f" -nt "$tmpf" ]; then  
            cp "$f" "$tmpf"  
            $cmd  
        fi  
        sleep 2  
    done  
    

Это работает на FreeBSD. Единственная проблема с переносимостью, о которой я могу подумать, это то, что в некоторых других Unix нет команды mktemp (1), но в этом случае вы можете просто жестко закодировать имя временного файла.

12
MikeyMike

Взгляните на incron . Это похоже на cron, но использует события inotify вместо времени.

8
Florian Diesch

Другое решение с NodeJs,fsmonitor:

  1. Установить

    Sudo npm install -g fsmonitor
    
  2. Из командной строки (например, монитор журналов и «розничная торговля», если один файл журнала изменяется)

    fsmonitor -s -p '+*.log' sh -c "clear; tail -q *.log"
    
6
Atika

Посмотрите на Guard, в частности, с этим плагином:

https://github.com/hawx/guard-Shell

Вы можете настроить его на просмотр любого количества шаблонов в каталоге вашего проекта и выполнение команд при возникновении изменений. Хороший шанс, даже если есть плагин для того, что вы пытаетесь сделать в первую очередь.

6
Wouter Van Vliet

Под Linux:

man watch

watch -n 2 your_command_to_run

Будет запускать команду каждые 2 секунды.

Если ваша команда выполняется более 2 секунд, часы будут ждать, пока она не будет выполнена, прежде чем делать это снова.

6
Eric Leschinski

если у вас установлен nodemon , то вы можете сделать это:

nodemon -w <watch directory> -x "<Shell command>" -e ".html"

В моем случае я редактирую html локально и отправляю его на мой удаленный сервер при изменении файла.

nodemon -w <watch directory> -x "scp filename [email protected]:/var/www" -e ".html"
5
Jay

Watchdog- это проект Python, и он может быть именно тем, что вы ищете:

Поддерживаемые платформы

  • Linux 2.6 (inotify)
  • Mac OS X (FSEvents, kqueue)
  • FreeBSD/BSD (kqueue)
  • Windows (ReadDirectoryChangesW с портами завершения ввода/вывода; рабочие потоки ReadDirectoryChangesW)
  • Независимо от ОС (опрос диска на наличие снимков каталогов и их периодическое сравнение; медленный и не рекомендуется)

Просто написал оболочку командной строки для негоwatchdog_exec:

Пример работает

На событии fs, включающем файлы и папки в текущем каталоге, выполните команду echo $src $dst, если только это событие fs не изменено, а затем выполните команду python $src.

python -m watchdog_exec . --execute echo --modified python

Использование коротких аргументов и ограничение на выполнение только в том случае, если события включают " main . Py":

python -m watchdog_exec . -e echo -a echo -s __main__.py

Правка: Только что обнаружил, что Watchdog имеет официальный CLI под названием watchmedo, так что проверьте это также.

5
Samuel Marks

Если ваша программа генерирует какой-либо журнал/вывод, вы можете создать Makefile с правилом для этого журнала/вывода, который зависит от вашего сценария и сделать что-то вроде

while true; do make -s my_target; sleep 1; done

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

4
ctgPi

Улучшено на ответ Жиля .

Эта версия запускает inotifywait один раз и отслеживает события (.e.: modify) после этого. Таким образом, inotifywait not необходимо повторно выполнять при каждом обнаруженном событии.

Это быстро и быстро! (даже при рекурсивном мониторинге большого каталога)

inotifywait --quiet --monitor --event modify FILE | while read; do
    # trim the trailing space from inotifywait output
    REPLY=${REPLY% }
    filename=${REPLY%% *}
    # do whatever you want with the $filename
done
4
cychoi
4
Denilson Sá Maia

Еще немного о программировании, но вы хотите что-то вроде inotify . Существуют реализации на многих языках, такие как jnotify и pyinotify .

Эта библиотека позволяет отслеживать отдельные файлы или целые каталоги и возвращает события при обнаружении действия. Возвращаемая информация включает в себя имя файла, действие (создание, изменение, переименование, удаление) и путь к файлу, а также другую полезную информацию.

3
John T

Мне нравится простота while inotifywait ...; do ...; done, однако она имеет две проблемы:

  • Изменения файла, происходящие во время do ...;, будут будут пропущены
  • Медленно при использовании в рекурсивном режиме

Для этого я создал вспомогательный скрипт, который использует inotifywait без этих ограничений: inotifyexec

Я предлагаю вам поставить этот скрипт на вашем пути, как в ~/bin/. Использование описывается просто запуском команды.

Пример: inotifyexec "echo test" -r .

3
Wernight

Улучшено решение Себастьяна с командой watch:

watch_cmd.sh:

#!/bin/bash
WATCH_COMMAND=${1}
COMMAND=${2}

while true; do
  watch -d -g "${WATCH_COMMAND}"
  ${COMMAND}
  sleep 1     # to allow break script by Ctrl+c
done

Пример звонка:

watch_cmd.sh "ls -lR /etc/nginx | grep .conf$" "Sudo service nginx reload"

Это работает, но будьте осторожны: команда watch имеет известные ошибки (см. Man): она реагирует на изменения только в VISIBLE в терминальных частях вывода -g CMD.

3
alex_1948511

Для тех из вас, кто ищет решение FreeBSD, вот порт:

/usr/ports/sysutils/wait_on
3
akond

Вы можете попробовать рефлекс .

Reflex - небольшой инструмент для просмотра каталога и повторного запуска команды при изменении определенных файлов. Он отлично подходит для автоматического запуска задач компиляции/lint/test и для перезагрузки приложения при изменении кода.

# Rerun make whenever a .c file changes
reflex -r '\.c$' make
2
masterxilo

Для тех, кто использует OS X, вы можете использовать LaunchAgent, чтобы отслеживать путь/файл на предмет изменений и что-то делать, когда это происходит. К вашему сведению - LaunchControl - хорошее приложение для простого создания/изменения/удаления демонов/агентов.

( пример взят здесь )

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN
http://www.Apple.com/DTDs/PropertyList-1.0.dtd>
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>test</string>
    <key>ProgramArguments</key>
    <array>
        <string>say</string>
        <string>yy</string>
    </array>
    <key>WatchPaths</key>
    <array>
        <string>~/Desktop/</string>
    </array>
</dict>
</plist>
1
Hefewe1zen

У меня есть Gist для этого, и использование довольно просто

watchfiles <cmd> <paths...>

https://Gist.github.com/thiagoh/5d8f53bfb64985b94e5bc8b3844dba55

1
thiagoh

Я использую этот скрипт, чтобы сделать это. Я использую inotify в режиме монитора

#!/bin/bash
MONDIR=$(dirname $1)
ARQ=$(basename $1)

inotifywait -mr -e close_write $MONDIR | while read base event file 
do
  if (echo $file |grep -i "$ARQ") ; then
    $1
  fi
done

Сохраните это как runatwrite.sh

Usage: runatwrite.sh myfile.sh

он будет запускать myfile.sh при каждой записи.

1
Fernando Silva

Ответ oneliner, который я использую, чтобы отслеживать изменения файла:

$ while true ; do NX=`stat -c %Z file` ; [[ $BF != $NX ]] && date >> ~/tmp/fchg && BF=$NX || sleep 2 ; done

Вам не нужно инициализировать BF, если вы знаете, что первая дата является временем начала.

Это просто и портативно. Здесь есть другой ответ, основанный на той же стратегии с использованием сценария. Посмотрите также.


Использование: я использую это для отладки и слежу за ~/.kde/share/config/plasma-desktop-appletsrc; что по неизвестной причине продолжает терять мой SwitchTabsOnHover=false

1
Dr Beco

Основное использование

Вот решение, которое не требует установки большего количества программного обеспечения и работает из коробки.

tail -q --follow=name myfile.txt | head -n 0

Эта команда завершается при следующих условиях:

  • Строка добавляется в myfile.txt после запуска команды
  • myfile.txt заменяется другим после выполнения команды

Вы говорите, что используете vim, и vim заменит файл при сохранении. Я проверил это работает с Vim.

Вы можете игнорировать вывод этой команды, она может упомянуть что-то вроде:

хвост: «myfile.txt» заменен; следующий конец нового файла

Расширенное использование

Вы можете объединить это с timeout, чтобы вернуть true или false. Вы можете использовать это так:

timeout 5s bash -c 'tail -q --follow = имя канала 2>/dev/null | заголовок -n 0 '&& echo изменен || тайм-аут эха

Обсуждение

tail использует inotify под капотом. Вот так вы получаете это причудливое асинхронное поведение без опроса. Вероятно, есть какая-то другая стандартная Unix-программа, которая использует inotify, которую мы можем использовать более элегантно.

Иногда эти команды выходят сразу, но если вы сразу же запустите их во второй раз, они будут работать так, как объявлено. Я где-то допустил ошибку, помогите мне исправить это.

На RHEL я могу использовать:

тайм-аут 5s sh -c 'gio monitor pipe | заголовок -n 0 '&& echo изменен || тайм-аут эха

Но я не уверен, что это портативно.

0
William Entriken

find может сделать свое дело.

while true; do
    find /path/to/watched/file -ctime 1s | xargs do-what-you-will
done

find -ctime 1s печатает имя файла, если оно было изменено в последнем 1s.

0
lvijay

Инструмент «fido» может быть еще одним вариантом для этой необходимости. Смотрите https://www.joedog.org/fido-home/

0
David Ramirez

Для людей, которые находят это с помощью Googling для внесения изменений в конкретный файл, ответ гораздо проще (вдохновлен ответом Жиля ).

Если вы хотите что-то сделать после был записан определенный файл, вот как:

while true; do
  inotifywait -e modify /path/to/file
  # Do something *after* a write occurs, e.g. copy the file
  /bin/cp /path/to/file /new/path
done

Сохраните это как, например, copy_myfile.sh и поместите файл .sh в папку /etc/init.d/, чтобы запустить его при запуске.

0
LondonRob

Как и некоторые другие, я также написал для этого облегченный инструмент командной строки. Он полностью документирован, протестирован и модульный.

Watch-Do

Installation

Вы можете установить его (если у вас есть Python3 и pip), используя:

pip3 install git+https://github.com/vimist/watch-do

Использование

Используйте это сразу, запустив:

watch-do -w my_file -d 'echo %f changed'

Обзор возможностей

  • Поддерживает глобализацию файлов (используйте -w '*.py' или -w '**/*.py')
  • Запустите несколько команд для изменения файла (просто снова укажите флаг -d)
  • Динамически поддерживает список файлов для просмотра, если используется globbing (-r, чтобы включить это)
  • Несколько способов «посмотреть» файл:
    • Время модификации (по умолчанию)
    • Файловый хеш
    • Тривиально реализовать свой собственный (это ModificationTime watcher)
  • Модульная конструкция. Если вы хотите, чтобы команды выполнялись, когда к файлу обращаются, написать свой собственный наблюдатель (механизм, который определяет, должны ли исполнители выполняться), тривиально.
0
vimist

Я написал для этого именно программу на Python, которая называется rerun .

ОБНОВЛЕНИЕ: Этот ответ представляет собой скрипт Python, который запрашивает изменения, что полезно в некоторых случаях. Для сценария Bash только для Linux, который использует inotify, см. Мой другой ответ, поищите на этой странице «rerun2».

Установите для Python2 или Python3 с:

pip install --user rerun

и использование очень просто:

rerun "COMMAND"

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

По умолчанию он просматривает все файлы в текущем каталоге или под ним, пропуская такие вещи, как известные каталоги управления исходным кодом, .git, .svn и т.д.

Необязательные флаги включают '-i NAME', который игнорирует изменения именованных файлов или каталогов. Это может быть дано несколько раз.

Поскольку это скрипт Python, он должен запускать команду как подпроцесс, и мы используем новый экземпляр текущей командной оболочки пользователя, чтобы интерпретировать 'COMMAND' и решить, какой процесс на самом деле запустить. Однако, если ваша команда содержит псевдонимы оболочки и т.п., которые определены в .bashrc, они не будут загружены подоболочкой. Чтобы это исправить, вы можете повторно установить флаг '-I', чтобы использовать интерактивные (иначе называемые 'логин') субоболочки. Это медленнее и более подвержено ошибкам, чем запуск обычной оболочки, потому что она должна быть источником вашего .bashrc.

Я использую его с Python 3, но последний раз, когда я проверял, повторный запуск все еще работал с Python 2.

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

С другой стороны, опрос означает, что задержка составляет от 0,0 до 1,0 секунды, и, конечно, медленнее отслеживать очень большие каталоги. Сказав это, я никогда не сталкивался с проектом, достаточно большим, чтобы это было даже заметно, если вы используете '-i', чтобы игнорировать такие важные вещи, как ваши virtualenv и node_modules.

Хммм. rerun был для меня незаменим в течение многих лет - я в основном использую его по восемь часов каждый день для запуска тестов, восстановления точечных файлов при их редактировании и т. д. Но теперь я пришел, чтобы напечатать это здесь, ясно, что мне нужно переключиться на Решение, которое использует inotify (я больше не использую Windows или OSX.) и написано на Bash (поэтому оно работает с псевдонимами без каких-либо дополнительных действий).

0
Jonathan Hartley

Описание

Это будет следить за изменениями в файле и выполнять любую команду (включая дополнительные аргументы) было задано как второе утверждение. Он также очистит экран и напечатает время последнего выполнения. Примечание: вы можете сделать функцию более (или менее) реактивной, изменив количество секунд, в течение которых функция должна находиться в спящем режиме после каждого цикла цикла.

Пример использования

watch_file my_file.php php my_file.php

Эта строка будет смотреть php-файл my_file.php и запускаться через интерпретатор php при каждом его изменении.


Определение функции

function watch_file (){

### Set initial time of file
LTIME=`stat -c %Z $1`
printf "\033c"
echo -e "watching: $1 ---- $(date '+%Y-%m-%d %H:%M:%S')\n-------------------------------------------\n"
${@:2}

while true
do
   ATIME=`stat -c %Z $1`

   if [[ "$ATIME" != "$LTIME" ]]
   then
    printf "\033c"
    echo -e "watching: $1 ---- $(date '+%Y-%m-%d %H:%M:%S')\n-------------------------------------------\n"
    ${@:2}
    LTIME=$ATIME
   fi
   sleep 1
done
}

Кредит

Это в основном более общий вариант ответа VDR.

0
petermeissner