How to Run a Shell Script When a File or Directory Changes

How to run a shell script when a file or directory changes?

Use inotify-tools.

The linked Github page has a number of examples; here is one of them.

#!/bin/sh

cwd=$(pwd)

inotifywait -mr \
--timefmt '%d/%m/%y %H:%M' --format '%T %w %f' \
-e close_write /tmp/test |
while read -r date time dir file; do
changed_abs=${dir}${file}
changed_rel=${changed_abs#"$cwd"/}

rsync --progress --relative -vrae 'ssh -p 22' "$changed_rel" \
usernam@example.com:/backup/root/dir && \
echo "At ${time} on ${date}, file $changed_abs was backed up via rsync" >&2
done

How to execute a shell script when a file changes?

First of all, the [[1617030570: command not found error is caused by a missing space after the [[ (Not shown in question)

Secondly, you'll always run ./targetscript.sh on the first iteration since LTIME isn't set. Therefore the "$ATIME" != "$LTIME" will fail, and the sh script will be executed.

Consider setting $LTIME before the while-loop:

#!/bin/bash
LTIME=$(stat -c %Z /private/tmp/jq/tst.txt)
while true
do
ATIME=$(stat -c %Z /private/tmp/jq/tst.txt)
if [[ "$ATIME" != "$LTIME" ]]; then
echo "RUN COMMNAD"
./targetscript.sh
LTIME=$ATIME
fi
sleep 2
done

monitor a folder tree for changes and run a script when a file is created - linux

inotify is being around for a while, It's stable and is part of main stream of many distros.

How to install:

on Ubuntu:

sudo apt-get install inotify-tools

on Centos/RHEL (from EPEL repo):

yum --enablerepo epel install inotify-tools

How to use:

inotifywait -re create /tmp/test1/ && echo "Change detected"

Once you create a file echo "change detected" will be triggered which could be just about anything.

The output you get:

Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.
/tmp/test1/test2/test3/ CREATE file
Change detected

PS. -r for recursive -e create to detect new files.

Shell Script - opening files from a different directory

Here is a code to open the bar directory with nautilus (ubuntu's explorer):

#!/bin/bash

path='/home/your_user_name/foo'
nautilus $path/bar/

Rules:

  1. Use absolute path: /home/your_user_name/, not ~/ nor $HOME.
  2. Bash doesn't like spaces: path='~/Datasets/foo', and not path = '~/Datasets/foo'

How to change current directory via shell script and execute command there?

This is very nearly a duplicate of Change the current directory from a Bash script, and the answer is very similar -- the only difference being the appending of the command you want to run.

Don't use a script at all; instead, in your ~/.bashrc or similar, define a function:

runInMyDir() {
cd ~/my-dir || return
runall
}

...to define a command runInMyDir. (If you want runall to happen in the background, add a & at the end of that line).


If you do want a script, that script needs to be sourced rather than executed out-of-process -- when a program is executed as an executable external to the shell, it has already been split off from the original shell before it starts, so it has no opportunity to change that shell's behavior. Thus, if you created a file named runInMyDir with the commands cd ~/my-dir || return and runall, you would need to run source runInMyDir rather than just runInMyDir to invoke it.

Bash script to check if a new file has been created on a directory after run a command

Thanks to informative comments, I've just realized that I've missed the basics of bash script but finally made that work. I'll leave my solution here as an answer for those who struggle like me.:

WATCH_DIR=./tmp

FILES_BEFORE=$(ls $WATCH_DIR)

echo >$WATCH_DIR/filename

FILES_AFTER=$(ls $WATCH_DIR)

if diff <(echo "$FILES_AFTER") <(echo "$FILES_BEFORE")
then
echo "No changes"
else
echo "Changes"
fi

It outputs "Changes" on the first run and "No Changes" for the other unless you delete the newly added documents.

How to run a .sh-script from any path in a terminal?

One option is simply to type the path to the script:

~/Desktop/script

This works fine, but gets a bit unwieldy.

This is what the PATH environment variable is for. And it is what $HOME/bin is for.

  1. Create yourself a directory $HOME/bin. Put all your executable scripts in it (make them executable with chmod +x script if need be††). This way, there's one place to look for the scripts you want to run.
  2. Add $HOME/bin to your PATH. I put mine at the front: PATH="$HOME/bin:$PATH, but you could put it at the back if you prefer.
  3. Update your .profile or .bash_profile (or possibly .bashrc) file to set PATH. Beware of a continually growing PATH, though.

As tripleee noted, once the command is installed in a directory on PATH, you no longer type ./script, but just script. This is exactly like you type ls and not /bin/ls, etc. Once the program is installed in a directory on your PATH, it is (for many purposes) indistinguishable from a system-provided command.

I have about 500 scripts and programs in my $HOME/bin directory.

Note that this doesn't require any special privileges. If you have administrator access to your machine and you think other users might find your commands useful, then you could install the scripts/programs in one of the system-provided directories on your PATH. However, it is usually best not to add programs to any of:

  • /bin
  • /usr/bin
  • /sbin
  • /usr/sbin

There is often/usually /usr/local/bin which is a suitable place for widely used commands not provided by the system.


†† It would be better to use chmod a+x,go-w script; your scripts should not be writable by other people. You could even simply use chmod 555 script or chmod 755 script. I tend to keep my scripts non-writable. That way, I have to go through a formal change process with the version control system. It means there's less danger of uncontrolled changes.

Executing shell script without changing its environment

Please try the following:

( cd dir1; ./script1 )
( cd dir2; ./script2 )
( cd dir3; ./script3 )

Note that () are needed to save/restore you master script current directory.



Related Topics



Leave a reply



Submit