1

I came to this post (Monitor folder and run command if there is a file there?) about monitoring folders and then execute an action on found files. Everything works, but now I want to add a ".tmp" extension while files are being moved and then removing the .tmp extension again. However, instead of first moving to a .tmp file it moves the file back to a .mkv file.

So lets say I do:

cp /home/j-j/test/move_script/tv/tv_s01e01.mkv /home/j-j/test/move_script/transcoded_tv/
  • tv_s01e01.mkv is being copied to transcoded_tv
  • meanwhile tv_s01e01.mkv is recognised by inotifywait
  • file is copied to watched_tv as tv_s01e01.mkv instead of to tv_s01e01.mkv.tmp first.

The solution is probably something easy, but can't find the solution. If anyone can help me? Below you can find the script.

#!/bin/bash
## set path to watch
movies="/home/j-j/test/move_script/transcoded_movies"
tv="/home/j-j/test/move_script/transcoded_tv"


## set path to copy the script to
watchedMovies="/home/j-j/test/move_script/watched_movies"
watchedTv="/home/j-j/test/move_script/watched_tv"

## Inotify Monitor
inotifywait -m -r -e moved_to -e create "$movies" "$tv" --format "%f" | while read f
## Inotify Daemon
# inotifywait -d -r -e moved_to -e create "$movies" "$tv" --format "%f" | while read f

do
    echo $f
    shopt -s nocasematch
   ## check if file is a tv show
    if [[ $f == *S[0-9][0-9]E[0-9][0-9]* ]] ; then
    mediaType=$tv
    watchedDir=$watchedTv
   ## file is a movie
    else
    mediaType=$movies
    watchedDir=$watchedMovies
    fi
   ## check if the file is not a cache file and is a .mkv file
    if [[ $f != *TdarrCacheFile* ]] && [[ $f = *.mkv ]] ; then
   ## creating temporary file first and then revert to mkv
    mv "$mediaType/$f" "$watchedDir/$f.tmp" && mv "$watchedDir/$f.tmp" "$watchedDir/$f"
   ## and rum it
    /bin/bash "$watchedDir/$f" &
    fi
done
J-J
  • 23
  • 4

2 Answers2

2

file is copied to watched_tv as tv_s01e01.mkv instead of to tv_s01e01.mkv.tmp first.

No, it's moved as tv_s01e01.mkv.tmp, first, then renamed to tv_s01e01.mkv instantly ... To see it in action, run your script with the -x flag which will enable debugging/tracing the execution of your script like so:

bash -x scriptfile

Remarks:

  • /bin/bash "$watchedDir/$f" & is not the right way to run media files ... You should use a media player application instead of /bin/bash.

  • Use read with the option -r i.e. read -r to prevent mangling backslashes.

  • Double quote your variables whenever they are used in your script like echo "$f" to prevent globbing and word splitting.

  • Always check your scripts at ShellCheck ... shellcheck is also available as a package that you can install and use locally.

Raffa
  • 24,905
  • 3
  • 35
  • 79
  • Thanks for clearing this out. Then I need to find an other solution. The $watchDir is also monitored by another process who moves those files to my media library. When a file is copied to the transcoded_tv/transcoded_movies it may take a few minutes. Inotify will **instantly** move the file to the $watchedDir, instead of waiting until the file is completed copied and the other process (Sonarr/Radarr) will already move the file to my media library before it was completly copied. To prevent this last behaviour, I thouth of creating a file with ".tmp" first. But that doesn't seem to work. – J-J Aug 08 '22 at 11:37
  • Thanks for all your suggestions. **`/bin/bash "$watchedDir/$f" & is not the right way to run media files ... You should use a media player application instead of /bin/bash.`** I don't need this line, I forgot to comment it out. **`- Use read with the option -r i.e. read -r to prevent mangling backslashes - Double quote your variables whenever they are used in your script like echo "$f" to prevent globbing and word splitting.`** I adapted the code. – J-J Aug 08 '22 at 11:37
  • @J-J You can use `inotifywait -m -r -e close_write` instead of `inotifywait -m -r -e moved_to -e create` so that the file is not processed by `inotifywait` in the watched directories until it is completely copied and closed for writing. – Raffa Aug 08 '22 at 11:51
  • 1
    Thanks, this actually fixed my script – J-J Aug 08 '22 at 17:31
1

Final script:

#!/bin/bash
## set path to watch
movies="/home/j-j/test/move_script/transcoded_movies"
tv="/home/j-j/test/move_script/transcoded_tv"

## set path to copy the script to
watchedMovies="/home/j-j/test/move_script/watched_movies"
watchedTv="/home/j-j/test/move_script/watched_tv"

## Inotify Monitor
inotifywait -m -r -e close_write "$movies" "$tv" --format "%f" | while read -r f
## Inotify Daemon
# inotifywait -d -r -e close_write "$movies" "$tv" --format "%f" | while read -r f

do
  echo "$f"
  shopt -s nocasematch
  if [[ $f == *S[0-9][0-9]E[0-9][0-9]* ]] ; then
    mediaType=$tv
    watchedDir=$watchedTv
  else
    mediaType=$movies
    watchedDir=$watchedMovies
  fi
  ## check if the file is a .mkv file
  if [[ $f != *TdarrCacheFile* ]] && [[ $f = *.mkv ]] ; then
    # if so, move the file to the target dir
    mv "$mediaType/$f" "$watchedDir"
  fi
done
J-J
  • 23
  • 4