当文件或目录发生变化时,如何运行 shell 脚本?

2024-10-14 08:40:00
admin
原创
74
摘要:问题描述:我想在特定文件或目录发生变化时运行 shell 脚本。我怎样才能轻松地做到这一点?解决方案 1:您可以尝试使用entr工具在文件更改时运行任意命令。文件示例:$ ls -d * | entr sh -c 'make && make test&...

问题描述:

我想在特定文件或目录发生变化时运行 shell 脚本。

我怎样才能轻松地做到这一点?


解决方案 1:

您可以尝试使用entr工具在文件更改时运行任意命令。文件示例:

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

或者:

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

或者在保存Changed!文件时打印:file.txt

$ echo file.txt | entr echo Changed!

对于目录使用-d,但您必须在循环中使用它,例如:

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

或者:

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

解决方案 2:

我使用这个脚本来对目录树中的更改运行构建脚本:

#!/bin/bash -eu
DIRECTORY_TO_OBSERVE="js"      # might want to change this
function block_for_change {
  inotifywait --recursive \n    --event modify,move,create,delete \n    $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

用途inotify-tools。查看inotifywait 手册页以了解如何自定义触发构建的操作。

解决方案 3:

使用inotify-tools。

链接的 Github 页面有许多示例;这里是其中之一。

#!/bin/sh

cwd=$(pwd)

inotifywait -mr \n  --timefmt '%d/%m/%y %H:%M' --format '%T %w %f' \n  -e close_write /tmp/test |
while read -r date time dir file; do
       changed_abs=${dir}${file}
       changed_rel=${changed_abs#"$cwd"/}

       rsync --progress --relative -vrae 'ssh -p 22' "$changed_rel" \n           usernam@example.com:/backup/root/dir && \n       echo "At ${time} on ${date}, file $changed_abs was backed up via rsync" >&2
done

解决方案 4:

这个脚本怎么样?使用“stat”命令获取文件的访问时间,并在访问时间发生变化时(每次访问文件时)运行命令。

#!/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

解决方案 5:

检查内核文件系统监视守护进程

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

以下是操作方法:

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

解决方案 6:

如上所述,inotify-tools 可能是最好的选择。但是,如果您编程只是为了好玩,您可以尝试明智地使用tail -f来获得黑客 XP 。

解决方案 7:

仅出于调试目的,当我编写 shell 脚本并希望它在保存时运行时,我使用以下命令:

#!/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

运行如下

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

编辑:以上是在 Ubuntu 12.04 上测试的,对于 Mac OS,将 ls 行更改为:

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

解决方案 8:

将以下内容添加到〜/.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
}

解决方案 9:

对于想要跟踪单个文件的 fish shell 用户的快速解决方案:

while true
    set old_hash $hash
    set hash (md5sum file_to_watch)
    if [ $hash != $old_hash ]
        command_to_execute
    end
    sleep 1
end

md5sum在 macos 上用if替换md5

解决方案 10:

这是另一个选择:http://fileschanged.sourceforge.net/

尤其请参阅“示例 4”,其中“监视目录并存档任何新的或更改的文件”。

解决方案 11:

inotifywait一定能满足你。

这是一个常见的示例:

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

解决方案 12:

假设您想要在rake test每次修改app/test/目录中的任何 ruby​​ 文件(“* .rb”)时运行。

只需获取所监视文件的最近修改时间并每秒检查一次该时间是否发生变化。

脚本代码

t_ref=0; while true; do t_curr=$(find app/ test/ -type f -name "*.rb" -printf "%T+
" | sort -r | head -n1); if [ $t_ref != $t_curr ]; then t_ref=$t_curr; rake test; fi; sleep 1; done

好处

  • 当文件发生变化时,您可以运行任何命令或脚本。

  • 它可以在任意文件系统和虚拟机(使用 Vagrant 在 VirtualBox 上共享文件夹)之间工作;因此,您可以在 Macbook 上使用文本编辑器并在 Ubuntu(虚拟盒)上运行测试。

警告

  • -printf选项在 Ubuntu 上运行良好,但在 MacOS 上不起作用。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用