有没有比“手表制造”更明智的替代方案?

发布于 2024-12-06 10:37:45 字数 239 浏览 0 评论 0 原文

我遇到了这个有用的提示,如果您经常处理文件并且希望它们自动构建,您可以运行:

watch make

每隔几秒它就会重新运行 make 并构建东西。

然而……它似乎一直在吞噬所有的输出。我认为它可能更聪明 - 也许显示输出流,但抑制“全部”不做任何事情,这样如果没有构建任何内容,输出就不会滚动。

我想到了一些使用循环和 grep 的 shell 脚本方法……但也许有更优雅的东西?有人看到过什么吗?

I ran into this useful tip that if you're working on files a lot and you want them to build automatically you run:

watch make

And it re-runs make every couple seconds and things get built.

However ... it seems to swallow all the output all the time. I think it could be smarter - perhaps show a stream of output but suppress Nothing to be done for 'all' so that if nothing is built the output doesn't scroll.

A few shell script approaches come to mind using a loop and grep ... but perhaps something more elegant is out there? Has anyone seen something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

依 靠 2024-12-13 10:37:45

使用经典的 gnu makeinotifywait,无需基于间隔的轮询:

watch:
    while true; do \
        $(MAKE) $(WATCHMAKE); \
        inotifywait -qre close_write .; \
    done

这种方式会在当前目录树中的每个文件写入时触发 make。您可以通过运行来指定目标

make watch WATCHMAKE=foo

Using classic gnu make and inotifywait, without interval-based polling:

watch:
    while true; do \
        $(MAKE) $(WATCHMAKE); \
        inotifywait -qre close_write .; \
    done

This way make is triggered on every file write in the current directory tree. You can specify the target by running

make watch WATCHMAKE=foo
我偏爱纯白色 2024-12-13 10:37:45

这是一句:

while true; do make -q || make; sleep 0.5; done

使用 make -q || make 而不仅仅是 make 只会在有需要完成的事情时运行构建,否则不会输出任何消息。

您可以将其作为规则添加到项目的 Makefile 中:

watch:
    while true; do $(MAKE) -q || $(MAKE); sleep 0.5; done

然后使用 make watch 调用它。

此技术将阻止 Make 向终端填充“make:无需为 TARGET 执行任何操作”消息。

它也不会像某些文件观察器解决方案那样保留一堆打开的文件描述符,这可能会导致 ulimit 错误。

Here is a one-liner:

while true; do make -q || make; sleep 0.5; done

Using make -q || make instead of just make will only run the build if there is something to be done and will not output any messages otherwise.

You can add this as a rule to your project's Makefile:

watch:
    while true; do $(MAKE) -q || $(MAKE); sleep 0.5; done

And then use make watch to invoke it.

This technique will prevent Make from filling a terminal with "make: Nothing to be done for TARGET" messages.

It also does not retain a bunch of open file descriptors like some file-watcher solutions, which can lead to ulimit errors.

鹿港小镇 2024-12-13 10:37:45

这个单行代码应该可以做到这一点:

while true; do make --silent; sleep 1; done

它将每秒运行一次 make ,并且只有在实际执行某些操作时才会打印输出。

This one-liner should do it:

while true; do make --silent; sleep 1; done

It'll run make once every second, and it will only print output when it actually does something.

挽你眉间 2024-12-13 10:37:45

怎么样

# In the makefile:
.PHONY: continuously
continuously:
    while true; do make 1>/dev/null; sleep 3; done  

这样你就可以运行

连续制作

,只有在出现问题时才得到输出。

How about

# In the makefile:
.PHONY: continuously
continuously:
    while true; do make 1>/dev/null; sleep 3; done  

?

This way you can run

make continuously

and only get output if something is wrong.

離人涙 2024-12-13 10:37:45

Twitter Bootstrap 为此使用 watchr ruby​​ gem。

https://github.com/twbs/bootstrap/blob/v2.3.2/ Makefile

