1

I'm trying to make a script in bash. This script is supposed to either exit with prompt if file does not exist, or if it does exit it will exit with prompt once modified, or deleted. The parameter $1 is for the filename, and the parameter $2 is for time intervals between each check. Will it be sufficient to use the -N to check whether the file is modified? Code so far(few small errors which im working on):

#!/bin/bash
running=true;
while[ $running ]
do
    if [ ! -f $1 ]; then
    echo "File: $1 does not exist!"
    running=false;
    fi

    if [ -f $1 ]; then

        if [ ! -N $1 ]; then
            sleep [ $2 ]
            fi;

        elif [ -N $1 ]; then
            echo "File: $1 has been modified!"
            running=false;
            fi;

    fi;
done;
5
  • Better to use running=1 / running=0 and while (( running )); do. true and false don't have special meaning to bash unless you run them as commands. Commented Sep 1, 2013 at 19:33
  • 1
    ...also, you should either switch from [ ] to [[ ]] or be sure to double-quote all your expansions. That is to say, either [[ -f $1 ]] or [ -f "$1" ], but not [ -f $1 ]. Commented Sep 1, 2013 at 19:34
  • 1
    ...also, it's just sleep "$2", not sleep [ $2 ]. Square-brackets are a synonym for the "test" command, and the test command is not part of sleep's syntax. (It's not part of if's syntax either, but that's a separate issue). Commented Sep 1, 2013 at 19:34
  • Also, you can break out a loop with break, so you don't need a running flag at all. Commented Sep 1, 2013 at 19:37
  • Thanks for all feedback, I'm quite fresh to bash programming so all these tips are greatly appreciated. Commented Sep 1, 2013 at 19:43

3 Answers 3

3

I'm assuming that you're targeting only platforms with GNU stat installed.

#!/bin/bash

file="$1"
sleep_time="$2"

# store initial modification time
[[ -f $file ]] || \
  { echo "ERROR: $1 does not exist" >&2; exit 1; }
orig_mtime=$(stat --format=%Y "$file")

while :; do

  # collect current mtime; if we can't retrieve it, it's a safe assumption
  # that the file is gone.
  curr_mtime=$(stat --format=%Y "$file") || \
    { echo "File disappeared" >&2; exit 1; }

  # if current mtime doesn't match the new one, we're done.
  (( curr_mtime != orig_mtime )) && \
    { echo "File modified" >&2; exit 0; }

  # otherwise, delay before another time around.
  sleep "$sleep_time"
done

That said, in an ideal world, you wouldn't write this kind of code yourself -- instead, you'd use tools such as inotifywait, which operate much more efficiently (being notified by the operating system when things change, rather than needing to periodically check.

Sign up to request clarification or add additional context in comments.

3 Comments

I can see that the tool inotifywait is more ideal to use indeed, unfortunately this is a part of my study to be honest, i have a course for bash programming and some other stuff. This was a task we were given to learn some. This code you show'd me here is exactly what i was aiming for, but i read about the -N and it seemed slightly like something i could use, but had to be utterly sure. Thanks alot for you're help!
By the way, after some troubleshooting i were still not able to pinpoint what caused this. But it seems something is wrong when i run the part of the code " (( curr_mtime != orig_mtime )) && \ { echo "File modified" >&2; exit 0; }". the terminal says then that :"syntax error near unexpected token }. Feedback greatly appreciated.
@Ole-MortenHeggertveit The \ is only appropriate if you're adding a linebreak immediately after. If you're putting both of those on the same line, leave it out.
1

Not precisely. -N does a comparison between the file's atime and mtime, which is not accurate on e.g. ext3 filesystems that are mounted relatime. You should either use the OS's file monitoring facilities or compare the mtime of the file directly.

Comments

0

As an aside - if you change running=false; to exit 1, 2, 3 then the code would be clearer and another script that called this could use the return value to determine why the script completed.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.