还在学习,我迷失了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 =&#39;无论什么&#39;定义字段分隔符,但我不想在生产过程中弄乱它;它有效,但当我无法获得上传文件的用户的用户名时,它会让我很烦。请给我一个提示。
答案 0 :(得分: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 offered a workaround:
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