Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fswatch command fires multiple events for a single move operation #312

Open
unlocked2412 opened this issue Jun 1, 2023 · 4 comments
Open

Comments

@unlocked2412
Copy link

Hello, and thank you for this amazing tool

I have a photos.sh file (osascript set to JavaScript):

#!/usr/bin/osascript -l JavaScript

function run(argv) {
    return importFileIntoPhotos(argv[0])
};

// importFileIntoPhotos :: FilePath -> IO ()
const importFileIntoPhotos = fp => {
    const 
        appPhotos = Application("Photos");
    return appPhotos.import([Path(fp)])
};

and, the following test.sh file:

#!/bin/zsh

fp="$HOME/Documents/Samsung T5"

fpScript="$HOME/Library/CloudStorage/Dropbox/VSC Files/Automation/Manuel/photos.sh"

fswatch -0 -event-flags -r --exclude=".*\.DS_Store" "$fp" | xargs -0 -n1 -r -I {} "$fpScript" "{}"

I execute test.sh in Terminal. With that process open, whenever I move a single photo into fp folder, the same photo is imported multiple times into ​Photos​ app. Then, I have to kill the process.

Do you know how can I fix this issue, and import a single photo corresponding to a single move operation ? Is there something wrong with my code ?

Specs:

MacBook Air M1 with macOS Ventura

@unlocked2412
Copy link
Author

UPDATE:

Upon further testing, I have more clarity about the issue. Whenever the file is imported into Photos, a new event is sent (and captured) by fswatch, so it gets triggered again.

@unlocked2412
Copy link
Author

Now, the act of importing into Photos doesn't trigger an event that could be captured by fswatch, and also doesn't trigger duplicated events. Not sure what happened. I am closing this issue.

@unlocked2412
Copy link
Author

I am reopening the issue because the problem persists. I tried with Preview app, and I get duplicated events again.

@tgill880
Copy link

tgill880 commented Feb 1, 2024

I have encountered something similar. Here is what I found.

System: MacBook Air M1, Sonoma 14.2.1
fswatch --version: fswatch 1.17.1

We want a file path whenever a file is created in the watch folder.

Here is a dirt simple script that shows we are getting the file paths we want.

#! /bin/zsh

FOLDER=$1
echo "monitoring $FOLDER"

# Using fswatch to monitor the folder for changes.
fswatch "$FOLDER" | while read FILE
do
  echo "file: $FILE"
done

Execute the script.

./watch.sh watch_folder

In another terminal, drop some files, delete them, create and remove a directory.

cp test.png watch_folder
cp test.png watch_folder/test2.png
rm watch_folder/*
mkdir watch_folder/test
rmdir watch_folder/test

Output

monitoring watch_folder
file: /Users/Joe/Projects/LATscan/watch_folder/test.png
file: /Users/Joe/Projects/LATscan/watch_folder/test2.png
file: /Users/Joe/Projects/LATscan/watch_folder/test.png
file: /Users/Joe/Projects/LATscan/watch_folder/test2.png
file: /Users/Joe/Projects/LATscan/watch_folder/test
file: /Users/Joe/Projects/LATscan/watch_folder/test

Good news! We are getting the file paths we want. The other paths (from removing files, directory stuff) can be filtered out with an event mask and/or filtering.

Now let's open these image files with the default application (Preview). Add this line below the echo command in the loop.
open "$FILE" &

Copy one file into our watch_folder.

 $ ./watch.sh watch_folder
monitoring watch_folder
file: /Users/Joe/Projects/LATscan/watch_folder/test.png
file: /Users/Joe/Projects/LATscan/watch_folder/test.png
file: /Users/Joe/Projects/LATscan/watch_folder/test.png
file: /Users/Joe/Projects/LATscan/watch_folder/test.png
file: /Users/Joe/Projects/LATscan/watch_folder/test.png
file: /Users/Joe/Projects/LATscan/watch_folder/test.png
file: /Users/Joe/Projects/LATscan/watch_folder/test.png
file: /Users/Joe/Projects/LATscan/watch_folder/test.png
^C

Boom. Although only one image is opened by Preview, the script loops until we abort it (similar to the OP). I tried various combinations of the open command, and substituted ImageJ.app, with the same results.
open -a ImageJ.app "$FILE" &

What DOES work is viewing the image with the ImageMagick display command.
Replace the open line with this:
magick "$FILE" - | display - &
Now multiple images display in an XQuartz (X11) window, without the runaway loop.

NOTE: To use display, download the macOS binaries from ImageMagick.org, and don't use the version installed with brew. Also, install XQuartz if it's not on your system.

For the next tests, I just looked at the raw fswatch output to stdout with different monitors.

For the queue_monitor, the file paths were outputted without the file name.

$ fswatch -m queue_monitor watch_folder
/Users/Joe/Projects/LATscan/watch_folder
/Users/Joe/Projects/LATscan/watch_folder
/Users/Joe/Projects/LATscan/watch_folder

For the poll_monitor, no output at stdout.

$ fswatch -m poll_monitor
[no output]

Summary

  • On the Apple Silicon Macs, some combinations of the default fsevents_monitor with other system calls can cause a runaway loop (as observed by the OP).
  • The kqueue_monitor and poll_monitor do not seem to work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants