ACLs являются ответом. Студентам не нужно никакое специальное разрешение работать setfacl
, пользователь может установить ACL любого файла, которым он владеет.
Если необходимо настроить систему для ACLs, посмотрите, Делают все новые файлы в каталоге доступными для группы
Скажите студентам, что, если им нужен файл, чтобы быть доступными для Apache, затем они должны работать
setfacl -m group:daemon:r ~/path/to/password.file
setfacl -m group:daemon:x ~ ~/path ~/path/to
x
разрешение на каталогах необходимо для файлов доступа (включая подкаталоги) в этих каталогах.
Некоторые общие принципы программирования оболочки:
"$foo"
означает значение переменной foo
, но $foo
вне кавычек подвергается последующей обработке."$(foo)"
.while read i; do …
снимает изоляцию с ведущего и запаздывающего пробела и обратных косых черт. Использовать while IFS= read pr i; do …
к производственным линейкам точно.find $filePath type -d
только каталоги списков.
Передача по каналу find
в while read
не является самым легким или большая часть устойчивого способа выполнить команду оболочки для каждого файла. Используйте -exec
действие в find
обработать файлы надежно, не попадая в беду с именами файлов, содержащими специальные символы, такие как пробел. При необходимости больше чем в одной команде вызвать sh
; обработать файл за один раз:
find … -exec sh -c 'command1 "$0"; command2 "$0"' {} \;
Для ускорения вещей немного можно использовать более сложную идиому который файлы групп сократить количество последовательных вызовов оболочки:
find … -exec sh -c 'for x; do command1 "$x"; command2 "$x"; done' _ {} +
Все проверки в начале Вашего сценария бесполезны или главным образом бесполезны. Вы не заботитесь, является ли аргументом символьная ссылка, например, и Ваше сообщение об ошибке в этом случае является неправильным.
Я предполагаю, что Ваш сценарий называют с двумя аргументами, исходным каталогом и целевым каталогом. Можно использовать mkdir -p
создать целевые каталоги по мере необходимости. Это помогает работать find
на текущем каталоге, чтобы избежать необходимости делать управление именем файла для вычислений путей назначения.
Звонить file
проверять тип файла на основе его содержания. Можно хотеть настроить форматы файлов, которые приняты.
cd "$1" || exit
find . -type f -exec sh -c '
# $0 = target directory; $1 = source file
case "$(file "$1");" in
video/x-flv\;*)
mkdir -p "$0/${1%/*}" # create target subdirectory if needed
cp -p "$1" "$0/$1" # copy the file under the same relative path
esac
' "$2" {} \;
Вот сценарий с рекурсивной функцией, которая делает то, что Вы искали:
#!/bin/bash
if [ "$#" -ne 1 ]; then
echo "usage: "$0" <search_dir>"
exit 1
fi
# recursive function to walk a directory tree
walktree() {
# $1 is the function parameter
local files=$(find "$1" -maxdepth 1 -type f) # find all files in the current dir
for file in $files; do # iterate through all found files
if [[ "$(file "$file")" == *video/x-flv* ]]; then # check the file content
echo "found one"
# put your copy code here
fi
done
local subdirs=$(find "$1" -maxdepth 1 -type d) # find all sub-directories
for dir in $subdirs; do # iterate through all sub-directories
if [ "$dir" != "$1" ]; then # omit the current directory
walktree "$dir" # call the recursive function
fi
done
}
walktree "$1" # first call with <search_dir>
Однако я все еще рекомендовал бы Вам просто использовать find . -type f
как объяснил Gilles.