-1

In my directory, I have a text file called test.txt and I have a shell script called targetscript.sh.

I want to run this shell script when any changes occur on test.file. On my server, I have no option to install new tools like inotfy or similar like anything.

So after some research I wrote the following shell script which will take the time stamp of test.txt and if any changes occur it will trigger the targetscript.sh.

#!/bin/bash
while true
do
    ATIME=$(stat -c %Z /home/haider/test.txt)
    if [[ "$ATIME" != "$LTIME" ]]; then
        echo "RUN COMMNAD"
        ./targetscript.sh
        LTIME=$ATIME
    fi
    sleep 5
done

But I am getting the following error. enter image description here

tink
  • 14,342
  • 4
  • 46
  • 50
TAMIM HAIDER
  • 641
  • 1
  • 10
  • 19
  • `%(` should be `$(` – 0stone0 Mar 29 '21 at 15:47
  • @0stone0 i have typed wrong i used $(....)...any other suggestion plz – TAMIM HAIDER Mar 29 '21 at 15:49
  • 2
    The error suggests that you're missing a blank after `[[` in your actual script, unlike in the one you're showing us. – Benjamin W. Mar 29 '21 at 15:51
  • 1
    Then there's probably a space missing on `if [[ "$ATIME" != "$LTIME" ]]; then` – 0stone0 Mar 29 '21 at 15:51
  • 4
    Please [edit] your question and **copy&paste** the code, commands and error messages **as text** to the question. Don't show a screenshot of text. Don't retype the code in the question because this way you may hide or introduce errors. – Bodo Mar 29 '21 at 16:19

2 Answers2

2

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
tink
  • 14,342
  • 4
  • 46
  • 50
0stone0
  • 34,288
  • 4
  • 39
  • 64
  • Thanks, @0stone0. I have another question...if I close the putty window/exit the server it stopped the monitorScript automatically...but I want the monitor script will work 24/7 and look for changes...then what modification/measure I need to take – TAMIM HAIDER Mar 30 '21 at 09:57
  • Glad it helped! Please consider [upvoting](https://meta.stackexchange.com/questions/173399/how-can-i-upvote-answers-and-comments) or [accepting](https://meta.stackexchange.com/q/5234/179419) any answers that might have helped you. This indicates to the wider community that you've found a solution and gives some reputation to both the answerer and yourself. – 0stone0 Mar 30 '21 at 10:00
  • 1
    Regarding the second question, that out-of-scope of the current question. However, you'll need to run the script in the background, take a look [here](https://stackoverflow.com/questions/3430330/best-way-to-make-a-shell-script-daemon) or [here](https://unix.stackexchange.com/questions/426862/proper-way-to-run-shell-script-as-a-daemon) to get started! – 0stone0 Mar 30 '21 at 10:00
  • When trying to execute this "./targetscript.sh" I am getting this error . no such file or directory... any more suggestion @0stone0 – TAMIM HAIDER Mar 30 '21 at 11:14
  • 1
    The dot (`.`) means 'current dir', are you sure the file exist? Again, please keep on the current question scope, any other questions can be asked on a new one – 0stone0 Mar 30 '21 at 11:23
1

I think you can try the entr command. This command is not on a mac by default and if you are using mac, you need to install it by homebrew.

brew install entr

If you are using Linux, you can install it by apt-get.

sudo apt-get install entr

How to use entr?

You first list out the files that you are watching, then pipe the list into the entr command. Basically, if you have a example.txt file and you want to monitor it and execute a command whenever it is changed, use this command.

ls example.txt | entr echo "watching..."

Another basic usage is that you first define your bash script and make it executable, then run this command.

find . -type f | entr "./run.sh"

find . -type f returns a list of files inside the current directory recursively. The result is then pipe into the entr command, executing the script run.sh.

よまる
  • 101
  • 1
  • 4