joh / when-changed Goto Github PK
View Code? Open in Web Editor NEWExecute a command when a file is changed
License: Other
Execute a command when a file is changed
License: Other
If I set it to run a command when a text document is changed, for example, if I save changes to that text document in gedit, when-changed
executes the command 3 times. Is this a bug in the way that gedit saves things, or in when-changed
?
when-changed isn't working on a NFS mounted directory, after reading through this I suppose watchdog observers are not notifying about the file changes. Just an FYI, if you may add this to notify users on README or help, might help instead of researching.
I'm just beginning to investigate this, so I'd never heard of the program 'watchdog' (mentioned in README) before. Google can't help me, because the word is so common.
What am I supposed to install before I try to run this?
Since the project uses pyinotify to listen on changes, it is no longer able to do the job in case of Windows OS. Also, It does not work on Linux Guest OS under Windows host in VirtualBox when you are polling files shared with vboxsf module. Codebase is small thus anyone could adjust it a bit to do own job without learning something bigger like http://pythonhosted.org/watchdog/. So far it was very platform-independent. I think kind of fallback would be nice.
Some probably relevant info
$ pip show when-changed
---
Name: when-changed
Version: 0.3.0
Location: /usr/local/lib/python2.7/dist-packages
Requires: watchdog
Both the host and guest OSes are debian Jessie.
Even though When-Changed allows you to monitor directories, it does not allow to run commands over a directory
Mac-Pro-de-Luis:~ luis$ when-changed -[vr1s] "MyDirectory" do shell script "sudo chmod -R 766 " & "/Users/Luis/Documents/Videos Chiapas" password MyPassword with administrator privileges
[6] 1327
-bash: /Users/Luis/Documents/Videos Chiapas: is a directory
Vim's swap files can be more than just .swp and .swx:
- If this file already exists (e.g., when you are recovering from a crash) a
warning is given and another extension is used, ".swo", ".swn", etc.
I'm watching a directory of files under OS X 10.10.5, with the latest when-changed and watchdog version 0.8.3. Changing individual files works just fine, but when changing more than one file at a time, only one of the file changes is reported.
I'm happy to give additional details or do tests as requested.
Edit: further info; the changes can be separated by a second or two, and still only the first one is recognized. It looks like all subsequent changes are ignored from when a file is changed until when-changed has finished executing the resulting change command (which in my case takes a few seconds).
I'd like to kill the currently running command and kick off a fresh one if a file changes. This is in constast with -l which just doesn't execute a second command.
Hi there,
I see when-changed got released to PyPI but only as a tarball:
https://pypi.org/project/when-changed/#files
Python wheels are the current standard for packaging pip packages and it will take you seconds to build one.
Could you upload a wheel (.whl) please? All you need to do is python setup.py bdist_wheel
and it'll make a .whl file instead of a .tar.gz file. (If you get errors, pip install wheel
and try again.)
If you upload directly from commandline then instead of python setup.py sdist upload
you do python setup.py sdist bdist_wheel upload
. There's not much more to it.
See, when pip installs a package if there is no wheel, it goes and builds one. This involves downloading the tarball, extracting it, generating a wheel internally, copying it to the local pip wheel cache and then deploying it from there. By serving a wheel to begin with, you save a lot of processing as it pretty much just drops in. (This may sound minor but if you're redeploying pip packages frequently, those saved seconds add up!)
You can read more about wheels in the docs:
https://wheel.readthedocs.io/en/stable/user_guide.html#building-wheels
If you're confident your code runs in Python 2 and 3, then you can read more about building a "universal" wheel, which will target both. Else it will be a wheel for the main version that you build with (ie, build in Python 2 and it makes a py2 wheel, build in Python 3 and it makes a py3 wheel.)
Thank you!
When you pip install when-changed
you don't get a working tool, because it doesn't specify that it depends on pyinotify
.
Adding a install_requires=['pyinotify']
to setup()
(and importing the setup
function from setuptools
instead of distutils.core
) would fix this.
Hello, can this script support wildcard character like
when-change *.tex -c pdflatex main.tex
My main.tex
include multiple sub tex file, how can I make main.tex
compile when any tex file in the directory get changed.
Thanks
is it possible to get the changes made to the file as an argument to the command?
Using vim as text editor makes saving (:w
) text files trigger two events in a row (almost simultaneously), causing the command to be executed twice. It might be complicated to avoid this, and the file might be actually being written twice, so a suggestion would be to have an option to set a minimum delay to accept a new event after just triggering one.
One example of this is watching .css
and .js
files then running gulp
when one of the files change, but gulp gets executed twice in a row after a single change in one of the files. I tested this in a single text file and it has the same behaviour, two events fired in a row. This happens when using vim, doesn't happen with Sublime Text or nano.
To test this:
touch myfile
# this prints the current system time in milliseconds when myfile is changed
when-changed myfile "echo $(($(date +%s%N)/1000000))"
# in another terminal
vim myfile
[do some change and save it by using :w]
[check the events, you'll see two events triggered in the same millisecond]
An idea is to have a flag to set a minimal delay for accepting a new event. So for example, if the delay is set to 1ms and the above case happens, we got two events being triggered but the second one is ignored because it triggered too fast (before first event + delay
).
Again, this happens when saving a file in vim. Doesn't happen in Sublime Text and nano. Other editors have to be tested.
This delay could also useful in many other scenarios, in which you don't want to run the command two times in a row just because the file changed too fast.
Or maybe have support for something like an event queue (and avoid ignoring events triggered) with a minimal delay between each trigger.
While trying to figure out what -r does, I found that when-changed
behaves recursively, even if you specify a directory without using -r.
As long as this is the case, can we get rid of -r and just make it the default?
WhenChanged.__init__
will automatically pass the recursive argument to watchdog.observers.Observer
. However, -r will still matter in WhenChanged.is_interested
, which is used by WhenChanged.on_change
.
So either the setting is not exactly necessary, or I am misunderstanding its purpose.
Example: when-changed *.tex xelatex %f
Hello,
I cannot stop it making prints to stdout or stderr.
Could there be an option for that, please?
Thanks.
Hi,
the following code taken from the on_created
event handler:
if self.observer.__class__.__name__ == 'InotifyObserver':
# inotify also generates modified events for created files
return
prevents the on_change
method to be called on on_created
events.
This appears more as a semantic issue as the on_modified
handler seems to do the job for now.
But just partially in fact, because this is the source of the issue #68.
And it would take more importance regarding the issue #58 which implies to distinguish event types.
I think being able to propose an alternative soon.
best regards
creating of a new file triggers the action, so it makes sense that deleting a file would do that also.
Can I monitor specific file type like "*.py' in a directory?
I monitor a folder for new files . These files are not copied there , but moved from other places .
The tool cannot understand these moved files . I tried the -r option , tried to make a second folder inside the folder I monitor , but it doesn't work .
If I copy files it's OK . Problem is that the tools that produce the files are moving them , not copying them.
It runs command twice after my file has changed. In file test.js i have:
console.log('Hello world!');
and after setting when-changed like this:
when-changed test.js node test.js
I get node called twice. Maybe it's worth to mention that I have Python3 as my main Python interpreter.
Hi!
Thank you for a good work so far!
I have an issue though... I'm running Ubuntu 16.04 and when-changed sometimes executes my command two times when run like so:
when-changed * -c ./pushGit.sh
pushGit.sh:
#!/bin/bash
git commit -am 'save'
git push
Thanks again and have a nice day!
when-changed
has the extremely user friendly behavior of continuing to watch when a file is deleted and replaced. However, this does not hold if the file's directory is deleted or replaced.
If this is not feasible, raising an error would also be helpful.
So that I can install when-changed with 'pip install whenchanged' :).
Hi,
this refers to this message: #77 (comment)
As some behaviors may differ from a platform to another, it would be great to add a bunch of tests to guarantee that the when-changed
behaviors are the expected ones.
The expected behaviors are the following:
When watching directory:
When watching a file:
I am new with this:
I am getting this error:
$ pip install https://github.com/joh/when-changed/archive/maste r.zip
Downloading/unpacking https://github.com/joh/when-changed/archive/master.zip
Downloading master.zip (unknown size): 4.1kB downloaded
Cleaning up...
Exception:
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/pip/basecommand.py", line 122, in main
status = self.run(options, args)
File "/usr/lib/python2.7/dist-packages/pip/commands/install.py", line 290, in run
requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundl e=self.bundle)
File "/usr/lib/python2.7/dist-packages/pip/req.py", line 1198, in prepare_file s
do_download,
File "/usr/lib/python2.7/dist-packages/pip/req.py", line 1376, in unpack_url
self.session,
File "/usr/lib/python2.7/dist-packages/pip/download.py", line 572, in unpack_h ttp_url
download_hash = _download_url(resp, link, temp_location)
File "/usr/lib/python2.7/dist-packages/pip/download.py", line 433, in _downloa d_url
for chunk in resp_read(4096):
File "/usr/lib/python2.7/dist-packages/pip/download.py", line 421, in resp_rea d
chunk_size, decode_content=False):
File "/usr/lib/python2.7/dist-packages/urllib3/response.py", line 256, in stre am
data = self.read(amt=amt, decode_content=decode_content)
File "/usr/lib/python2.7/dist-packages/urllib3/response.py", line 186, in read
data = self._fp.read(amt)
File "/usr/lib/python2.7/httplib.py", line 573, in read
s = self.fp.read(amt)
File "/usr/lib/python2.7/socket.py", line 380, in read
data = self._sock.recv(left)
File "/usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.py", line 188 , in recv
data = self.connection.recv(*args, **kwargs)
ZeroReturnError
Storing debug log for failure in /home/pi/.pip/pip.log
.pip/pip.log
(debug log)
------------------------------------------------------------
/usr/bin/pip run on Sat Jan 16 00:03:28 2016
Downloading/unpacking https://github.com/joh/when-changed/archive/master.zip
Downloading from URL https://github.com/joh/when-changed/archive/master.zip
Cleaning up...
Exception:
Traceback (most recent call last):
File "/usr/lib/python2.7/dist-packages/pip/basecommand.py", line 122, in main
status = self.run(options, args)
File "/usr/lib/python2.7/dist-packages/pip/commands/install.py", line 290, in run
requirement_set.prepare_files(finder, force_root_egg_info=self.bundle, bundle=self.bundle)
File "/usr/lib/python2.7/dist-packages/pip/req.py", line 1198, in prepare_files
do_download,
File "/usr/lib/python2.7/dist-packages/pip/req.py", line 1376, in unpack_url
self.session,
File "/usr/lib/python2.7/dist-packages/pip/download.py", line 572, in unpack_http_url
download_hash = _download_url(resp, link, temp_location)
File "/usr/lib/python2.7/dist-packages/pip/download.py", line 433, in _download_url
for chunk in resp_read(4096):
File "/usr/lib/python2.7/dist-packages/pip/download.py", line 421, in resp_read
chunk_size, decode_content=False):
File "/usr/lib/python2.7/dist-packages/urllib3/response.py", line 256, in stream
data = self.read(amt=amt, decode_content=decode_content)
File "/usr/lib/python2.7/dist-packages/urllib3/response.py", line 186, in read
data = self._fp.read(amt)
File "/usr/lib/python2.7/httplib.py", line 573, in read
s = self.fp.read(amt)
File "/usr/lib/python2.7/socket.py", line 380, in read
data = self._sock.recv(left)
File "/usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.py", line 188, in recv
data = self.connection.recv(*args, **kwargs)
ZeroReturnError
Nodemon [https://github.com/remy/nodemon] has basically the same use case as when-changed, but dedicated for nodejs.
It has this feature that when it monitors a file, one can re-launch the app by typying in 'rs' and hitting return. I believe it is useful when one file depends on others but you don't need to explicitly monitor every each of them. Think of use cases like external config files, temporary changes in libs etc.
I tried my best, but I'm not familiar with Python and from my initial explorations I got this far:
try:
wc.run()
except KeyboardInterrupt:
print()
exit(0)
print('Press a key')
inkey = _Getch()
for i in xrange(sys.maxint):
k=inkey()
if k=='n':break
print('you pressed ',k)
But I'm at a loss if this is the right track or if it should work at all. I'd appreciate any hints to complete this.
Is it intentionally that watched
Set
initialized at https://github.com/joh/when-changed/blob/master/whenchanged%2Fwhenchanged.py#L100 is then addressed twice to check presence of elements but is never modified?
...
Argparse is a much more cleaner solution to parsing the command line arguments. It will make the code more pythonic ๐
Hello,
First off, thanks a lot for your work! This script is super handy for latex. So handy, in fact, I'm considering packaging it for Ubuntu and making it available through a PPA.
Are you (Joh) at all interested in this? I can do the whole thing by myself, but I'm curious if, for example, you'd like to integrate the changes via pull request or if I should just maintain my own fork.
Hi. Have a look at my fork -- tremby/when-changed
I don't imagine you'll want to pull everything over (since I see you used to use argparse and then removed it -- I have added optparse which is more widely available but deprecated), but you may be interested in some of them.
Perhaps
And in the commit which introduced optparse, the command is accepted on stdin rather than as one of the arguments when -c is not used.
You have %f gets replaced with the file that changed:
currently, but ideally I'd like a variable that contains what changed.
I have a couple of issues, and I might try to work on fixes, but they'd be good here for starters.
I found it only in the stackoverflow answer
It could be nice to have the possibility of watching multiple files at once, either by specifying them as first arguments or by using a wildcard/global/regex syntax
when-changed "file1.cpp file2.cpp" make
when-changed "*.cpp" make
when-changed "file\d+.cpp" make
I run when-changed -rv
but I don't get any notiofications. What is the verbose mode supposed to print out?
I'm getting an error when attempting to use when-changed:
Traceback (most recent call last):
File "/usr/local/bin/when-changed", line 3, in <module>
from whenchanged.whenchanged import main
File "/usr/local/lib/python2.6/dist-packages/whenchanged/whenchanged.py", line 27
self.paths = {os.path.realpath(f): f for f in files}
^
SyntaxError: invalid syntax
I'm sure it's a simple fix but I don't have much experience with python.
if i'm in a
and I have children b
and c
, and d
how do i get this to only watch a/b
and a/d
?
Maybe this issue is not related to when-changed, so excuse me if it's the case.
I found that the command when-changed src/**/*.java -c echo %f
is working as expected.
But as soon as I use this one sh -c 'when-changed src/**/*.java -c echo %f'
I get an error:
OSError: [Errno 2] No such file or directory: '/Users/me/project/src/**'
This is the command in my crontab
@reboot sh /home/pi/project2/mainfile.sh >> /home/pi/project2/mainfile.log 2>&1
mainfile.sh
#!/bin/sh
when-changed /media/SAIF16GB/shares/ytvideolist.txt -c sh /home/pi/yt-dl/videodl.sh & >> /home/pi/yt-dl/QQQQ.log
when-changed /media/SAIF16GB/shares/ytpllist.txt -c sh /home/pi/yt-dl/playlistdl.sh &
But its not working and log file says that command not found
/home/pi/project2/mainfile.sh: 2: /home/pi/project2/mainfile.sh: when-changed: not found
Hello, I cannot find any examples using this and I'm still getting syntax error. My code is
`
import watchdog
import whenchanged
import subprocess32
when-changed funcaptcha.png print("funcaptcha changed")
`
File is in the same folder as python script. Im using python 2.7
I find it cleaner to run "clear;date;echo;command" instead of command as the 2nd argument to your excellent utility. Perhaps you can make it the default?
Hi
In case anyone trips over the same issue, I must use a hyphen per each option e.g. when-changed -v -1
. Concenating the options doesn't work e.g. `when-changed -v1
Can I get process id of which process changed the file?
I'd like to use when-changed to run blogofile whenever any of my website sources changes, but unfortunately blogofile writes the output into a subdirectory of the source directory, which triggers when-changed again. Infinite loop.
I'd love to be able to tell when-changed to please ignore changes to website/_site.
Does this monitor files that are added to the parent directory after the process is launched?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.