https://github.com/mynyml/watchr

编辑:

两年后,watchr 项目似乎不再被维护了。请在答案中寻找其他解决方案。就个人而言,如果目标只是获得更好的输出,我会推荐此处的wch答案

Twitter Bootstrap uses the watchr ruby gem for this.

https://github.com/twbs/bootstrap/blob/v2.3.2/Makefile

https://github.com/mynyml/watchr

Edit:

After two years the watchr project seems not to be maintained anymore. Please look for another solution among the answers. Personally, if the goal is only to have a better output, i would recommend the answer from wch here

櫻之舞 2024-12-13 10:37:45

此 shell 脚本使用 make 本身来检测带有 -q 标志的更改,然后当且仅当有更改时才进行完全重建。

#!/bin/sh

while true;
do
  if ! make -q "$@";
  then
    echo "#-> Starting build: `date`"
    make "$@";
    echo "#-> Build complete."
  fi
  sleep 0.5;
done
  • 除了 make 之外,它没有任何依赖项。

  • 您可以将普通的 make 参数(例如 -C mydir)传递给它,就像它们传递给 make 命令一样。< /p>

  • 按照问题中的要求,如果没有任何要构建的内容,它会保持沉默,但在有输出

  • 您可以将此脚本放在方便的地方,例如 ~/bin/watch-make 以便在多个项目中使用。

This shell script uses make itself to detect changes with the -q flag, and then does a full rebuild if and only if there are changes.

#!/bin/sh

while true;
do
  if ! make -q "$@";
  then
    echo "#-> Starting build: `date`"
    make "$@";
    echo "#-> Build complete."
  fi
  sleep 0.5;
done
  • It does not have any dependencies apart from make.

  • You can pass normal make arguments (such as -C mydir) to it as they are passed on to the make command.

  • As requested in the question it is silent if there is nothing to build but does not swallow output when there is.

  • You can keep this script handy as e.g. ~/bin/watch-make to use across multiple projects.

马蹄踏│碎落叶 2024-12-13 10:37:45

我在 Makefile 中这样做:

watch:
    (while true; do make build.log; sleep 1; done) | grep -v 'make\[1\]'

