2009-10-07 4 views
9

Я немного искал и переполнял и не мог найти ничего полезного.Папка монитора для новых файлов с использованием сценария оболочки unix ksh или скрипта perl и сценария запуска perl

Мне нужен скрипт, который контролирует общую папку и запускает создание нового файла, а затем перемещает файлы в личное место.

У меня есть общая папка samba /exam/ple/ на unix, сопоставленная X:\ на окнах. При определенных действиях файлы txt записываются в общий ресурс. Я хочу похитить любой файл txt, который появляется в папке, и поместить его в личную папку /pri/vate на unix. После перемещения файла я хочу запустить отдельный скрипт perl.

EDIT Все еще жду, чтобы увидеть скрипт, если у кого есть какие-либо идеи ... что-то, что будет следить за новыми файлами, а затем запустить что-то вроде:

#!/bin/ksh 
mv -f /exam/ple/*.txt /pri/vate 
+1

Вам нужно сделать это программно или вы можете использовать существующие средства? для этого был создан cron. –

+0

Может ли cron быть вызван новым файлом? – CheeseConQueso

+0

Я также не хочу, чтобы cron запускал второй скрипт снова и снова ... я хочу, чтобы второй скрипт запускался после того, как новый файл был успешно перенесен в личную папку – CheeseConQueso

ответ

9

Проверьте incron. Кажется, он делает именно то, что вам нужно.

+0

это выглядит довольно прилично ... слишком плохо, я могу 't установить его: < – CheeseConQueso

+0

Отличный пример приветствия мирового типа incron: http://www.errr-online.com/2011/02/25/monitor-a-directory-or-file-for-changes-on- linux-using-inotify/ – mdaddy

+0

Может ли incron быть установлен в Windows? –

6

Если я правильно понимаю, вы просто хотите что-то вроде этого?

#!/usr/bin/perl 

use strict; 
use warnings; 

use File::Copy 

my $poll_cycle = 5; 
my $dest_dir = "/pri/vate"; 

while (1) { 
    sleep $poll_cycle; 

    my $dirname = '/exam/ple'; 

    opendir my $dh, $dirname 
     or die "Can't open directory '$dirname' for reading: $!"; 

    my @files = readdir $dh; 
    closedir $dh; 

    if (grep(!/^[.][.]?$/, @files) > 0) { 
     print "Dir is not empty\n"; 

     foreach my $target (@files) { 
      # Move file 
      move("$dirname/$target", "$dest_dir/$target"); 

      # Trigger external Perl script 
      system('./my_script.pl'); 
    } 
} 
+0

плохо проверить это .... это бесконечно бесконечно угадывает? также, im только ищет текстовые файлы, но Grep-бомба классная, чтобы иметь – CheeseConQueso

+1

@CheeseConQueso: Да, это бесконечный цикл while, опрос на заданной вами частоте. Я не строго тестировал код, но идея достаточно проста. –

+0

@CheeseConQueso: Вы можете, очевидно, модифицировать 'grep', чтобы игнорировать файлы с определенным суффиксом, если это ваша ситуация. –

1

Это приведет справедливый бит гипергликемии - стат() вызывает и тому подобное. Если вы хотите быстро уведомлений без выполнения накладных расходов (но более авансовых усилий), обратите внимание на FAM/dnotify: link text или link text

0
#!/bin/ksh 
while true 
do 
    for file in `ls /exam/ple/*.txt` 
    do 
      # mv -f /exam/ple/*.txt /pri/vate 
      # changed to 
      mv -f $file /pri/vate 

    done 
    sleep 30 
done 
+0

вот способ выполнить поиск каждые 30 секунд в оболочке korn, которую я нашел в Интернете ... он не срабатывает новый файл, его больше процесс cron-типа .... я все еще не могу найти сценарий оболочки korn, который работает при наличии нового файла – CheeseConQueso

+0

@ Cheese, это немного неуклюжий пример - если есть два файла в/exam/ple на одной итерации, тогда для тела будет выполняться дважды, но оба файла будут первыми пропущены через mv'ed. Таким образом, вы увидите ошибки во втором вызове mv. Нужны ли эти backticks? –

+0

@Martin - хорошая точка ... Я нашел его онлайн и не тестировал, поэтому я не уверен, нужны ли обратные сигналы. Я просто выразился здесь, потому что это был подход с оболочкой. Это также неудобно в том, что cron может делать то же самое – CheeseConQueso

2
$ python autocmd.py /exam/ple .txt,.html /pri/vate some_script.pl 

Преимущество:

  • легче установить, чем incron из-за pyinotify является чистым Python
  • событийное воздействие - меньше воздействия, чем the perl script

autocmd.py:

#!/usr/bin/env python 
"""autocmd.py 

Adopted from autocompile.py [1] example. 

[1] http://git.dbzteam.org/pyinotify/tree/examples/autocompile.py 

Dependencies: 

Linux, Python, pyinotify 
""" 
import os, shutil, subprocess, sys 

import pyinotify 
from pyinotify import log 

class Handler(pyinotify.ProcessEvent): 
    def my_init(self, **kwargs): 
     self.__dict__.update(kwargs) 

    def process_IN_CLOSE_WRITE(self, event): 
     # file was closed, ready to move it 
     if event.dir or os.path.splitext(event.name)[1] not in self.extensions: 
      # directory or file with uninteresting extension 
      return # do nothing 

     try: 
      log.debug('==> moving %s' % event.name) 
      shutil.move(event.pathname, os.path.join(self.destdir, event.name)) 
      cmd = self.cmd + [event.name] 
      log.debug("==> calling %s in %s" % (cmd, self.destdir)) 
      subprocess.call(cmd, cwd=self.destdir) 
     except (IOError, OSError, shutil.Error), e: 
      log.error(e) 

    def process_default(self, event): 
     pass 


def mainloop(path, handler): 
    wm = pyinotify.WatchManager() 
    notifier = pyinotify.Notifier(wm, default_proc_fun=handler) 
    wm.add_watch(path, pyinotify.ALL_EVENTS, rec=True, auto_add=True) 
    log.debug('==> Start monitoring %s (type c^c to exit)' % path) 
    notifier.loop() 


if __name__ == '__main__': 
    if len(sys.argv) < 5: 
     print >> sys.stderr, "USAGE: %s dir ext[,ext].. destdir cmd [args].." % (
      os.path.basename(sys.argv[0]),) 
     sys.exit(2) 

    path = sys.argv[1] # dir to monitor 
    extensions = set(sys.argv[2].split(',')) 
    destdir = sys.argv[3] 
    cmd = sys.argv[4:] 

    log.setLevel(10) # verbose 

    # Blocks monitoring 
    mainloop(path, Handler(path=path, destdir=destdir, cmd=cmd, 
          extensions=extensions)) 
+0

это выглядит пряным .... У меня нет python, но из того, что вы говорите о том, что уведомление является родным, мне, возможно, придется его установить и попробовать. . спасибо – CheeseConQueso

+0

CheeseConQueso: если http://search.cpan.org/~drolsky/File-ChangeNotify-0.07/lib/File/ChangeNotify/Watcher/Inotify.pm доступен подкласс, то File :: ChangeNotify, упомянутый @jsoversion, может сделать так же, как pyinotify. Быстрый поиск CPAN показал еще одно возможное решение http://search.cpan.org/~mlehmann/Linux-Inotify2-1.21/Inotify2.pm – jfs

+0

спасибо ... я проверю его – CheeseConQueso

1

Я не использую Ksh, но вот как я делаю это с ш. Я уверен, что он легко адаптируется к ksh.

#!/bin/sh 
trap 'rm .newer' 0 
touch .newer 
while true; do 
    (($(find /exam/ple -maxdepth 1 -newer .newer -type f -name '*.txt' -print \ 
     -exec mv {} /pri/vate \; | wc -l))) && found-some.pl & 
    touch .newer 
    sleep 10 
done 
+0

спасибо, плохо попробуйте преобразовать синтаксис и попробуйте – CheeseConQueso

3

Я опаздываю на вечеринку, я знаю, но в интересах полноты и предоставления информации будущим посетителям;

#!/bin/ksh 
# Check a File path for any new files 
# And execute another script if any are found 

POLLPATH="/path/to/files" 
FILENAME="*.txt" # Or can be a proper filename without wildcards 
ACTION="executeScript.sh argument1 argument2" 
LOCKFILE=`basename $0`.lock 

# Make sure we're not running multiple instances of this script 
if [ -e /tmp/$LOCKFILE ] ; then 
    exit 0 
else 
    touch /tmp/$LOCKFILE 
fi 

# check the dir for the presence of our file 
# if it's there, do something, if not exit 

if [ -e $POLLPATH/$FILENAME ] ; then 
    exec $ACTION 
else 
    rm /tmp/$LOCKFILE 
    exit 0 
fi 

Запустить его из cron;

*/1 7-22/1 * * * /path/to/poll-script.sh >/dev/null 2>&1

Вы хотели бы использовать локировки в вашем последующем сценарии ($ ACTION), а затем очистить его на выходе, просто так, у вас нет каких-либо процессов штабелирования.

Смежные вопросы