Wie ein Shell-Skript, wenn eine Datei oder ein Verzeichnis Änderungen ausgeführt werden?

StackOverflow https://stackoverflow.com/questions/4060212

  •  27-09-2019
  •  | 
  •  

Frage

Ich möchte ein Shell-Skript ausgeführt werden soll, wenn eine bestimmte Datei oder ein Verzeichnis ändert.

Wie kann ich das einfach tun?

War es hilfreich?

Lösung

Verwenden Sie inotify-tools .

Andere Tipps

Ich benutze dieses Skript einen Build-Skript auf Änderungen in einem Verzeichnisbaum auszuführen:

#!/bin/bash -eu
DIRECTORY_TO_OBSERVE="js"      # might want to change this
function block_for_change {
  inotifywait --recursive \
    --event modify,move,create,delete \
    $DIRECTORY_TO_OBSERVE
}
BUILD_SCRIPT=build.sh          # might want to change this too
function build {
  bash $BUILD_SCRIPT
}
build
while block_for_change; do
  build
done

Verwendet inotify-tools. Prüfen inotifywait Manpage wie anpassen, was die Build auslöst.

Sie können versuchen, entr Werkzeug beliebige Befehle auszuführen, wenn Dateien geändert werden. Beispiel für Dateien:

$ ls -d * | entr sh -c 'make && make test'

oder:

$ ls *.css *.html | entr reload-browser Firefox

oder Druck Changed! wenn Datei file.txt wird gespeichert:

$ echo file.txt | entr echo Changed!

Für Verzeichnisse verwenden -d, aber Sie haben es in der Schleife zu verwenden, z.

while true; do find path/ | entr -d echo Changed; done

oder:

while true; do ls path/* | entr -pd echo Changed; done

Überprüfen Sie die Kernel-Dateisystem Monitor out-Daemon

http://freshmeat.net/projects/kfsmd/

Hier ist ein How-to:

http://www.linux.com/archive/feature/124903

Hier ist eine andere Option: http://fileschanged.sourceforge.net/

Siehe insbesondere „Beispiel 4“, die „überwacht ein Verzeichnis und Archive neue oder geänderte Dateien“.

inotifywait können Sie erfüllen.

Hier ist eine gemeinsame Probe für sie:

inotifywait -m /path -e create -e moved_to -e close_write | # -m is --monitor, -e is --event
    while read path action file; do
        if [[ "$file" =~ .*rst$ ]]; then             # if suffix is '.rst'
            echo ${path}${file} ': '${action}        # execute your command
            echo 'make html'
            make html
        fi
    done

Nur zum Debuggen, wenn ich einen Shell-Skript schreiben und will es speichern läuft auf, ich benutze diese:

#!/bin/bash
file="$1" # Name of file
command="${*:2}" # Command to run on change (takes rest of line)
t1="$(ls --full-time $file | awk '{ print $7 }')" # Get latest save time
while true
do
  t2="$(ls --full-time $file | awk '{ print $7 }')" # Compare to new save time
  if [ "$t1" != "$t2" ];then t1="$t2"; $command; fi # If different, run command
  sleep 0.5
done

Ausführen als

run_on_save.sh myfile.sh ./myfile.sh arg1 arg2 arg3

Edit: Vor getestet auf Ubuntu 12.04, für Mac OS, die ls Zeilen ändern:

"$(ls -lT $file | awk '{ print $8 }')"

Fügen Sie folgende zu ~ / .bashrc:

function react() {
    if [ -z "$1" -o -z "$2" ]; then
        echo "Usage: react <[./]file-to-watch> <[./]action> <to> <take>"
    elif ! [ -r "$1" ]; then
        echo "Can't react to $1, permission denied"
    else
        TARGET="$1"; shift
        ACTION="$@"
        while sleep 1; do
            ATIME=$(stat -c %Z "$TARGET")
            if [[ "$ATIME" != "${LTIME:-}" ]]; then
                LTIME=$ATIME
                $ACTION
            fi
        done
    fi
}

Beispiel für die Verwendung inotifywait:

Angenommen, ich rails test ich eine entsprechende Datei ändern, jedes Mal ausgeführt werden soll.

1. Machen Sie eine Liste der relevanten Dateien, die Sie sehen wollen:

Sie können es manuell tun, aber ich finde ack sehr hilfreich, diese Liste zu machen.

ack --type-add=rails:ext:rb,erb --rails -f > Inotifyfile

2. Stellen Sie inotifywait die Arbeit zu tun

while inotifywait --fromfile Inotifyfile; do rails test; done

Das ist es!

Hinweis: Falls Sie Vagrant verwenden Sie den Code auf einer VM laufen, finden Sie vielleicht nützlich, die mhallin / Vagabund-notify-Spediteur Erweiterung.

UPDATE: Noch besser ist, eine alias machen und loszuwerden der Datei:

alias rtest="while inotifywait $(ack --type-add=rails:ext:rb,erb --rails -f | tr \\n \ ); do rails test; done"
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top