2010-06-04 31 views
17

Tôi muốn tự động khởi chạy một bản dựng bất cứ khi nào một tệp thay đổi.kịch bản lệnh linux giám sát các thay đổi tệp trong các thư mục (như autospec!)

Tôi đã sử dụng autospec (RSpec) trong Ruby và yêu thích điều đó.

Làm thế nào điều này có thể được thực hiện trong bash?

+0

thấy cũng http://stackoverflow.com/q/4060212/119790 –

+0

cũng xem http://stackoverflow.com/q/880263/119790 –

+0

Xem thêm http://superuser.com/questions/18151 7/how-to-execute-a-command-bất cứ khi nào-a-file-thay đổi –

Trả lời

5

Sau khi đọc trả lời cho bài viết khác, tôi tìm thấy một bài (nay là đi), tôi tạo ra kịch bản này: -

#!/bin/bash 

sha=0 
previous_sha=0 

update_sha() 
{ 
    sha=`ls -lR . | sha1sum` 
} 

build() { 
    ## Build/make commands here 
    echo 
    echo "--> Monitor: Monitoring filesystem... (Press enter to force a build/update)" 
} 

changed() { 
    echo "--> Monitor: Files changed, Building..." 
    build 
    previous_sha=$sha 
} 

compare() { 
    update_sha 
    if [[ $sha != $previous_sha ]] ; then changed; fi 
} 

run() { 
    while true; do 

     compare 

     read -s -t 1 && (
      echo "--> Monitor: Forced Update..." 
      build 
     ) 

    done 
} 

echo "--> Monitor: Init..." 
echo "--> Monitor: Monitoring filesystem... (Press enter to force a build/update)" 
run 
+9

đây là giải pháp khủng khiếp nhất. nó sẽ lấy tất cả các tập tin từ một thư mục mỗi giây mà là một hit hiệu suất rất lớn. hãy xem giải pháp của dennis williamson !!! – kritzikratzi

+2

Xin vui lòng loại bỏ các câu trả lời của bạn từ câu trả lời của tôi, họ là câu trả lời hợp lệ và công việc, chỉ vì họ không được chấp nhận cho việc sử dụng của bạn, họ đã được tốt cho tôi, và có thể những người khác là tốt. Như vậy downvoting có nghĩa là những người khác sẽ không thử câu trả lời này. Downvotes thực sự chỉ dành cho những thứ không hoạt động hoặc không có chủ đề ... Và cũng vui lòng chỉnh sửa bình luận của bạn để loại bỏ từ khủng khiếp, tùy chọn cá nhân của bạn, bạn được hoan nghênh nói rằng nó không đạt hiệu quả, nhưng hãy để nó tại đó. Chúc mừng. –

+4

Bởi vì một cái gì đó hoạt động không có nghĩa là nó là một ý tưởng tốt để làm điều đó. Theo tôi, câu trả lời của bạn cũng bình thường và có vấn đề. Tôi thấy không có lý do gì để loại bỏ nhược điểm của tôi. – kritzikratzi

5

từ khóa inotifywait & inotifywatch lệnh

14

Hãy xem incroninotify-tools.

+0

Cụ thể, hãy xem https://github.com/tartley/rerun2 sử dụng công cụ inotify và giúp dễ dàng chạy lệnh tùy chỉnh, như được giải thích trong câu trả lời bị bỏ qua của Jonathan Hartley về superuser (http://superuser.com/a/970780/60931) – nealmcb

5

Làm thế nào về kịch bản này? Sử dụng lệnh 'stat' để có được thời gian truy cập của một tập tin và chạy một lệnh bất cứ khi nào có sự thay đổi trong thời gian truy cập (bất cứ khi nào tập tin được truy cập).

#!/bin/bash 
while true 
do 
    ATIME=`stat -c %Z /path/to/the/file.txt` 
    if [[ "$ATIME" != "$LTIME" ]] 
    then 
     echo "RUN COMMNAD" 
     LTIME=$ATIME 
    fi 
    sleep 5 
done 
+0

Cảm ơn, một điểm tho, chỉ giám sát một tệp 'ATIME'. –

+2

Vâng, chúng tôi có thể sử dụng lệnh ** stat ** để truy cập/theo dõi thời gian truy cập DIR cũng: ** stat -c% Z/var/tmp ** kích hoạt tập lệnh bất cứ khi nào có thêm hoặc xóa trong DIR – VDR

+0

Tôi thực sự như sự đơn giản của giải pháp này. – Richard

2

Xem this dụ như một sự cải tiến khi về câu trả lời Ian Vaughan:

#!/usr/bin/env bash 
# script: watch 
# author: Mike Smullin <[email protected]> 
# license: GPLv3 
# description: 
# watches the given path for changes 
# and executes a given command when changes occur 
# usage: 
# watch <path> <cmd...> 
# 

path=$1 
shift 
cmd=$* 
sha=0 
update_sha() { 
    sha=`ls -lR --time-style=full-iso $path | sha1sum` 
} 
update_sha 
previous_sha=$sha 
build() { 
    echo -en " building...\n\n" 
    $cmd 
    echo -en "\n--> resumed watching." 
} 
compare() { 
    update_sha 
    if [[ $sha != $previous_sha ]] ; then 
    echo -n "change detected," 
    build 
    previous_sha=$sha 
    else 
    echo -n . 
    fi 
} 
trap build SIGINT 
trap exit SIGQUIT 

echo -e "--> Press Ctrl+C to force build, Ctrl+\\ to exit." 
echo -en "--> watching \"$path\"." 
while true; do 
    compare 
    sleep 1 
done 
2

Nếu bạn đã entr cài đặt, sau đó trong vỏ bạn có thể sử dụng cú pháp sau:

while true; do find src/ | entr -d make build; done 
Các vấn đề liên quan