How can I execute scripts based on changes that are happening on a specific folder?
Clash Royale CLAN TAG#URR8PPP
up vote
1
down vote
favorite
For changing a specific image's size I use the following command:
mogrify -geometry x50 my_image.png
Every time that I take a new print screen, an image is saved on my ~/Pictures
folder. I'd like to make a script that watches my Pictures
folder and takes an action copying a reduced sized version of my new image to a different folder on my computer, e.g. ~/.icons/
...
I know I could solve this problem using cron
, but I don't really want to take actions at regular intervals of time. I want a command ( or a script) that can find out what's different on a folder based on logs or something like this. Is that possible? How can I do it?
command-line files scripting logs images
add a comment |Â
up vote
1
down vote
favorite
For changing a specific image's size I use the following command:
mogrify -geometry x50 my_image.png
Every time that I take a new print screen, an image is saved on my ~/Pictures
folder. I'd like to make a script that watches my Pictures
folder and takes an action copying a reduced sized version of my new image to a different folder on my computer, e.g. ~/.icons/
...
I know I could solve this problem using cron
, but I don't really want to take actions at regular intervals of time. I want a command ( or a script) that can find out what's different on a folder based on logs or something like this. Is that possible? How can I do it?
command-line files scripting logs images
Possibly useful, possibly even a dup: How to loop over ever-increasing list of files in bash?
â ilkkachu
May 16 at 13:36
add a comment |Â
up vote
1
down vote
favorite
up vote
1
down vote
favorite
For changing a specific image's size I use the following command:
mogrify -geometry x50 my_image.png
Every time that I take a new print screen, an image is saved on my ~/Pictures
folder. I'd like to make a script that watches my Pictures
folder and takes an action copying a reduced sized version of my new image to a different folder on my computer, e.g. ~/.icons/
...
I know I could solve this problem using cron
, but I don't really want to take actions at regular intervals of time. I want a command ( or a script) that can find out what's different on a folder based on logs or something like this. Is that possible? How can I do it?
command-line files scripting logs images
For changing a specific image's size I use the following command:
mogrify -geometry x50 my_image.png
Every time that I take a new print screen, an image is saved on my ~/Pictures
folder. I'd like to make a script that watches my Pictures
folder and takes an action copying a reduced sized version of my new image to a different folder on my computer, e.g. ~/.icons/
...
I know I could solve this problem using cron
, but I don't really want to take actions at regular intervals of time. I want a command ( or a script) that can find out what's different on a folder based on logs or something like this. Is that possible? How can I do it?
command-line files scripting logs images
edited May 16 at 14:04
asked May 16 at 13:29
Ramuyko
299314
299314
Possibly useful, possibly even a dup: How to loop over ever-increasing list of files in bash?
â ilkkachu
May 16 at 13:36
add a comment |Â
Possibly useful, possibly even a dup: How to loop over ever-increasing list of files in bash?
â ilkkachu
May 16 at 13:36
Possibly useful, possibly even a dup: How to loop over ever-increasing list of files in bash?
â ilkkachu
May 16 at 13:36
Possibly useful, possibly even a dup: How to loop over ever-increasing list of files in bash?
â ilkkachu
May 16 at 13:36
add a comment |Â
3 Answers
3
active
oldest
votes
up vote
1
down vote
accepted
I've created this functional script that solves my problem using inotify-tools
. So I'm leaving it here in case it's useful for someone else.
#!/bin/bash
watchedFolder=~/Pictures
iconsFolder=~/.icons
imageGeometry=100
while [ true ]
do
fileName=$(inotifywait -q -e create --format "%f" "$watchedFolder")
if ! [ -d $iconsFolder ]; then mkdir -p $iconsFolder ; fi
sleep 1s
cp $watchedFolder/"$fileName" $iconsFolder
mogrify -geometry x$imageGeometry $iconsFolder/"$fileName"
done
Save it as e.g. ~/automatedIcons.bash
and make it executable with chmod +x ~/automatedIcons.bash
. Now if you run it, it's already working, it's going to copy every new picture that is created inside the Pictures
folder to a new location and change its size. To make it run on boot use crontab -e
and write one line with the script's location on it, e.g. @reboot /home/myUserName/automatedIcons.bash
.
This is just a functional script. So if anyone has any suggestion about improving the way it works, feel free to write in the comments.
you could get rid of the temp file with justfileName=$(inotifywait ...)
. And you probably should double-quote all the variable expansions, esp.fileName
, since it relies on data that comes from outside the script (for the ones set inside the script, you could say you know they are safe).
â ilkkachu
May 16 at 20:02
@ilkkachu Thanks, I've incorporated the changes on the answer already. I've realized that this script doesn't work when there're spaces on the picture's name though. I thought that the double quotes on fileName would solve that but it's still not working. Do you you have any idea why?
â Ramuyko
May 16 at 21:07
ah, thetr
trashes the spaces. You'd need something more careful to remove the unnecessary parts, or just useinotifywait -q -e create --format "%f"
to only get the filename. The event and directory are constant here, so they're not really needed.
â ilkkachu
May 16 at 21:18
@ilkkachu Ah yeah... That's easier. I've updated the script again. Now it works with spaces as well. Thanks!!
â Ramuyko
May 16 at 21:31
1
Note thatwhile [ true ]
is just testing whether the stringtrue
is nonempty.while [ false ]
would work just as well.
â Kusalananda
Jun 30 at 8:50
add a comment |Â
up vote
0
down vote
This question (or similar) was answered in Stack Overflow
Mainly says, that you need to use inotify-tools
2
This would be much more useful with at least a brief sample of how to do it, instead of just the link. Especially when the accepted answer in that SE question is also just a link-only answer, gahh.
â ilkkachu
May 16 at 13:39
You're right. But it's just a point to start from. I would like to "teach" him, but I would usecron
orwatch
â Kyrie001
May 16 at 13:44
add a comment |Â
up vote
0
down vote
I've created a script that simplifies the use of inotifywait
by declaring specific flags that can be used later. So I'm posting it here as well:
#!/bin/bash
watchedFolder=/path/to/monitored_folder
declare -A cache
inotifywait --format="%w^%e^%f" -q -r -m -e move,create,delete "$watchedFolder" |
while IFS='^' read id event file; do
file_moved_from_different_folder='0'
file_renamed='0'
file_moved_different_folder='0'
file_created='0'
file_deleted='0'
echo ""
echo "id:$id"
echo "event:$event"
echo "file:$file"
################# DECLARATION OF FLAGS
if [ "$event" == "MOVED_FROM" -o "$event" == "MOVED_FROM,ISDIR" ]; then
cache[moved_from]="$file"
SECONDS=0
elif [ "$event" == "MOVED_TO" -o "$event" == "MOVED_TO,ISDIR" ]; then
if [ $SECONDS -gt 2 ]; then
echo "Action: Moved from an external folder flag declared"
file_moved_from_different_folder='1'
elif [ "$cache[moved_from]" != "$file" ]; then
echo "Action: Renamed Flag declared ..."
file_renamed='1'
unset cache[moved_from]
elif [ "$cache[moved_from]" == "$file" ] ; then
echo "Action: Moved to a different folder flag declared"
file_moved_different_folder='1'
unset cache[moved_from]
fi
elif [ "$event" == "CREATE" -o "$event" == "CREATE,ISDIR" ]; then
echo "Action: Created Flag declared ..."
file_created='1'
elif [ "$event" == "DELETE" -o "$event" == "DELETE,ISDIR" ]; then
echo "Action: Deleted Flag declared ..."
file_deleted='1'
fi
###
if [ $file_moved_from_different_folder == '1' ]; then
echo "Do something here when a file from outside is moved to the monitored folder"
fi
if [ file_renamed == '1' ]; then
echo "Do something here when a file is renamed"
fi
if [ $file_moved_different_folder == '1' ]; then
echo "Do something here when files are moved inside the recursive structure of the monitored folder"
fi
if [ $file_created == '1' ]; then
echo "Do something here when a file is created"
fi
if [ $file_deleted == '1' ]; then
echo "Do something here when a file is deleted"
fi
done
The idea here is to separate flags that can tell us what's happening in a folder while saving the path of the file ($id
), the event that's happening ($event
) and the name of the file ($file
) on variables for later use. Besides the fact that we can easily detect when a file or folder is renamed (the renamed flag can't be got directly using inotifywait
).
In this example, the recursive parameter -r
is settled, so the script is going to watch all subfolders of the watched folder as well. For watching only a single folder just remove the -r
parameter... This is a generic solution that can be used for different situations when we want to execute specific actions based on changes that are happening on folders.
add a comment |Â
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
I've created this functional script that solves my problem using inotify-tools
. So I'm leaving it here in case it's useful for someone else.
#!/bin/bash
watchedFolder=~/Pictures
iconsFolder=~/.icons
imageGeometry=100
while [ true ]
do
fileName=$(inotifywait -q -e create --format "%f" "$watchedFolder")
if ! [ -d $iconsFolder ]; then mkdir -p $iconsFolder ; fi
sleep 1s
cp $watchedFolder/"$fileName" $iconsFolder
mogrify -geometry x$imageGeometry $iconsFolder/"$fileName"
done
Save it as e.g. ~/automatedIcons.bash
and make it executable with chmod +x ~/automatedIcons.bash
. Now if you run it, it's already working, it's going to copy every new picture that is created inside the Pictures
folder to a new location and change its size. To make it run on boot use crontab -e
and write one line with the script's location on it, e.g. @reboot /home/myUserName/automatedIcons.bash
.
This is just a functional script. So if anyone has any suggestion about improving the way it works, feel free to write in the comments.
you could get rid of the temp file with justfileName=$(inotifywait ...)
. And you probably should double-quote all the variable expansions, esp.fileName
, since it relies on data that comes from outside the script (for the ones set inside the script, you could say you know they are safe).
â ilkkachu
May 16 at 20:02
@ilkkachu Thanks, I've incorporated the changes on the answer already. I've realized that this script doesn't work when there're spaces on the picture's name though. I thought that the double quotes on fileName would solve that but it's still not working. Do you you have any idea why?
â Ramuyko
May 16 at 21:07
ah, thetr
trashes the spaces. You'd need something more careful to remove the unnecessary parts, or just useinotifywait -q -e create --format "%f"
to only get the filename. The event and directory are constant here, so they're not really needed.
â ilkkachu
May 16 at 21:18
@ilkkachu Ah yeah... That's easier. I've updated the script again. Now it works with spaces as well. Thanks!!
â Ramuyko
May 16 at 21:31
1
Note thatwhile [ true ]
is just testing whether the stringtrue
is nonempty.while [ false ]
would work just as well.
â Kusalananda
Jun 30 at 8:50
add a comment |Â
up vote
1
down vote
accepted
I've created this functional script that solves my problem using inotify-tools
. So I'm leaving it here in case it's useful for someone else.
#!/bin/bash
watchedFolder=~/Pictures
iconsFolder=~/.icons
imageGeometry=100
while [ true ]
do
fileName=$(inotifywait -q -e create --format "%f" "$watchedFolder")
if ! [ -d $iconsFolder ]; then mkdir -p $iconsFolder ; fi
sleep 1s
cp $watchedFolder/"$fileName" $iconsFolder
mogrify -geometry x$imageGeometry $iconsFolder/"$fileName"
done
Save it as e.g. ~/automatedIcons.bash
and make it executable with chmod +x ~/automatedIcons.bash
. Now if you run it, it's already working, it's going to copy every new picture that is created inside the Pictures
folder to a new location and change its size. To make it run on boot use crontab -e
and write one line with the script's location on it, e.g. @reboot /home/myUserName/automatedIcons.bash
.
This is just a functional script. So if anyone has any suggestion about improving the way it works, feel free to write in the comments.
you could get rid of the temp file with justfileName=$(inotifywait ...)
. And you probably should double-quote all the variable expansions, esp.fileName
, since it relies on data that comes from outside the script (for the ones set inside the script, you could say you know they are safe).
â ilkkachu
May 16 at 20:02
@ilkkachu Thanks, I've incorporated the changes on the answer already. I've realized that this script doesn't work when there're spaces on the picture's name though. I thought that the double quotes on fileName would solve that but it's still not working. Do you you have any idea why?
â Ramuyko
May 16 at 21:07
ah, thetr
trashes the spaces. You'd need something more careful to remove the unnecessary parts, or just useinotifywait -q -e create --format "%f"
to only get the filename. The event and directory are constant here, so they're not really needed.
â ilkkachu
May 16 at 21:18
@ilkkachu Ah yeah... That's easier. I've updated the script again. Now it works with spaces as well. Thanks!!
â Ramuyko
May 16 at 21:31
1
Note thatwhile [ true ]
is just testing whether the stringtrue
is nonempty.while [ false ]
would work just as well.
â Kusalananda
Jun 30 at 8:50
add a comment |Â
up vote
1
down vote
accepted
up vote
1
down vote
accepted
I've created this functional script that solves my problem using inotify-tools
. So I'm leaving it here in case it's useful for someone else.
#!/bin/bash
watchedFolder=~/Pictures
iconsFolder=~/.icons
imageGeometry=100
while [ true ]
do
fileName=$(inotifywait -q -e create --format "%f" "$watchedFolder")
if ! [ -d $iconsFolder ]; then mkdir -p $iconsFolder ; fi
sleep 1s
cp $watchedFolder/"$fileName" $iconsFolder
mogrify -geometry x$imageGeometry $iconsFolder/"$fileName"
done
Save it as e.g. ~/automatedIcons.bash
and make it executable with chmod +x ~/automatedIcons.bash
. Now if you run it, it's already working, it's going to copy every new picture that is created inside the Pictures
folder to a new location and change its size. To make it run on boot use crontab -e
and write one line with the script's location on it, e.g. @reboot /home/myUserName/automatedIcons.bash
.
This is just a functional script. So if anyone has any suggestion about improving the way it works, feel free to write in the comments.
I've created this functional script that solves my problem using inotify-tools
. So I'm leaving it here in case it's useful for someone else.
#!/bin/bash
watchedFolder=~/Pictures
iconsFolder=~/.icons
imageGeometry=100
while [ true ]
do
fileName=$(inotifywait -q -e create --format "%f" "$watchedFolder")
if ! [ -d $iconsFolder ]; then mkdir -p $iconsFolder ; fi
sleep 1s
cp $watchedFolder/"$fileName" $iconsFolder
mogrify -geometry x$imageGeometry $iconsFolder/"$fileName"
done
Save it as e.g. ~/automatedIcons.bash
and make it executable with chmod +x ~/automatedIcons.bash
. Now if you run it, it's already working, it's going to copy every new picture that is created inside the Pictures
folder to a new location and change its size. To make it run on boot use crontab -e
and write one line with the script's location on it, e.g. @reboot /home/myUserName/automatedIcons.bash
.
This is just a functional script. So if anyone has any suggestion about improving the way it works, feel free to write in the comments.
edited May 20 at 20:04
answered May 16 at 19:33
Ramuyko
299314
299314
you could get rid of the temp file with justfileName=$(inotifywait ...)
. And you probably should double-quote all the variable expansions, esp.fileName
, since it relies on data that comes from outside the script (for the ones set inside the script, you could say you know they are safe).
â ilkkachu
May 16 at 20:02
@ilkkachu Thanks, I've incorporated the changes on the answer already. I've realized that this script doesn't work when there're spaces on the picture's name though. I thought that the double quotes on fileName would solve that but it's still not working. Do you you have any idea why?
â Ramuyko
May 16 at 21:07
ah, thetr
trashes the spaces. You'd need something more careful to remove the unnecessary parts, or just useinotifywait -q -e create --format "%f"
to only get the filename. The event and directory are constant here, so they're not really needed.
â ilkkachu
May 16 at 21:18
@ilkkachu Ah yeah... That's easier. I've updated the script again. Now it works with spaces as well. Thanks!!
â Ramuyko
May 16 at 21:31
1
Note thatwhile [ true ]
is just testing whether the stringtrue
is nonempty.while [ false ]
would work just as well.
â Kusalananda
Jun 30 at 8:50
add a comment |Â
you could get rid of the temp file with justfileName=$(inotifywait ...)
. And you probably should double-quote all the variable expansions, esp.fileName
, since it relies on data that comes from outside the script (for the ones set inside the script, you could say you know they are safe).
â ilkkachu
May 16 at 20:02
@ilkkachu Thanks, I've incorporated the changes on the answer already. I've realized that this script doesn't work when there're spaces on the picture's name though. I thought that the double quotes on fileName would solve that but it's still not working. Do you you have any idea why?
â Ramuyko
May 16 at 21:07
ah, thetr
trashes the spaces. You'd need something more careful to remove the unnecessary parts, or just useinotifywait -q -e create --format "%f"
to only get the filename. The event and directory are constant here, so they're not really needed.
â ilkkachu
May 16 at 21:18
@ilkkachu Ah yeah... That's easier. I've updated the script again. Now it works with spaces as well. Thanks!!
â Ramuyko
May 16 at 21:31
1
Note thatwhile [ true ]
is just testing whether the stringtrue
is nonempty.while [ false ]
would work just as well.
â Kusalananda
Jun 30 at 8:50
you could get rid of the temp file with just
fileName=$(inotifywait ...)
. And you probably should double-quote all the variable expansions, esp. fileName
, since it relies on data that comes from outside the script (for the ones set inside the script, you could say you know they are safe).â ilkkachu
May 16 at 20:02
you could get rid of the temp file with just
fileName=$(inotifywait ...)
. And you probably should double-quote all the variable expansions, esp. fileName
, since it relies on data that comes from outside the script (for the ones set inside the script, you could say you know they are safe).â ilkkachu
May 16 at 20:02
@ilkkachu Thanks, I've incorporated the changes on the answer already. I've realized that this script doesn't work when there're spaces on the picture's name though. I thought that the double quotes on fileName would solve that but it's still not working. Do you you have any idea why?
â Ramuyko
May 16 at 21:07
@ilkkachu Thanks, I've incorporated the changes on the answer already. I've realized that this script doesn't work when there're spaces on the picture's name though. I thought that the double quotes on fileName would solve that but it's still not working. Do you you have any idea why?
â Ramuyko
May 16 at 21:07
ah, the
tr
trashes the spaces. You'd need something more careful to remove the unnecessary parts, or just use inotifywait -q -e create --format "%f"
to only get the filename. The event and directory are constant here, so they're not really needed.â ilkkachu
May 16 at 21:18
ah, the
tr
trashes the spaces. You'd need something more careful to remove the unnecessary parts, or just use inotifywait -q -e create --format "%f"
to only get the filename. The event and directory are constant here, so they're not really needed.â ilkkachu
May 16 at 21:18
@ilkkachu Ah yeah... That's easier. I've updated the script again. Now it works with spaces as well. Thanks!!
â Ramuyko
May 16 at 21:31
@ilkkachu Ah yeah... That's easier. I've updated the script again. Now it works with spaces as well. Thanks!!
â Ramuyko
May 16 at 21:31
1
1
Note that
while [ true ]
is just testing whether the string true
is nonempty. while [ false ]
would work just as well.â Kusalananda
Jun 30 at 8:50
Note that
while [ true ]
is just testing whether the string true
is nonempty. while [ false ]
would work just as well.â Kusalananda
Jun 30 at 8:50
add a comment |Â
up vote
0
down vote
This question (or similar) was answered in Stack Overflow
Mainly says, that you need to use inotify-tools
2
This would be much more useful with at least a brief sample of how to do it, instead of just the link. Especially when the accepted answer in that SE question is also just a link-only answer, gahh.
â ilkkachu
May 16 at 13:39
You're right. But it's just a point to start from. I would like to "teach" him, but I would usecron
orwatch
â Kyrie001
May 16 at 13:44
add a comment |Â
up vote
0
down vote
This question (or similar) was answered in Stack Overflow
Mainly says, that you need to use inotify-tools
2
This would be much more useful with at least a brief sample of how to do it, instead of just the link. Especially when the accepted answer in that SE question is also just a link-only answer, gahh.
â ilkkachu
May 16 at 13:39
You're right. But it's just a point to start from. I would like to "teach" him, but I would usecron
orwatch
â Kyrie001
May 16 at 13:44
add a comment |Â
up vote
0
down vote
up vote
0
down vote
This question (or similar) was answered in Stack Overflow
Mainly says, that you need to use inotify-tools
This question (or similar) was answered in Stack Overflow
Mainly says, that you need to use inotify-tools
answered May 16 at 13:36
Kyrie001
434
434
2
This would be much more useful with at least a brief sample of how to do it, instead of just the link. Especially when the accepted answer in that SE question is also just a link-only answer, gahh.
â ilkkachu
May 16 at 13:39
You're right. But it's just a point to start from. I would like to "teach" him, but I would usecron
orwatch
â Kyrie001
May 16 at 13:44
add a comment |Â
2
This would be much more useful with at least a brief sample of how to do it, instead of just the link. Especially when the accepted answer in that SE question is also just a link-only answer, gahh.
â ilkkachu
May 16 at 13:39
You're right. But it's just a point to start from. I would like to "teach" him, but I would usecron
orwatch
â Kyrie001
May 16 at 13:44
2
2
This would be much more useful with at least a brief sample of how to do it, instead of just the link. Especially when the accepted answer in that SE question is also just a link-only answer, gahh.
â ilkkachu
May 16 at 13:39
This would be much more useful with at least a brief sample of how to do it, instead of just the link. Especially when the accepted answer in that SE question is also just a link-only answer, gahh.
â ilkkachu
May 16 at 13:39
You're right. But it's just a point to start from. I would like to "teach" him, but I would use
cron
or watch
â Kyrie001
May 16 at 13:44
You're right. But it's just a point to start from. I would like to "teach" him, but I would use
cron
or watch
â Kyrie001
May 16 at 13:44
add a comment |Â
up vote
0
down vote
I've created a script that simplifies the use of inotifywait
by declaring specific flags that can be used later. So I'm posting it here as well:
#!/bin/bash
watchedFolder=/path/to/monitored_folder
declare -A cache
inotifywait --format="%w^%e^%f" -q -r -m -e move,create,delete "$watchedFolder" |
while IFS='^' read id event file; do
file_moved_from_different_folder='0'
file_renamed='0'
file_moved_different_folder='0'
file_created='0'
file_deleted='0'
echo ""
echo "id:$id"
echo "event:$event"
echo "file:$file"
################# DECLARATION OF FLAGS
if [ "$event" == "MOVED_FROM" -o "$event" == "MOVED_FROM,ISDIR" ]; then
cache[moved_from]="$file"
SECONDS=0
elif [ "$event" == "MOVED_TO" -o "$event" == "MOVED_TO,ISDIR" ]; then
if [ $SECONDS -gt 2 ]; then
echo "Action: Moved from an external folder flag declared"
file_moved_from_different_folder='1'
elif [ "$cache[moved_from]" != "$file" ]; then
echo "Action: Renamed Flag declared ..."
file_renamed='1'
unset cache[moved_from]
elif [ "$cache[moved_from]" == "$file" ] ; then
echo "Action: Moved to a different folder flag declared"
file_moved_different_folder='1'
unset cache[moved_from]
fi
elif [ "$event" == "CREATE" -o "$event" == "CREATE,ISDIR" ]; then
echo "Action: Created Flag declared ..."
file_created='1'
elif [ "$event" == "DELETE" -o "$event" == "DELETE,ISDIR" ]; then
echo "Action: Deleted Flag declared ..."
file_deleted='1'
fi
###
if [ $file_moved_from_different_folder == '1' ]; then
echo "Do something here when a file from outside is moved to the monitored folder"
fi
if [ file_renamed == '1' ]; then
echo "Do something here when a file is renamed"
fi
if [ $file_moved_different_folder == '1' ]; then
echo "Do something here when files are moved inside the recursive structure of the monitored folder"
fi
if [ $file_created == '1' ]; then
echo "Do something here when a file is created"
fi
if [ $file_deleted == '1' ]; then
echo "Do something here when a file is deleted"
fi
done
The idea here is to separate flags that can tell us what's happening in a folder while saving the path of the file ($id
), the event that's happening ($event
) and the name of the file ($file
) on variables for later use. Besides the fact that we can easily detect when a file or folder is renamed (the renamed flag can't be got directly using inotifywait
).
In this example, the recursive parameter -r
is settled, so the script is going to watch all subfolders of the watched folder as well. For watching only a single folder just remove the -r
parameter... This is a generic solution that can be used for different situations when we want to execute specific actions based on changes that are happening on folders.
add a comment |Â
up vote
0
down vote
I've created a script that simplifies the use of inotifywait
by declaring specific flags that can be used later. So I'm posting it here as well:
#!/bin/bash
watchedFolder=/path/to/monitored_folder
declare -A cache
inotifywait --format="%w^%e^%f" -q -r -m -e move,create,delete "$watchedFolder" |
while IFS='^' read id event file; do
file_moved_from_different_folder='0'
file_renamed='0'
file_moved_different_folder='0'
file_created='0'
file_deleted='0'
echo ""
echo "id:$id"
echo "event:$event"
echo "file:$file"
################# DECLARATION OF FLAGS
if [ "$event" == "MOVED_FROM" -o "$event" == "MOVED_FROM,ISDIR" ]; then
cache[moved_from]="$file"
SECONDS=0
elif [ "$event" == "MOVED_TO" -o "$event" == "MOVED_TO,ISDIR" ]; then
if [ $SECONDS -gt 2 ]; then
echo "Action: Moved from an external folder flag declared"
file_moved_from_different_folder='1'
elif [ "$cache[moved_from]" != "$file" ]; then
echo "Action: Renamed Flag declared ..."
file_renamed='1'
unset cache[moved_from]
elif [ "$cache[moved_from]" == "$file" ] ; then
echo "Action: Moved to a different folder flag declared"
file_moved_different_folder='1'
unset cache[moved_from]
fi
elif [ "$event" == "CREATE" -o "$event" == "CREATE,ISDIR" ]; then
echo "Action: Created Flag declared ..."
file_created='1'
elif [ "$event" == "DELETE" -o "$event" == "DELETE,ISDIR" ]; then
echo "Action: Deleted Flag declared ..."
file_deleted='1'
fi
###
if [ $file_moved_from_different_folder == '1' ]; then
echo "Do something here when a file from outside is moved to the monitored folder"
fi
if [ file_renamed == '1' ]; then
echo "Do something here when a file is renamed"
fi
if [ $file_moved_different_folder == '1' ]; then
echo "Do something here when files are moved inside the recursive structure of the monitored folder"
fi
if [ $file_created == '1' ]; then
echo "Do something here when a file is created"
fi
if [ $file_deleted == '1' ]; then
echo "Do something here when a file is deleted"
fi
done
The idea here is to separate flags that can tell us what's happening in a folder while saving the path of the file ($id
), the event that's happening ($event
) and the name of the file ($file
) on variables for later use. Besides the fact that we can easily detect when a file or folder is renamed (the renamed flag can't be got directly using inotifywait
).
In this example, the recursive parameter -r
is settled, so the script is going to watch all subfolders of the watched folder as well. For watching only a single folder just remove the -r
parameter... This is a generic solution that can be used for different situations when we want to execute specific actions based on changes that are happening on folders.
add a comment |Â
up vote
0
down vote
up vote
0
down vote
I've created a script that simplifies the use of inotifywait
by declaring specific flags that can be used later. So I'm posting it here as well:
#!/bin/bash
watchedFolder=/path/to/monitored_folder
declare -A cache
inotifywait --format="%w^%e^%f" -q -r -m -e move,create,delete "$watchedFolder" |
while IFS='^' read id event file; do
file_moved_from_different_folder='0'
file_renamed='0'
file_moved_different_folder='0'
file_created='0'
file_deleted='0'
echo ""
echo "id:$id"
echo "event:$event"
echo "file:$file"
################# DECLARATION OF FLAGS
if [ "$event" == "MOVED_FROM" -o "$event" == "MOVED_FROM,ISDIR" ]; then
cache[moved_from]="$file"
SECONDS=0
elif [ "$event" == "MOVED_TO" -o "$event" == "MOVED_TO,ISDIR" ]; then
if [ $SECONDS -gt 2 ]; then
echo "Action: Moved from an external folder flag declared"
file_moved_from_different_folder='1'
elif [ "$cache[moved_from]" != "$file" ]; then
echo "Action: Renamed Flag declared ..."
file_renamed='1'
unset cache[moved_from]
elif [ "$cache[moved_from]" == "$file" ] ; then
echo "Action: Moved to a different folder flag declared"
file_moved_different_folder='1'
unset cache[moved_from]
fi
elif [ "$event" == "CREATE" -o "$event" == "CREATE,ISDIR" ]; then
echo "Action: Created Flag declared ..."
file_created='1'
elif [ "$event" == "DELETE" -o "$event" == "DELETE,ISDIR" ]; then
echo "Action: Deleted Flag declared ..."
file_deleted='1'
fi
###
if [ $file_moved_from_different_folder == '1' ]; then
echo "Do something here when a file from outside is moved to the monitored folder"
fi
if [ file_renamed == '1' ]; then
echo "Do something here when a file is renamed"
fi
if [ $file_moved_different_folder == '1' ]; then
echo "Do something here when files are moved inside the recursive structure of the monitored folder"
fi
if [ $file_created == '1' ]; then
echo "Do something here when a file is created"
fi
if [ $file_deleted == '1' ]; then
echo "Do something here when a file is deleted"
fi
done
The idea here is to separate flags that can tell us what's happening in a folder while saving the path of the file ($id
), the event that's happening ($event
) and the name of the file ($file
) on variables for later use. Besides the fact that we can easily detect when a file or folder is renamed (the renamed flag can't be got directly using inotifywait
).
In this example, the recursive parameter -r
is settled, so the script is going to watch all subfolders of the watched folder as well. For watching only a single folder just remove the -r
parameter... This is a generic solution that can be used for different situations when we want to execute specific actions based on changes that are happening on folders.
I've created a script that simplifies the use of inotifywait
by declaring specific flags that can be used later. So I'm posting it here as well:
#!/bin/bash
watchedFolder=/path/to/monitored_folder
declare -A cache
inotifywait --format="%w^%e^%f" -q -r -m -e move,create,delete "$watchedFolder" |
while IFS='^' read id event file; do
file_moved_from_different_folder='0'
file_renamed='0'
file_moved_different_folder='0'
file_created='0'
file_deleted='0'
echo ""
echo "id:$id"
echo "event:$event"
echo "file:$file"
################# DECLARATION OF FLAGS
if [ "$event" == "MOVED_FROM" -o "$event" == "MOVED_FROM,ISDIR" ]; then
cache[moved_from]="$file"
SECONDS=0
elif [ "$event" == "MOVED_TO" -o "$event" == "MOVED_TO,ISDIR" ]; then
if [ $SECONDS -gt 2 ]; then
echo "Action: Moved from an external folder flag declared"
file_moved_from_different_folder='1'
elif [ "$cache[moved_from]" != "$file" ]; then
echo "Action: Renamed Flag declared ..."
file_renamed='1'
unset cache[moved_from]
elif [ "$cache[moved_from]" == "$file" ] ; then
echo "Action: Moved to a different folder flag declared"
file_moved_different_folder='1'
unset cache[moved_from]
fi
elif [ "$event" == "CREATE" -o "$event" == "CREATE,ISDIR" ]; then
echo "Action: Created Flag declared ..."
file_created='1'
elif [ "$event" == "DELETE" -o "$event" == "DELETE,ISDIR" ]; then
echo "Action: Deleted Flag declared ..."
file_deleted='1'
fi
###
if [ $file_moved_from_different_folder == '1' ]; then
echo "Do something here when a file from outside is moved to the monitored folder"
fi
if [ file_renamed == '1' ]; then
echo "Do something here when a file is renamed"
fi
if [ $file_moved_different_folder == '1' ]; then
echo "Do something here when files are moved inside the recursive structure of the monitored folder"
fi
if [ $file_created == '1' ]; then
echo "Do something here when a file is created"
fi
if [ $file_deleted == '1' ]; then
echo "Do something here when a file is deleted"
fi
done
The idea here is to separate flags that can tell us what's happening in a folder while saving the path of the file ($id
), the event that's happening ($event
) and the name of the file ($file
) on variables for later use. Besides the fact that we can easily detect when a file or folder is renamed (the renamed flag can't be got directly using inotifywait
).
In this example, the recursive parameter -r
is settled, so the script is going to watch all subfolders of the watched folder as well. For watching only a single folder just remove the -r
parameter... This is a generic solution that can be used for different situations when we want to execute specific actions based on changes that are happening on folders.
edited Jun 30 at 18:48
answered Jun 30 at 8:41
Ramuyko
299314
299314
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f444160%2fhow-can-i-execute-scripts-based-on-changes-that-are-happening-on-a-specific-fold%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Possibly useful, possibly even a dup: How to loop over ever-increasing list of files in bash?
â ilkkachu
May 16 at 13:36