build.log: ./src/*
    thecompiler | tee build.log

因此,只有当我的源代码比 build.log 更新时,它才会构建,并且“grep -v”内容会删除一些不必要的 make 输出。

I do it this way in my Makefile:

watch:
    (while true; do make build.log; sleep 1; done) | grep -v 'make\[1\]'

build.log: ./src/*
    thecompiler | tee build.log

So, it will only build when my source code is newer than my build.log, and the "grep -v" stuff removes some unnecessary make output.

执笏见 2024-12-13 10:37:45

有几个自动构建系统可以执行此操作以及更多操作 - 基本上,当您检查版本控制的更改时,它们将进行/构建 - 寻找持续集成

简单的系统是 TeamCityHudson

There are several automatic build systems that do this and more - basically when you check a change into version control they will make/build - look for Continuous Integration

Simple ones are TeamCity and Hudson

dawn曙光 2024-12-13 10:37:45

@Dobes Vandermeer - 我有一个名为“mkall”的脚本,它在每个子目录中运行 make 。我可以将该脚本分配为 cron 作业,每五分钟、一分钟或三十秒运行一次。然后,为了查看输出,我将 gcc 结果(在每个单独的 makefile 中)重定向到每个子目录中的日志。

类似的东西对你有用吗?

它可以非常复杂,以避免不执行任何操作。例如,脚本可以保存每个源文件的修改时间,并在该人更改时执行 make。

@Dobes Vandermeer -- I have a script named "mkall" that runs make in every subdirectory. I could assign that script as a cron job to run every five minutes, or one minute, or thirty seconds. Then, to see the output, I'd redirect gcc results (in each individual makefile) to a log in each subdirectory.

Could something like that work for you?

It could be pretty elaborate so as to avoid makes that do nothing. For example, the script could save the modify time of each source file and do the make when that guy changes.

夏了南城 2024-12-13 10:37:45

您可以尝试使用 inotify-tools 之类的东西。它可以让您监视目录并在文件更改或保存或 inotify 可以监视的任何其他事件时运行命令。一个简单的脚本可以监视保存并在保存文件时启动 make 可能会很有用。

You could try using something like inotify-tools. It will let you watch a directory and run a command when a file is changed or saved or any of the other events that inotify can watch for. A simple script that does a watch for save and kicks off a make when a file is saved would probably be useful.

何以心动 2024-12-13 10:37:45

您可以更改 make 文件以输出 growl (OS X) 或 growl (OS X) 或 notify-send (Linux) 通知。对于使用 Ubuntu 的我来说,这会在屏幕的右上角显示一个通知气泡。

然后,您只会在构建失败时才会注意到它。

您可能希望将 watch 设置为仅按照这些通知显示的速度循环(这样它们就不会堆积起来)。

You could change your make file to output a growl (OS X) or notify-send (Linux) notification. For me in Ubuntu, that would show a notification bubble in the upper-right corner of my screen.

Then you'd only notice the build when it fails.

You'd probably want to set watch to only cycle as fast as those notifications can display (so they don't pile up).

彼岸花ソ最美的依靠 2024-12-13 10:37:45

有点考古学,但我仍然发现这个问题很有用。这是 @otto 答案的修改版本,使用 fswatch (适用于 Mac):

TARGET ?= foo

all:
    @fswatch -1 . | read i && make $(TARGET)
    @make -ski TARGET=$(TARGET)

%: %.go
    @go build 
lt;
    @./$@

Bit of archaeology, but I still find this question useful. Here is a modified version of @otto's answer, using fswatch (for the mac):

TARGET ?= foo

all:
    @fswatch -1 . | read i && make $(TARGET)
    @make -ski TARGET=$(TARGET)

%: %.go
    @go build 
lt;
    @./$@
薆情海 2024-12-13 10:37:45

这是我编写的一个快速脚本,它执行所要求的操作:watchmake。它基于 inotify(因此只能在 Linux 上运行),用于监听给定文件的更改。

usage: watchmake [-h] [-e EXTENSIONS] [-q] [-i IGNORE] [-m MAKE_CMD]
                 [files ...]

Watch files and make on changes

positional arguments:
  files                 Files or directories to watch. Defaults to current
                        directory

options:
  -h, --help            show this help message and exit
  -e EXTENSIONS, --ext EXTENSIONS
                        Only watch files with this extension
  -q, --quiet           Run quietly
  -i IGNORE, --ignore IGNORE
                        Ignore files or folders. Use a leading "/" to denote
                        files at the top level. Globs not supported
  -m MAKE_CMD, --make-cmd MAKE_CMD
                        Define command to run upon modification of files.
                        Defaults to `make`. You may use {} in the command and
                        it will be replace by the changed file

Here is a quick script I wrote that does what is asked: watchmake. It is based on inotify (so only runs on linux), with which it listens for changes on given files.

usage: watchmake [-h] [-e EXTENSIONS] [-q] [-i IGNORE] [-m MAKE_CMD]
                 [files ...]

Watch files and make on changes

positional arguments:
  files                 Files or directories to watch. Defaults to current
                        directory

options:
  -h, --help            show this help message and exit
  -e EXTENSIONS, --ext EXTENSIONS
                        Only watch files with this extension
  -q, --quiet           Run quietly
  -i IGNORE, --ignore IGNORE
                        Ignore files or folders. Use a leading "/" to denote
                        files at the top level. Globs not supported
  -m MAKE_CMD, --make-cmd MAKE_CMD
                        Define command to run upon modification of files.
                        Defaults to `make`. You may use {} in the command and
                        it will be replace by the changed file
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文