2009-11-20 3 views
4

У меня есть следующая ситуация:сценарий bash для просмотра папки

Существует папка с окнами, установленная на Linux-машине. Там может быть несколько папок (настройка перед рукой) в этом окне. Я должен что-то сделать (желательно сценарий для начала), чтобы смотреть эти папки.

Это следующие шаги: Следите за любыми входящими файлами. Убедитесь, что они полностью переданы. Переместите его в другую папку. У меня нет никакого контроля над программой передачи файлов на машине Windows. Я считаю, что это безопасный FTP. Поэтому я не могу попросить этот процесс отправить мне трейлер, чтобы обеспечить завершение передачи файла.

Я написал сценарий bash. Я хотел бы узнать о любых потенциальных препятствиях при таком подходе. Причина в том, что есть возможность копировать копии этого скрипта для нескольких каталогов, подобных этому.

На данный момент может быть до 100 каталогов, которые, возможно, необходимо будет контролировать.

Ниже приведен сценарий. Прошу прощения за вставку очень длинного здесь. Не тратьте время на просмотр, и комментировать/критиковать. :-)

Требуется 3 параметра: папка, на которую нужно смотреть, папку, в которую должен быть перемещен файл, и временной интервал, поясненный ниже.

Извините, но, похоже, проблема с выравниванием. Markdown, похоже, не нравится. Я попытался организовать его правильно, но не смог это сделать.

Linux servername 2.6.9-42.ELsmp #1 SMP Wed Jul 12 23:27:17 EDT 2006 i686 i686 i386 GNU/Linux

#!/bin/bash 
log_this() 
{ 
    message="$1" 
    now=`date "+%D-%T"` 
    echo $$": "$now ": " $message 
} 
usage() 
{ 
    cat << EOF 
Usage: $0 <Directory to be watched> <Directory to transfer> <time interval> 
Time interval is the amount of time after which the modification time of a 
file will be monitored. 
EOF 
    `exit 1` 
} 

