0

仍在学习,我迷失了 IFS=

#!/bin/bash
inotifywait -m -r --excludei '(.txt$|.old$|.swp$|.swx$|.swpx$|.zip$)' /path/to/watch -e create |
    while read path action file; do
        cd $path
        USER="$(stat -c %U $file)"
        echo "To: User <user@domain.com>
CC: Support <user@domain.com>
From: $USER <user@domain.com>
Subject: $USER has Uploaded a new File

The user '$USER' uploaded the file '$file' to '$path'" >  /mnt/remote/ian/temp2.txt
    cat /path/to/temp/file.txt | ssmtp list@domain.com
    rm /path/to/temp/file.txt
done

这是我的第一个脚本,只要上传的文件名中没有空格,它就可以很好地工作。我已经阅读了一些使用 IFS= 'whatever' 来定义字段分隔符的脚本,但我不想在生产时搞乱它;它可以工作,但是当我无法获取上传文件的用户的用户名时,这让我很恼火。请给我一个提示。

4

1 回答 1

1

知道您的实现并想要欺骗任意数据(通过使用换行符创建文件名)的攻击者可以打破这一点,但这是一个粗略的初稿:

while IFS= read -r -d $'\n' path && IFS= read -r -d $'\n' file; do
    user=$(stat -c %U "$file")
    printf 'File %q created by %q in %q\n' "$file" "$user" "$path"
done < <(inotifywait --format $'%w\n%f\n' ~/tmp -r -e create)

我强烈建议向上游 inotifytools 提交一张票,请求能够\0在格式字符串中使用。


顺便说一句,这已经在 inotify-tools 邮件列表中提出, Stephane Chazelas 提供了一个解决方法

nl="
"
inotifywait --syslog -e close_write -mr /tmp --format '%f///' |
  while IFS= read -r file; do
    while :; do
      case $file in
        (*///) file=${file%///}; break
      esac
      IFS= read -r extra || exit
      file=$file$nl$extra
    done

    something with "$file"

  done
于 2015-03-30T21:36:38.673 回答