inotify 和 bash

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7542430/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 21:04:30  来源:igfitidea点击:

inotify and bash

bashinotify

提问by user963091

I am trying to make a bash script with inotify-tools that will monitor a directory and alter all new files by removing lines containing "EE". Once altered it will move the files to another directory

我正在尝试使用 inotify-tools 制作一个 bash 脚本,该脚本将监视目录并通过删除包含“EE”的行来更改所有新文件。更改后,它将文件移动到另一个目录

    #!/bin/sh
    while inotifywait -e create /home/inventory/initcsv; do
      sed '/^\"EE/d' Filein > fileout #how to capture File name?
      mv fileout /home/inventory/csvstorage
    fi
    done

Please help?

请帮忙?

回答by James Waldby - jwpat7

By default, the text output from inotifywait -e CREATEis of form

默认情况下,输出的文本inotifywait -e CREATE格式为

     watched_filename CREATE event_filename

where watched_filenamerepresents /home/inventory/initcsvand event_filenamerepresents the name of the new file.

其中 watched_filename代表/home/inventory/initcsvevent_filename代表新文件的名称。

So, in place of your while inotifywait -e ...line, put:

所以,代替你的while inotifywait -e ...行,把:

    DIR=/home/inventory/initcsv
    while RES=$(inotifywait -e create $DIR); do
        F=${RES#?*CREATE }

and in your sedline use $Fas the Fileinname. Note, the $(...)construction is posix-compatible form of process substitution (often done using backticks) and the ${RES#pattern}result is equal to $RESwith the shortest pattern-matching prefix removed. Note, the last character of the pattern is a blank. [See update 2]

并在您的sed行中$F用作Filein名称。请注意,该$(...)构造是过程替换的 posix 兼容形式(通常使用反引号完成)并且${RES#pattern}结果等于$RES删除了最短的模式匹配前缀。请注意,模式的最后一个字符是空格。 [见更新2]

Update 1To handle file names that may contain whitespace, in the sed line use "$F"instead of $F. That is, use double quotes around the reference to value of F.

更新1处理可能包含空格,在SED线使用的文件名"$F"来代替$F。也就是说,在对 的值的引用周围使用双引号F

The RES=...and F=...definitions do not need to use double quotes, but it is ok to use them if you like; for example: F=${RES#?*CREATE }and F="${RES#?*CREATE }"both will work ok when handling filenames containing whitespace.

RES=...F=...定义并不需要使用双引号,但它也可以,如果你喜欢使用它们; 例如: 当处理包含空格的文件名时F=${RES#?*CREATE }F="${RES#?*CREATE }"两者都可以正常工作。

Update 2As noted in Daan's comment, inotifywaithas a --formatparameter that controls the form of its output. With command

更新 2正如 Daan 的评论中所指出的,inotifywait有一个--format控制其输出形式的参数。用命令

while RES=$(inotifywait -e create $DIR --format %f .)
   do echo RES is $RES at `date`; done

running in one terminal and command

在一个终端和命令中运行

touch a aa; sleep 1; touch aaa;sleep 1; touch aaaa

running in another terminal, the following output appeared in the first terminal:

在另一个终端中运行,第一个终端中出现以下输出:

Setting up watches.
Watches established.
RES is a at Tue Dec 31 11:37:20 MST 2013
Setting up watches.
Watches established.
RES is aaa at Tue Dec 31 11:37:21 MST 2013
Setting up watches.
Watches established.
RES is aaaa at Tue Dec 31 11:37:22 MST 2013
Setting up watches.
Watches established.

回答by Jonathan Leffler

The output from inotifywaitis of the form:

的输出inotifywait格式为:

filename eventlist [eventfilename]

If your file names can contain spaces and commas, this gets tricky to parse. If it only contains 'sane' file names, then you can do:

如果您的文件名可以包含空格和逗号,则解析起来会很棘手。如果它只包含“理智”的文件名,那么你可以这样做:

srcdir=/home/inventory/initcsv
tgtdir=/home/inventory/csvstorage
inotifywait -m -e create "$directory" |
while read filename eventlist eventfile
do
    sed '/^"EE/d'/' "$srcdir/$eventfile" > "$tgtdir/$eventfile" &&
    rm -f "$srcdir/$eventfile
done

回答by bmargulies

Quoting the man page of inotifywait:

引用 inotifywait 的手册页:

inotifywait will output diagnostic information on standard error and event information  on
   standard  output.  The event output can be configured, but by default it consists of lines
   of the following form:

   watched_filename EVENT_NAMES event_filename

   watched_filename
          is the name of the file on which the event occurred.  If the file is a directory, a
          trailing slash is output.

In other words, it prints the names of the files to standard output. So, you need to read them from standard output and operate on them to do what you want to do.

换句话说,它将文件名打印到标准输出。因此,您需要从标准输出中读取它们并对它们进行操作以执行您想做的操作。