2
votes

This post is updated, look below for the solution.

i have the need to check a folder for a presence of a file, which is not always present.

i made a script like this:

#!/bin/sh
while true; do
file=/path/to/file
if [[ "$file" = *filename* ]]
then
echo "$file is present"
else
echo "No present"
fi
sleep 3
done

Works perfectly, except for the fact that the "$file is present" is continuosly repeated, until i delete or move the file. Which command can I insert after "echo "$file is present" to stop the alert but continue to check for this file (eg when the file will be again available) ?

Thank you.

Since i can't add an answer until 8 hours, i post here my solution:

In anyway i have solved using this script: comparing the time of the file with the current date and then, using "touch" changing the date to 10 seconds ago:

    #!/bin/sh
    while true
    do
    cd $(dirname "$0")
    current=$(pwd)
    cd /boot/home/Downloads
    last=$(ls -t | head -n1)
    name=$(basename "$last")
    filedate=$(date -r "$last" +%G%m%d%H%M%S)
    currentdate=$(date +%G%m%d%H%M%S)
    if [ "$filedate" -eq "$currentdate" ]
    then
    echo "$name" "is present"
    touch -d '-10 seconds' "$name"
    fi
    done

Now works as espected and indipendently from the file name! Alert me about every new file just once and keep to watch that folder :-)

To keep the whole history of script, below there is the script of iamauser. I have a little bit improved this script: now it alert me for every new file (indipendentely from name, kind and so on) inside a folder and also alert me for deleted files :-)

    #!/bin/bash                                                                                                                                                                                         
    cd /boot/home

    filename=$(ls -t | head -n1)                                                                                                                                                                                     
    tstamp=$(stat --print "%Y" "$filename")                                                                                                                                                            
    while true; do
    prev=$(ls "/boot/home/Downloads" | tr '\n' '\n'  > /tmp/prev.txt)
    check=$(ls -t /boot/home/Downloads | head -n1)

     if [ ! -d "$filename" ]; then
    after=$(ls "/boot/home/Downloads" | tr '\n' '\n'  > /tmp/after.txt)

            echo "Not present";
            sleep 5;                                                                                                                                                    
        elif [[ "$filename" == "$filename" && $tstamp -ne $(stat --print "%Y" "$filename") ]]; then
    sleep 2
    difference=$(comm -2 -3 "/tmp/after.txt" "/tmp/prev.txt">/tmp/Diff.txt)
    lost=$(cat /boot/common/cache/tmp/Diff.txt)                                                                                                              
            alert --idea "/boot/home/Downloads: $check is the most recent file in this folder.";
            alert --idea "/boot/home/Downloads: $lost removed.";                                                                                                                                                                 
            tstamp=$(stat --print "%Y" "$filename")                                                                                                                                                        
        else                                                                                                                                                                                            
            sleep 3;                                                                                                                                                                                    
        fi                                                                                                                                                                                              
    done

2
Can you made an example? - Giova84
That would work but it would consume your processing power or fry your drive. Try adding a sleep at the end of the loop like at least 10 seconds (sleep 10). - konsolebox

2 Answers

1
votes

Something like this may work. I am checking the timstamp of the file to check if there is a new copy of the same filename in the folder.

#!/bin/bash                                                                                                                                                                                         

filename="/path/to/file"                                                                                                                                                                                     
tstamp=$(stat --print "%Y" "$file")                                                                                                                                                                 
while true; do                                                                                                                                                                                      
    if [ ! -f "$filename" ]; then                                                                                                                                                                       
        echo "Not present";
        sleep 5;                                                                                                                                                             
    elif [[ "$filename" == "myfile" && $tstamp -ne $(stat --print "%Y" "$filename") ]]; then                                                                                                              
        echo "$filename is present";                                                                                                                                                                    
        tstamp=$(stat --print "%Y" "$filename")                                                                                                                                                         
    else                                                                                                                                                                                            
        sleep 3;                                                                                                                                                                                    
    fi                                                                                                                                                                                              
done   

I tested the script, by touching the filename while the script was running, each time I touched, it printed $filename is present.

0
votes

Sure, konsolebox; you're right. my script isn't perfect also if i add a sleep to reduce CPU usage. In anyway, maybe, i miss something with the script from iamauser: The above script print the echo out when the file is not present, but doesn't print echo out when is present.. Why?

In anyway, since i'd like to experiment, i was also thinking to another way: check the number of files inside a folder using "ls -1 | wc -l", a new file is added and the number of files is +1 than "ls -1 | wc -l" and, so, i can be alerted indipendently from the file name.. If there is any kind of file with any name, the script should alert me once, while keep to check for new files in the folder. Any other suggestion?

Thank you!

UPDATE

Ok: this is the definitive revision of the script: When a new file is written in a folder, this script alert me about. And if I remove this file, the script will alert me, of the most recent file present in that folder. Very nice, since this is what i was looking for :-)

Since I am on Haiku, i have also replaced the "echo" with alert, an alert window, a sort of graphic "echo".

    #!/bin/bash                                                                                                                                                                                         
    cd /boot/home

    filename=$(ls -t | head -n1)                                                                                                                                                                                     
    tstamp=$(stat --print "%Y" "$filename")                                                                                                                                                            
    while true; do

    check=$(ls -t /boot/home/Downloads | head -n1)                                                                                                                                                                                          
        if [ ! -d "$filename" ]; then                                                                                                                                                                       
            echo "Not present";
            sleep 5;                                                                                                                                                             
        elif [[ "$filename" == "$filename" && $tstamp -ne $(stat --print "%Y" "$filename") ]]; then                                                                                                              
            alert --idea "/boot/home/Downloads: $check is the most recent file in this folder";                                                                                                                                                                    
            tstamp=$(stat --print "%Y" "$filename")                                                                                                                                                        
        else                                                                                                                                                                                            
            sleep 3;                                                                                                                                                                                    
        fi                                                                                                                                                                                              
    done