Baike.dev
All toolsOnline toolsAI codingTrendingOpen sourceNewsSubmit
Log in
< Back to tools
L

listen

> 编程语言
Open source

The Listen gem listens to file modifications and notifies you about the changes.

2.0K stars0 likes3 views
WebsiteGitHub

About

The Listen gem listens to file modifications and notifies you about the changes.

Listen

The listen gem listens to file modifications and notifies you about the changes.

Features

  • OS-optimized adapters on MRI for Mac OS X 10.6+, Linux, *BSD and Windows, more info below.
  • Detects file modification, addition and removal.
  • You can watch multiple directories.
  • Regexp-patterns for ignoring paths for more accuracy and speed
  • Increased change detection accuracy on OS X HFS and VFAT volumes.
  • Continuous Integration: tested on selected Ruby environments via Github Workflows.

Issues / limitations

  • Limited support for symlinked directories (#279):
    • Symlinks are always followed (#25).
    • Symlinked directories pointing within a watched directory are not supported (#273.
  • No directory/adapter-specific configuration options.
  • Support for plugins planned for future.
  • TCP functionality was removed in listen 3.0.0 (#319, #218). There are plans to extract this feature to separate gems (#258), until this is finished, you can use by locking the listen gem to version '~> 2.10'.
  • Some filesystems won't work without polling (VM/Vagrant Shared folders, NFS, Samba, sshfs, etc.).
  • Windows and *BSD adapter aren't continuously and automatically tested.
  • OSX adapter has some performance limitations (#342).
  • Listeners do not notify across forked processes, if you wish for multiple processes to receive change notifications you must listen inside of each process.

Pull requests or help is very welcome for these.

Install

The simplest way to install listen is to use Bundler.

ruby
gem 'listen'

Complete Example

Here is a complete example of using the listen gem:

ruby
require 'listen'

listener = Listen.to('/srv/app') do |modified, added, removed|
  puts(modified: modified, added: added, removed: removed)
end
listener.start
sleep

Running the above in the background, you can see the callback block being called in response to each command:

…

Usage

Call Listen.to with one or more directories and the "changes" callback passed as a block.

ruby
listener = Listen.to('dir/to/listen', 'dir/to/listen2') do |modified, added, removed|
  puts "modified absolute path array: #{modified}"
  puts "added absolute path array: #{added}"
  puts "removed absolute path array: #{removed}"
end
listener.start # starts a listener thread--does not block

# do whatever you want here...just don't exit the process :)

sleep

Changes Callback

Changes to the listened-to directories are reported by the listener thread in a callback. The callback receives three array parameters: modified, added and removed, in that order. Each of these three is always an array with 0 or more entries. Each array entry is an absolute path.

Pause / start / stop

Listeners can also be easily paused and later un-paused with start:

ruby
listener = Listen.to('dir/path/to/listen') { |modified, added, removed| puts 'handle changes here...' }

listener.start
listener.paused?     # => false
listener.processing? # => true

listener.pause       # stops processing changes (but keeps on collecting them)
listener.paused?     # => true
listener.processing? # => false

listener.start       # resumes processing changes
listener.stop        # stop both listening to changes and processing them

Note: While paused, listen keeps on collecting changes in the background - to clear them, call stop.

Note: You should keep track of all started listeners and stop them properly on finish.

Ignore / ignore!

Listen ignores some directories and extensions by default (See DEFAULT_IGNORED_FILES and DEFAULT_IGNORED_EXTENSIONS in Listen::Silencer). You can add ignoring patterns with the ignore option/method or overwrite default with ignore! option/method.

ruby
listener = Listen.to('dir/path/to/listen', ignore: /\.txt/) { |modified, added, removed| # ... }
listener.start
listener.ignore! /\.pkg/ # overwrite all patterns and only ignore pkg extension.
listener.ignore /\.rb/   # ignore rb extension in addition of pkg.
sleep

Note: :ignore regexp patterns are evaluated against relative paths.

Note: Ignoring paths does not improve performance, except when Polling (#274).

Only

Listen watches all files (less the ignored ones) by default. If you want to only listen to a specific type of file (i.e., just .rb extension), you should use the only option/method.

ruby
listener = Listen.to('dir/path/to/listen', only: /\.rb$/) { |modified, added, removed| # ... }
listener.start
listener.only /_spec\.rb$/ # overwrite all existing only patterns.
sleep

Note: :only regexp patterns are evaluated only against relative file paths.

Options

All the following options can be set through the Listen.to after the directory path(s) params.

…

Logging and Debugging

Listen logs its activity to Listen.logger. This is the primary method of debugging.

Custom Logger

You can call Listen.logger = to set a custom listen logger for the process. For example:

ruby
Listen.logger = Rails.logger

Default Logger

If no custom logger is set, a default listen logger which logs to to STDERR will be created and assigned to Listen.logger.

The default logger defaults to the error logging level (severity). You can override the logging level by setting the environment variable LISTEN_GEM_DEBUGGING=<level>. For <level>, all standard ::Logger levels are supported, with any mix of upper-/lower-case:

ruby
export LISTEN_GEM_DEBUGGING=debug # or 2 [deprecated]
export LISTEN_GEM_DEBUGGING=info  # or 1 or true or yes [deprecated]
export LISTEN_GEM_DEBUGGING=warn
export LISTEN_GEM_DEBUGGING=fatal
export LISTEN_GEM_DEBUGGING=error

The default of error will be used if an unsupported value is set.

Note: The alternate values 1, 2, true and yes shown above are deprecated and will be removed from listen v4.0.

Disabling Logging

If you want to disable listen logging, set

ruby
Listen.logger = ::Logger.new('/dev/null')

Adapter Warnings

If listen is having trouble with the underlying adapter, it will display warnings with Kernel#warn by default, which in turn writes to STDERR. Sometimes this is not desirable, for example in an environment where STDERR is ignored. For these reasons, the behavior can be configured using Listen.adapter_warn_behavior =:

ruby
Listen.adapter_warn_behavior = :warn   # default (true means the same)
Listen.adapter_warn_behavior = :log    # send to logger.warn
Listen.adapter_warn_behavior = :silent # suppress all adapter warnings (nil or false mean the same)

Also there are some cases where specific warnings are not helpful. For example, if you are using the polling adapter--and expect to--you can suppress the warning about it by providing a callable object like a lambda or proc that determines the behavior based on the message:

ruby
Listen.adapter_warn_behavior = ->(message) do
  case message
  when /Listen will be polling for changes/
    :silent
  when /directory is already being watched/
    :log
  else
    :warn
  end
end

In cases where the Listen gem is embedded inside another service--such as guard--the above configuration can be set in the environment variable LISTEN_GEM_ADAPTER_WARN_BEHAVIOR=warn|log|silent.

Listen Adapters

The Listen gem has a set of adapters to notify it when there are changes.

There are 4 OS-specific adapters to support Darwin, Linux, *BSD and Windows. These adapters are fast as they use some system-calls to implement the notifying function.

There is also a polling adapter - although it's much slower than other adapters, it works on every platform/system and scenario (including network filesystems such as VM shared folders).

The Darwin and Linux adapters are dependencies of the listen gem so they work out of the box. For other adapters a specific gem will have to be added to your Gemfile, please read below.

The listen gem will choose the best adapter automatically, if present. If you want to force the use of the polling adapter, use the :force_polling option while initializing the listener.

On Windows

If you are on Windows, it's recommended to use the wdm adapter instead of polling.

Please add the following to your Gemfile:

ruby
gem 'wdm', '>= 0.1.0'

On *BSD

If you are on *BSD you can try to use the rb-kqueue adapter instead of polling.

Please add the following to your Gemfile:

ruby
gem 'rb-kqueue', '>= 0.2'

Getting the polling fallback message?

If you see:

Listen will be polling for changes.

This means the Listen gem can’t find an optimized adapter. Typically this is caused by:

  • You’re on Windows and WDM gem isn’t installed.
  • You’re running the app without Bundler or RubyGems.
  • Using Sass which includes an ancient (the “dinosaur” type of ancient) version of the Listen gem.

Possible solutions:

  1. Suppress the message by using the :force_polling option. Or, you could just ignore the message since it’s harmless.
  2. Windows users: Install the WDM gem.
  3. Upgrade Ruby (use RubyInstaller for Windows or RVM/rbenv for Mac) and RubyGems.
  4. Run your apps using Bundler.
  5. Sass users: Install the latest version of Listen and try again.

Simplified Bundler and Sass example

Create a Gemfile with these lines:

source 'https://rubygems.org'
gem 'listen'
gem 'sass'

Next, use Bundler to update gems:

$ bundle update
$ bundle exec sass --watch # ... or whatever app is using Listen.

Increasing the amount of inotify watchers

If you are running Debian, RedHat, or another similar Linux distribution, run the following in a terminal:

$ sudo sh -c "echo fs.inotify.max_user_watches=524288 >> /etc/sysctl.conf"
$ sudo sysctl -p

If you are running ArchLinux, search the /etc/sysctl.d/ directory for config files with the setting:

$ grep -H -s "fs.inotify.max_user_watches" /etc/sysctl.d/*
/etc/sysctl.d/40-max_user_watches.conf:fs.inotify.max_user_watches=100000

Then change the setting in the file you found above to a higher value (see here for why):

$ sudo sh -c "echo fs.inotify.max_user_watches=524288 > /etc/sysctl.d/40-max-user-watches.conf"
$ sudo sysctl --system

The technical details

Listen uses inotify by default on Linux to monitor directories for changes. It's not uncommon to encounter a system limit on the number of files you can monitor. For example, Ubuntu Lucid's (64bit) inotify limit is set to 8192.

You can get your current inotify file watch limit by executing:

$ cat /proc/sys/fs/inotify/max_user_watches

When this limit is not enough to monitor all files inside a directory, the limit must be increased for Listen to work properly.

You can set a new limit temporarily with:

$ sudo sysctl fs.inotify.max_user_watches=524288
$ sudo sysctl -p

If you like to make your limit permanent, use:

$ sudo sh -c "echo fs.inotify.max_user_watches=524288 >> /etc/sysctl.conf"
$ sudo sysctl -p

You may also need to pay attention to the values of max_queued_events and max_user_instances if Listen keeps on complaining.

While 524,288 is the maximum number of files that can be watched. Each file watch [takes up 1,080 bytes](https://stackover

Issues· 0 open

View all issuesOpen on GitHub

No open issues yet, or sync has not completed.

> Tags

Ruby

No comments yet. Be the first to share.

> Details

PublishedAug 1, 2026
UpdatedSep 17, 2026
Category编程语言
PricingOpen source

> Related tools

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言