2015-03-30 10 views
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 <[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 

Это был мой первый сценарий, и он прекрасно работает до тех пор, пока нет пробелов в имена файлов, которые загружаются. Я прочитал несколько сценариев, которые используют IFS = 'whatever' для определения разделителей полей, но я не хочу обходиться с этим, пока он находится в процессе производства; он работает, но меня это раздражает, когда я не могу получить имя пользователя, загрузившего файл. Пожалуйста, дайте мне подсказку.

+0

КРОССПОСТИНГ: http://serverfault.com/q/679424/234750 – Cyrus

+0

С inotifywait-х форматированные строки не поддерживают '\ 0' - единственный символ, который не может легально существовать в имени файла - там буквально * не * возможно 100% -ное решение. –

+0

@CharlesDuffy вот что я боялся ... – snowexcuse

ответ

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) 

Я настоятельно рекомендую подав билет с upstream inotifytools, запрашивающий возможность использования \0 в строках формата.


Кстати, это уже воспитаны на Inotify-инструментов Список рассылки, где 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