26

是否有一个简单的解决方案(使用常见的 shell 实用程序,通过大多数发行版提供的实用程序,或一些简单的 python/... 脚本)在某些文件更改时重新启动进程?

简单地调用 sth like 会很好watch -cmd "./the_process -arg" deps/*

更新: 一个简单的 shell 脚本和建议的 inotify-tools (很好!)符合我的需要(适用于不带参数的命令):

#!/bin/sh
while true; do
  $@ &
  PID=$!
  inotifywait $1
  kill $PID
done
4

7 回答 7

19

是的,您可以通过inotify系统使用inotifywaitinotifywatchinotify-tools观看目录。

inotifywait将在检测到事件时退出。传递选项-r以递归方式监视目录。示例:inotifywait -r mydirectory

您还可以指定要观看的事件,而不是观看所有事件。要仅等待文件或目录内容更改,请使用 option -e modify

于 2012-09-04T13:14:15.760 回答
17

这是对问题中提供的答案的改进。当一个人中断脚本时,应该终止运行进程。

#!/bin/sh

sigint_handler()
{
  kill $PID
  exit
}

trap sigint_handler SIGINT

while true; do
  $@ &
  PID=$!
  inotifywait -e modify -e move -e create -e delete -e attrib -r `pwd`
  kill $PID
done
于 2016-01-08T08:58:17.393 回答
11

签出iWatch

Watch 是一个实时文件系统监控程序。它是一个检测文件系统变化并立即报告的工具。它使用 XML 格式的简单配置文件,基于 inotify,Linux 内核中的文件变化通知系统。

比,你可以轻松地观看文件:

iwatch /path/to/file -c 'run_you_script.sh'
于 2012-09-04T13:14:53.410 回答
7

我发现这非常适合 PO 要求的完整场景:

ls *.py | entr -r python my_main.py 

另请参阅http://eradman.com/entrproject/,尽管文档有些奇怪。是的,您需要ls匹配您想要匹配的文件模式,并将其通过管道传输到entr可执行文件中。它将运行您的程序并在任何匹配的文件更改时重新运行它。

于 2019-01-30T22:09:19.633 回答
1

我参与了一个 perl 脚本调用lrrr(真的是小重启运行器)。我每天在工作中使用它。

如果您安装了 perl 和 cpanm,则可以安装它cpanm App::lrrr,然后按如下方式使用它:

lrrr -w dirs,or_files,to-watch your_cmd_here

w 标志标记要监视的文件或目录。目前,如果文件更改,它会终止您运行的进程,但我将很快添加一个功能来切换它。

如果有什么要补充的请告诉我!

于 2020-02-03T17:49:56.590 回答
0

我使用这个“单线”根据文件更改重新启动长时间运行的进程

trap 'kill %1' 1 2 3 6; while : ; do YOUR_EXE & inotifywait -r YOUR_WATCHED_DIRECTORY -e create,delete,modify || break; kill %1; sleep 3; done

这将启动进程,将其输出保持到同一个控制台,观察变化,如果有变化,它将关闭进程,等待三秒钟(进一步在同一秒内写入或进程关闭时间),然后执行又是上述。
ctrl-c 和 ssh-disconnect 将受到尊重,完成后该过程将退出。

为了易读性:

trap 'kill %1' 1 2 3 6
while :
do
    YOUR_EXE &
    inotifywait \
        -r YOUR_WATCHED_DIRECTORY \
        -e create,delete,modify \
    || break
    kill %1
    sleep 3
done

例如对于 package.json-ran 项目

"module"          : "./dist/server.mjs",
"scripts"         : {
    "build"  : "cd ./src && rollup -c ",
    "watch"  : "cd ./src && rollup -c -w",
    "start"  : "cd ./dist && node --trace-warnings --enable-source-maps ./server.mjs",
    "test"   : "trap 'kill %1' 1 2 3 6; while : ; do npm run start & inotifywait -r ./dist -e create,delete,modify || break; kill %1; sleep 3; done"
},
"dependencies"    : {

现在,您可以在一个活动中运行npm run watch(从 src 编译到 dist),在另一个活动中运行npm run test(服务器运行器和重启程序),当您编辑./src文件时,构建器进程将更新./dist,服务器将重新启动以供您测试。

于 2021-08-11T06:35:42.423 回答
0

我需要一个生成子进程的 golanggo run命令的解决方案。所以结合上面的答案和pidtree给了我这个脚本。

#!/bin/bash

# go file to run
MAIN=cmd/example/main.go

# directories to recursively monitor
DIRS="cmd pkg"

# Based on pidtree from https://superuser.com/a/784102/524394
pidtree() {
  declare -A CHILDS
  while read P PP; do
    CHILDS[$PP]+=" $P"
  done < <(ps -e -o pid= -o ppid=)

  walk() {
    echo $1
    for i in ${CHILDS[$1]}; do
      walk $i
    done
  }

  for i in "$@"; do
    walk $i
  done
}

sigint_handler()
{
  kill $(pidtree $PID)
  exit
}

trap sigint_handler SIGINT

while true; do
  go run $MAIN &
  PID=$!
  inotifywait -e modify -e move -e create -e delete -e attrib -r $DIRS
  
  PIDS=$(pidtree $PID)
  kill $PIDS

  wait $PID
  sleep 1
done
于 2021-10-12T17:26:47.163 回答