inotify-tools

inotifywaitコマンドを使ったshellスクリプトで「逐次」作成されるファイルの動的処理を行ったが、
どうも漏れがある。つまり処理されないファイルが発生した

これは困った事態なのでスクリプトではなく、inotifyをC言語に組み込ませてみた
http://www.nminoru.jp/~nminoru/programming/file_change_notification.htmlを参考にしました
カメラ制御マシンから送られてくるmrc,tiffが保存し終えたら、引数のスクリプトが動く感じで。

あと一度処理が行われた対象ファイルには .touch を付けて、二度実行しないようにした

/*
  参照先:
  [http://www.nminoru.jp/~nminoru/programming/file_change_notification.html]
  gcc -Wall -o inotify inotify.c
 
 */
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h> /* for offsetof */
#include <string.h> /* for memmove */
#include <errno.h>
#include <limits.h>
#include <sys/inotify.h>
 
int main(int argc, char **argv)
{
    char cmd[512], basename[512], touch[512];
    char *pch = NULL, *temp;
    FILE *fp;
 
    if (argc != 4) {
        printf("Usage: inotify dir script work\n");
        exit(EXIT_SUCCESS);
    }
    if ( access(argv[2], 0) != 0 ){
        printf("run script %s not found\n", argv[2]);
        exit(EXIT_SUCCESS);
    }
 
    int fd  = inotify_init();
    if (fd == -1) {
        perror("inotify_init");
        exit(EXIT_FAILURE);
    }
    int wd = inotify_add_watch(fd, argv[1], IN_CLOSE_WRITE);
    if (wd < 0) {
            perror("inotify_add_watch");
            exit(EXIT_FAILURE);
    }
 
    for (;;) {
        int i, aux=0, ret;
        char buffer[65536];
    reread:
        ret = read(fd, buffer + aux, sizeof(buffer) - aux);
        if (ret == -1) {
            if (ret == -EINTR)
                goto reread;
            perror("read");
            exit(EXIT_FAILURE);
        }
        ret += aux;
 
        if (ret < sizeof(struct inotify_event)) {
            fprintf(stderr, "short of red bytes\n");
            exit(EXIT_FAILURE);
        }
        i = 0;
        while (i < ret) {
            struct inotify_event *inotify_p;
            inotify_p = (struct inotify_event *)(buffer + i);
 
            if (ret < i + offsetof(struct inotify_event, name)) {
                aux = ret - i;
                memmove(buffer, buffer + i, aux);
                goto reread;
            }
 
            int size = sizeof(struct inotify_event) + inotify_p->len;
            if (ret < i + size) {
                aux = ret - i;
                memmove(buffer, buffer + i, aux);
                goto reread;
            }
            if ( strstr(inotify_p->name , ".mrc" ) != NULL || strstr(inotify_p->name , ".tif" ) != NULL ){
               strcpy(basename, inotify_p->name);
 
               // make basename
               for ( temp = basename; (temp = strchr(temp, '.'))  != NULL; temp ++) pch = temp;
               if(pch !=NULL) *pch='\0';
 
               // make .touch file and run script
               sprintf(touch,"%s/.%s.touch", argv[1], basename );
               if( access( touch, 0) != 0 ){
                   fp=fopen( touch , "w");
                   fclose(fp);
                   sprintf(cmd,"%s %s/%s %s", argv[2], argv[1], inotify_p->name, argv[3] );
                   printf("%s\n",cmd);
                   system( cmd );
               }
 
            }
            i += size;
        }
    }
    close(fd);
    return 0;
}

未完成

実行

gcc -Wall -o inotify inotify.c
inotify  <監視対象フォルダ> <処理スクリプト> <解析word dir>
 
inotify  /<storage>/<ユーザ>/<電顕名>/SeralEM/data/<YYMMDD>/<GRID>/movie_frames/<square> \
         /Appl/bin/run.sh \
         /<dtorage>/<ユーザ>/Process/<プロジェクト名>/<square>

実行して、/opt/shareにファイル(mrc,tif)が届くと、

run.sh /<storage>/<ユーザ>/<電顕名>/SeralEM/data/<YYMMDD>/<GRID>/movie_frames/<square>/<tiffファイル> \
       /<storage>/<ユーザ>/Process/<プロジェクト名>/<square>

とかで実行される。ここで実行者はこのinotifyを実行したユーザになるので要注意

run.shは

#!/bin/bash
square=$(basename `dirname $1`)
file=$(basename $1)
 
cd $(dirname $1)/../../
if [ ! -d ./Movies/Link ]; then
   mkdir -p ./Movies/Link/
   echo "ok"
fi
cd ./Movies/Link/$square
 
# use simple lock for file numbering
if [ ! -f count ]; then
  echo 1 > count
fi
 
while :
do
   if [ ! -f lock ]; then
     ln -s count lock
     num=$(cat count)
     num=$(expr $num+1)
     echo $num > count
     rm lock
     break
   fi
done
ln -s ../../../movie_frames/$square/$file $square_`printf '%04d' $num`_movie.${$1##*.}
find ../../../movie_frames/$square -name SuperRef* -exec ln -s {} . \;
#
if [ ! -d ../../../Micrographs/$square ]; then
   mkdir ../../../Micrographs/$square
else
   exit
fi
#
#
/Appl/local/bin/MotionCor2 -InTiff Jun28_18.26.55.tif -OutMrc Jun28_18.26.55.mrc \
-Gain SuperRef_sq15_3.mrc <中略> -Gpu 0 > Jun28_18.26.55.out 2>> Jun28_18.26.55.err
 

この後にrelion偽装スクリプトを流す
計算が完了してからでもいいかも


トップ   編集 添付 複製 名前変更     ヘルプ   最終更新のRSS
Last-modified: 2017-06-30 (金) 19:09:07 (21d)