if [ $# -lt 2 ] 
then 
    usage 
fi 

WATCH_DIR=$1 
APP_DIR=$2 

if [ ! -d "$WATCH_DIR" ] 
then 
    log_this "FATAL: WATCH_DIR, $WATCH_DIR does not exist. Exiting" 
    exit 1 
fi 

if [ ! -d "$APP_DIR" ] 
then 
    log_this "APP_DIR: $APP_DIR does not exist. Exiting" 
    exit 1 
fi 


# This needs to be set after considering the rate of file transfer. 
# Represents the seconds elapsed after the last modification to the file. 
# If not supplied as parameter, defaults to 3. 

seconds_between_mods=$3 

if ! [[ "$seconds_between_mods" =~ ^[0-9]+$ ]]; then 
     if [ ${#seconds_between_mods} -eq 0 ]; then 
       log_this "No value supplied for elapse time. Defaulting to 3." 
       seconds_between_mods=3 
     else 
       log_this "Invalid value provided for elapse time" 
       exit 1 
     fi 
fi 

log_this "Start Monitor." 

while true 
do 
     ls -1 $WATCH_DIR | while read file_name 
     do 
      log_this "Start Monitoring for $file_name" 

      # Refer only the modification with reference to the mount folder. 
      # If there is a diff in time between servers, we are in trouble. 

      token_file=$WATCH_DIR/foo.$$ 
      current_time=`touch $token_file && stat -c "%Y" $token_file` 
      rm -f $token_file 2>/dev/null 

      log_this "Current Time: $current_time" 
      last_mod_time=`stat -c "%Y" $WATCH_DIR/$file_name` 

      elapsed_time=`expr $current_time - $last_mod_time` 
      log_this "Elapsed time ==> $elapsed_time" 

      if [ $elapsed_time -ge $seconds_between_mods ] 
      then 
        log_this "Moving $file_name to $APP_DIR" 

        # In case if there is no space left on the target mount, hide the  file 
        # in the mount itself and remove the incomplete file from APP_DIR. 
        mv $WATCH_DIR/$file_name $APP_DIR 
        if [ $? -ne 0 ] 
        then 
          log_this "FATAL: mv failed!! Hiding $file_name" 
          rm $APP_DIR/$file_name 
          mv $WATCH_DIR/$file_name $WATCH_DIR/.$file_name 
          log_this "Removed $APP_DIR/$file_name. Look for $WATCH_DIR/.$file_name and submit later." 
        fi 

        log_this "End Monitoring for $file_name" 
      else 
        log_this "$file_name: Transfer seems to be in progress" 
      fi 
    done 
    log_this "Nothing more to monitor." 
    echo 
    sleep 5 
done 
+0

Возможный дубликат [Monitor Directory for Changes] (http://stackoverflow.com/questions/511463/monitor-directory-for-changes) –

ответ

5

Это не будет работать какое-то время. В процессе производства у вас будут проблемы с сетью и другие ошибки, которые могут оставить частичный файл в каталоге загрузки. Мне также не нравится идея файла «трейлер». Обычный подход заключается в том, чтобы загрузить файл под временным именем, а затем переименовать его после завершения загрузки.

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

Если вы не можете внести это изменение, обратитесь к своему начальнику за письменным разрешением, чтобы реализовать что-то, что может привести к произвольному повреждению данных. Это делается для двух целей: 1) заставить их понять, что это настоящая проблема, а не то, что вы составляете, и 2) защитить себя, когда она ломается ... потому что она будет и догадаться, кто получит всю вину?

1

Чтобы быть честным питон Настройка приложения для запуска при запуске будет делать это быстро и эффективно. У Python есть потрясающая поддержка ОС и ее довольно полная.

Запуск сценария, скорее всего, будет работать, но будет хлопотно заботиться и управлять. Полагаю, вы запустите их как частые рабочие задания cron?

+0

Хммм. У меня нет знаний питона. Можете ли вы указать мне на пакет или модуль python (я не уверен в терминологии), которые могут помочь в этом? Благодарю. – prabhu

+0

1. Следуйте руководству python на сайте www.python.org, 2. посмотрите модуль os.path. Он имеет метод walk(), который вы можете использовать для изучения дерева каталогов. –

+0

Pynotify - это библиотека python, которая должна быть уведомлена об изменениях в каталоге: http://pyinotify.sourceforge.net –

4

Я считаю, что более здравым подходом было бы использование уведомления об элементах файловой системы на уровне ядра. Например, inotify. Получите также инструменты here.

+0

Inotify - это правильный способ сделать это. Но на данный момент я не могу исправлять наше ядро, чтобы установить его. – prabhu

0

Чтобы убрать вас с ног, вот небольшое приложение, которое я написал, которое берет путь и смотрит на двоичный вывод jpeg-файлов. Я никогда не закончил его, но он поможет вам начать работу и посмотреть структуру python, а также некоторое использование os.

Я бы не потратил много времени, беспокоясь о своем коде.

import time, os, sys 

#analyze() takes in a path and moves into the output_files folder, to then analyze files 

def analyze(path): 
    list_outputfiles = os.listdir(path + "/output_files") 
    print list_outputfiles 
    for i in range(len(list_outputfiles)): 
     #print list_outputfiles[i] 
     f = open(list_outputfiles[i], 'r') 
     f.readlines() 

#txtmaker reads the media file and writes its binary contents to a text file. 

def txtmaker(c_file): 
    print c_file 
    os.system("cat" + " " + c_file + ">" + " " + c_file +".txt") 
    os.system("mv *.txt output_files") 

#parser() takes in the inputed path, reads and lists all files, creates a directory, then calls txtmaker. 

def parser(path): 
    os.chdir(path) 
    os.mkdir(path + "/output_files", 0777) 
    list_files = os.listdir(path) 
    for i in range(len(list_files)): 
     if os.path.isdir(list_files[i]) == True: 
      print (list_files[i], "is a directory") 
     else: 
      txtmaker(list_files[i]) 
    analyze(path) 

def main(): 
    path = raw_input("Enter the full path to the media: ") 
    parser(path) 


if __name__ == '__main__': 

    main() 
1

incron является "Inotify хрон" системы. Он состоит из демона и манипулятора стола. Вы можете использовать его так же, как обычный cron. Разница заключается в том, что inotify cron обрабатывает события файловой системы, а не периоды времени.

2

Сначала убедитесь, что inotify-tools в установленном состоянии.

Затем используйте их так:

logOfChanges="/tmp/changes.log.csv" # Set your file name here. 

# Lock and load 
inotifywait -mrcq $DIR > "$logOfChanges" & # monitor, recursively, output CSV, be quiet. 
IN_PID=$$ 

# Do your stuff here 
... 

# Kill and analyze 
kill $IN_PID 
cat "$logOfChanges" | while read entry; do 
    # Split your CSV, but beware that file names may contain spaces too. 
    # Just look up how to parse CSV with bash. :) 
    path=... 
    event=... 
    ... # Other stuff like time stamps 
    # Depending on the event… 
    case "$event" in 
    SOME_EVENT) myHandlingCode path ;; 
    ... 
    *) myDefaultHandlingCode path ;; 
done 

В качестве альтернативы, используя --format вместо -c на inotifywait бы идея.

Всего man inotifywait и man inotifywatch для получения дополнительной информации.

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