DarkMatter in Cyberspace
  • Home
  • Categories
  • Tags
  • Archives

File Watcher on Linux


When writing the following Haskell script (saved in Main.hs),

module Main where

main :: IO ()
main = do
  input <- readFile "input.txt"
  print $ countWords input

-- Counts the number of words per line  
countWords input = map (length . words) (lines input)

I have to repeat the following process again and again:

  1. save the script file;

  2. run stack build --exec Code0101 or stack build && stack exec Code0101

  3. edit the file;

  4. back to step 1 ...

I need a tool to automate this process, and let me concentrate on coding.

ghcid

ndmitchell/ghcid can reload your script after file changed, and run script via the --test argument.

Install with stack install ghcid and open an editor in the left window, run ghcid --test "main" in the right window and that's all.

For a bare Haskell script (instead of files in a stack project), and a system level ghci is installed, you need start it with ghcid "--command=stack ghci solutions19.hs" --test main.

It is much faster than entr and watchman but only for Haskell.

See ghcid for the win! for details.

entr

entr is a tool running arbitrary commands when files change.

Download its source codes (entr-4.1.tar.gz) from its website, extract and install:

./configure
make test
sudo make install

Now open your editor in the left window, run ls *.hs | entr -r stack build --exec Code0101 in the right window and that's all.

With the -r option, you can press SPACE to terminate the current running command (here it's stack build and restart it immediately as if a file change event had occurred. See man entr for details.

Press q to quit the watcher.

See stack build --file-watch-post= for some examples for Haskell development.

The following scenario is running a PySpark project pv-current, which contains several Python scripts, on a remote host cdh1. You can copy the project folder onto cdh1, edit the scripts there. But the vim on cdh1 is very primitive. You can't comment/uncomment block codes, copy/paste from clipboard, ...

You can edit the file with your local vim with vi scp://cdh1/docs/pv-current/main.py. But when can want to edit another file, you have to quit the editor and run another command. Meanwhile you have no local copy of the modified version.

With entr you can easily edit the local files with all benefits of a local editor and sync them automatically to remote host once the file changes are saved: ls *.py | entr -c rsync -av *.py cdh1:~/docs/pypv

Here the rsync command runs quickly so there's no need to use -r option. The -c option clears the screen every time the command (rsync) is invoked.

Note: rsync must be installed on the remote server, or the rsync command will fail: rsync error: remote command not found (code 127).

watchman

watchman watch file changes and run some actions when watching file changes.

sudo apt install libtool
git clone https://github.com/facebook/watchman.git
cd  watchman
git checkout v4.9.0   # the latest stable release
./autogen.sh
./configure
make
sudo make install
pip install pywatchman

However watchman is very complicated. So there's a watchman-make shipped with watchman to make thing easier. Now it's incompatible with Python3, but you can fix it like this: search basestring in $(which watchman-make), and replace the line if isinstance(values, basestring): with:

if pywatchman.compat.PYTHON3:
    STRING_TYPES = (str, bytes)
else:
    STRING_TYPES = (str, unicode)
if isinstance(values, STRING_TYPES):

Run the following command in the project root folder: watchman-make -p '*.hs' --make='stack build && stack exec' -t 'Code0101' and open an editor. Now every time you change the *.hs file and save, stack will build and run.

But you have to delete the watch manually: watchman watch-del "/home/leo/docs/bookSourceCodes/Haskell-Data-Analysis-Cookbook"

Ref:

  • Installation of watchman

  • [watchman-make not working on python3](https://github.com/facebook/watchman/issues/631(

Note:

schell/steeloverseer is another candidate. But after I ran stack install steeloverseer on Ubuntu 16.04, the following error raised:

/tmp/stack11108/steeloverseer-2.0.2.0/app/Main.hs:258:5: error:
• The constructor ‘FSNotify.Added’ should have 3 arguments, but has been given 2
• In the pattern: FSNotify.Added path _
In a case alternative:
FSNotify.Added path _ -> S.yield (FileAdded (go cwd path))
In the second argument of ‘S.for’, namely
‘(\case
FSNotify.Added path _ -> S.yield (FileAdded (go cwd path))
FSNotify.Modified path _ -> S.yield (FileModified (go cwd path))
FSNotify.Removed _ _ -> pure ())’
|
258 | FSNotify.Added path _ -> S.yield (FileAdded (go cwd path))
| ^^^^^^^^^^^^^^^^^^^^^^^^

Looks like API incompatible.

inotify

See note "两台 Linux 主机上文件夹间远程同步" for details.

watchdog

Watchdog is a Python library.



Published

Sep 7, 2018

Last Updated

Feb 19, 2020

Category

Tech

Tags

  • ubuntu 61
  • watchman 1

Contact

  • Powered by Pelican. Theme: Elegant by Talha Mansoor