Reputation: 3
Still learning and I'm getting lost with 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 <[email protected]>
CC: Support <[email protected]>
From: $USER <[email protected]>
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 [email protected]
rm /path/to/temp/file.txt
done
This was my first ever script and it works great as long as there are no spaces in the the file names that get uploaded. I've read some scripts that use IFS= 'whatever' to define the field separators but I don't want to mess around with this while it's in production; it works, but it annoys me when I can't get the username of the user who uploaded the file. Please give me a hint.
Upvotes: 0
Views: 257
Reputation: 295281
This can be broken by an attacker who knows your implementation and wants to spoof arbitrary data (by creating filenames with newlines), but it's a rough first draft:
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)
I'd strongly suggest filing a ticket with upstream inotifytools requesting the ability use \0
in format strings.
Incidentally, this has already been brought up on the inotify-tools mailing list, where 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
Upvotes: 1