Executa o comando automaticamente quando os arquivos são copiados em um diretório

3

Eu tenho duas pastas chamadas: A e B, em caminhos diferentes no mesmo computador. Quando eu adiciono qualquer novo arquivo (s) na pasta A, eu quero copiá-lo para a pasta B automaticamente.

Minhas pastas:

/auto/std1/nat1/A
/auto/std2/nat2/B

O que eu faço atualmente para copiar os arquivos:

cp -r A B

Mas quero que esse processo seja executado automaticamente em segundo plano para cada novo arquivo e pasta em A em B .

Adicionada questão / problema

Ao copiar arquivos, eu gostaria que ações específicas fossem executadas em determinados tipos de arquivos, por exemplo: quando eu tenho um arquivo zip na pasta A , eu gostaria que ele fosse unzip desse arquivo na pasta B automaticamente.

Isso está em um sistema do CentOS 7 '.

    
por Gilles 23.02.2015 / 17:17

3 respostas

3

Por sua pergunta de bônus, adicione a seguinte linha abaixo do comando rsync no script de shell que forneci abaixo. Eu escrevi isso no comentário, mas vou adicioná-lo oficialmente à minha resposta aqui:

    find /auto/std2/nat2/B -name '*.zip' -exec sh -c 'unzip -d 'dirname {}' {}' ';'

Isso manipulará a descompactação de todos os arquivos zip copiados via rsync da pasta /auto/std2/nat2/A para /auto/std2/nat2/B


Se você tem rsync instalado, por que não apenas o cron dele e tem rsync gerenciando o espelhamento de arquivos?

Criar script myrsyncscript.sh

Não se esqueça de torná-lo executável: chmod 700 myrsyncscript.sh

#!/bin/sh

LOCKFILE=/tmp/.hiddenrsync.lock

if [ -e $LOCKFILE ]
        then
        echo "Lockfile exists, process currently running."
        echo "If no processes exist, remove $LOCKFILE to clear."
        echo "Exiting..."
#        mailx -s "Rsync Lock - Lock File found" [email protected] <<+
#Lockfile exists, process currently running.
#If no processes exist, remove $LOCKFILE to clear.
#+
        exit
fi

touch $LOCKFILE
timestamp='date +%Y-%m-%d::%H:%M:%s'
echo "Process started at: $timestamp" >> $LOCKFILE

## Run Rsync if no Lockfile
rsync -a --no-compress /auto/std1/nat1/A /auto/std2/nat2/B


echo "Task Finished, removing lock file now at 'date +%Y-%m-%d::%H:%M:%s'"
rm $LOCKFILE

Discriminação de opções:

-a is for archive, which preserves ownership, permissions etc.
--no-compress as there's no lack of bandwidth between local devices

Opções adicionais que você pode considerar man rsync :

--ignore-existing

skip updating files that exist on receiver

--update

This forces rsync to skip any files which exist on the destination and have a modified time that is newer than the source file. (If an existing destination file has a modification time equal to the source file’s, it will be updated if the sizes are different.) Note that this does not affect the copying of symlinks or other special files. Also, a difference of file format between the sender and receiver is always considered to be important enough for an update, no matter what date is on the objects. In other words, if the source has a directory where the destination has a file, the transfer would occur regardless of the timestamps.

This option is a transfer rule, not an exclude, so it doesn’t affect the data that goes into the file-lists, and thus it doesn’t affect deletions. It just limits the files that the receiver requests to be transferred.

Adicione-o ao cron e defina a frequência para o que lhe for mais conveniente:

Abra o cron com crontab -e e adicione o abaixo:

### Every 5 minutes
*/5 * * * * /path/to/my/script/myrsyncscript.sh > /path/to/my/logfile 2>&1 

# * * * * *  command to execute
 # │ │ │ │ │
 # │ │ │ │ │
 # │ │ │ │ └───── day of week (0 - 6) (0 to 6 are Sunday to Saturday, or use names; 7 is Sunday, the same as 0)
 # │ │ │ └────────── month (1 - 12)
 # │ │ └─────────────── day of month (1 - 31)
 # │ └──────────────────── hour (0 - 23)
 # └───────────────────────── min (0 - 59)
    
por 23.02.2015 / 17:27
2

Você pode usar o que o DevNull sugeriu que rsyncs periodicamente. Pessoalmente eu usaria inotify . É uma ferramenta bacana que você pode dar uma pasta para assistir. Ele configura os relógios e notifica você sempre que ocorrer uma alteração no sistema de arquivos. Você poderia, então, disparar um rsync baseado no gatilho de inotify .

Para o caso específico no final do qual você fala, você pode usar o gatilho de inotify para ver qual alteração aconteceu e então escrever um script bash simples para verificar se é um arquivo zip que foi adicionado à pasta A e Se for, você pode simplesmente descompactá-lo para a pasta B (ou qualquer outra coisa que você gostaria de fazer) em vez de simplesmente copiar o zip.

    
por 23.02.2015 / 18:16
2

Implementando a sugestão do @ Izkata usando o inotifywait com a resposta do evento estimulado para manter os rsyncs no máximo em 1 a cada 5 minutos enquanto ainda responde rapidamente às alterações iniciais:

#!/bin/sh
# usage: whateveryouwanttotcallthis "$directorytowatch" rsync args here

cd "$1" || { echo "${0##*/}: can't cd to $1"; exit 1; }
shift
rsync -nq "$@" || { echo "rsync doesn't like your $# arguments $@"; exit 1; }

notbefore=0
watchlock=.lock.inotifywait
rsynclock=.lock.rsync-pending

mkdir $watchlock ||
       { echo "${0##*/}: already running, rmdir '$PWD/$watchlock' if kill -9 took it out"
         exit 1;
       }
trap "rmdir '$watchlock'" 0 1 2 3 15

inotifywait -m -e close-write . |    # maybe also add move
        while read; do
                mkdir $rsynclock 2>&- || continue
                schedule=$(( notbefore <= (now='date +%s'+2) ? (now+2)
                                                           : (notbefore) ))
                notbefore=$((schedule+300))
                ( ( trap "rmdir '$rsynclock'" 0 1 2 3 15
                    sleep $(( schedule-now ))
                  )
                  # substitute your payload here
                  rsync --exclude='.lock.*' "$@" \
                          || echo ssia | mail -s "${0##*/} '$PWD' rsync failed" opswatch
                ) &
        done

O atraso de dois segundos ajuda a agrupar pequenos disparos e permite tempo para renomear algumas coisas quando uma gravação é concluída. Talvez 15 segundos seja melhor.

Não é possível testar, no windows atm, espero e acredito que seja pelo menos muito próximo.

    
por 24.02.2015 / 20:44