inotifywait ação diferente no arquivo ou dir

3

Estou tentando fazer com que um script inotifywait execute ações diferentes para arquivos vs pastas, se ele vir um sinalizador close_write sendo gerado no diretório observado, mas não conseguir que as verificações funcionem.

Em outros scripts eu uso esse tipo de checagem o tempo todo e eles apenas funcionam, mas parece haver algo sobre inotifywait que eu não estou entendendo ainda.

Este é o script na sua forma atual:

    #!/bin/bash

    dir1=/sambashares

    while true; do
     inotifywait -r -e close_write "$dir1" | while read f; do
      #debug
      echo $f
      #Is it a directory?
      if [[ -d "${f}" ]]; then
       #debug
       echo "New directory called ${f} detected"
       chown -R jake:jake $f
       chmod -R 775 $f
       cp -R $f /media/lacie/Film
      fi
      #Is it a file?
      if [[ -f "${f}" ]]; then 
      #debug
      echo "New file called ${f} detected"
      chown jake:jake $f
      chmod 775 $f
      cp $f /media/lacie/Film
      fi

     done
    done

Se eu executar isso em um terminal para ver o que está acontecendo, tudo que eu obtenho é a confirmação de um close_write detectado, seguido por uma "configuração de relógios" sem nenhuma outra mensagem ou qualquer outro código sendo acionado, nem mesmo depurar o eco diretamente abaixo:

 while read f; do

: - (

Estou executando isso no servidor Ubuntu 12.04 LTS de 64 bits.

$ bash --version
GNU bash, version 4.2.25(1)-release (x86_64-pc-linux-gnu)

$ dpkg -l | grep inotify
ii  inotify-tools                    3.13-3
ii  libinotifytools0                 3.13-3
ii  python-pyinotify                 0.9.2-1

$ python --version
Python 2.7.3
    
por Jake 30.05.2014 / 22:11

2 respostas

2

O seguinte funciona para mim:

Exemplo

Abaixo, mostra um exemplo de inotifywait usando um método semelhante ao seu.

$ inotifywait -r -e close_write "somedir" | while read f; do echo "$f hi";done
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.    

Eu entro no diretório somedir e toque em afile, touch afile . O que resulta disso na janela inotifywait :

somedir/ CLOSE_WRITE,CLOSE afile hi

OBSERVAÇÃO: Para obter todos os resultados de inotifywait , você pode modificar um pouco seu exemplo:

$ inotifywait -r -e close_write "somedir" 2>&1 | \
    while read f; do echo "$f | hi";done
Setting up watches.  Beware: since -r was given, this may take a while! | hi
Watches established. | hi

E, novamente, toque em um arquivo com o comando touch afile . Agora vejo o evento:

somedir/ CLOSE_WRITE,CLOSE afile | hi

Para outro exemplo que mostra como usar inotifywait , dê uma olhada no exemplo que mostrei em minha resposta a este P & A intitulado: Detecta automaticamente quando um arquivo atinge um limite de tamanho .

Seu problema

Acredito que parte do seu problema é que você está assumindo que a saída retornada de inotifywait é apenas o nome do arquivo, embora claramente não seja dos exemplos acima.

Portanto, essas declarações if nunca serão bem-sucedidas:

  if [[ -d "${f}" ]]; then

and

  if [[ -f "${f}" ]]; then 

Ao desenvolver scripts Bash como esse, geralmente é útil ativar as mensagens de depuração por meio deste comando na parte superior:

set -x

Você pode desativá-lo com isto:

set +x

Você pode agrupar seções do seu código usando essas mensagens para ativá-lo / desativá-lo.

set -x
...code...
set +x
    
por 30.05.2014 / 23:44
0

Funcionou graças ao slm de informações fornecido: -)

#!/bin/bash

# Written by Jan Duprez and licensed as
# do whatever you want with this but don't come whining
# if you somehow manage to trash your system with it.
# You pressed the buttons, remember?

# This script uses inotifywait to watch a directory and copies
# files or directories moved into it to another folder.

# The commandline parameters are:
# 1 - Directory to watch
# 2 - Directory where new file/folder is copied to
# 3 - UID to use to chmod the file/folder in BOTH dirs
# 4 - GID to use to chmod the file/folder in BOTH dirs
# 5 - permissions to set for the new file/folder in BOTH dirs

dir1=$1
dir2=$2
user=$3
group=$4
perms=$5

# Check if commandline parameters are all there, show reminder if not
if [[ -z $dir1 || -z $dir2 || -z $user || -z $group || -z $perms ]];
then    
    echo -e "Please provide a source dir as 1st parameter"
            echo -e "Please provide a dest dir as 2nd parameter"
            echo -e "Please provide a UID as 3rd parameter"
            echo -e "Please provide a GID as 4th parameter"
            echo -e "Please provide a file permission string (ex 755) as 5th parameter"
    exit
fi

# Good to go, start watching
while true; do

#add -e close_write and -e create for testing
inotifywait -r -e move "$dir1" | while read f; do

#Get part after inotify triggers with awk, remove leading spaces with sed
new='echo $f | awk '{$1=$2=""; print $0}' | sed 's/^ *//''
#And the preconstruded full path to avoid ugly buggery between the  [[ ]]    test
test=$dir1$new

    if [[ -d "${test}" ]] ; then
    chown -R $user:$group "$dir1$new"
    chmod -R $perms "$dir1$new"
    cp -R "$dir1$new" "$dir2"
    chown -R $user:$group "$dir2$new"
    fi

    if [[ -f "${test}" ]] ; then
    chown $user:$group "$dir1$new"
    chmod $perms "$dir1$new"
    cp "$dir1$new" "$dir2"
    chown $user:$group "$dir2$new"
    fi
done
done
    
por 08.06.2014 / 22:27