Я хочу сделать небольшой скрипт оболочки, который показывает все файлы в дереве файлов, начиная с заданного каталога, у которого заданный пользователь и размер больше заданного размера. Следовательно, мой скрипт будет принимать в качестве параметров каталог, с которого нужно начать, имя пользователя и размер. Это то, что я до сих пор имею:
#!/bin/bash
owner="valdsilviufarcas"
size=0
function display_owner_and_size()
{
owner=`stat --format "%s" $1`
size=`stat --format "%U" $1`
}
function search()
{
for elem in $1/*
do
display_owner_and_size "$elem"
if [[ $owner == $2 && $size > $3 ]]
then
echo $elem
fi
if test -d "$elem"
then
search "$elem" $2 $3
fi
done
}
search $1 $2 $3
Однако, я продолжаю получать эту ошибку: Cannot stat: (bla-bla-bla) : No such file or directory
. Почему функция stat не работает?
Необходимо просто использовать эти find
команда:
find ${dir} -user ${user} -type f -size +${size}c -printf "%u\t%s\t%h/%f\n"
Замена переменные Bash ${dir}
с каталогом для исследования рекурсивно, ${user}
с именем пользователя или UID, который должен быть отображен только и ${size}
с минимальным размером файла в байтах (не включительно! при использовании значения 100
самый маленький файл, который отображен, может иметь 101 байт).
Эта команда только распечатает регулярные файлы, она игнорирует каталоги и специальные файлы как символьные ссылки или устройства в выводе.
Существует два других вопроса.
Первый, Вы не заключаете свои переменные в кавычки: это в конечном счете делает stat
сбой по этой причине:
search $1 $2 $3
должен быть search "$1" "$2" "$3"
;for elem in $1/*
должен быть for elem in "$1"/*
;owner=`stat --format "%s" $1`
должен быть owner=`stat --format "%s" "$1"`
;size=`stat --format "%U" $1`
должен быть size=`stat --format "%U" "$1"`
;search "$elem" $2 $3
должен быть search "$elem" "$2" "$3"
.Второй - когда пустой каталог достигнут во время рекурсии, расширения for element in $1/*
сбои и два stat
к командам обращаются /path/to/empty/directory/*
, который не существует:
% bash script.sh /home/user user 0
stat: cannot stat ‘/home/user/Documenti/Musica/*’: No such file or directory
stat: cannot stat ‘/home/user/Documenti/Musica/*’: No such file or directory
stat: cannot stat ‘/home/user/Documenti/My Games/*’: No such file or directory
stat: cannot stat ‘/home/user/Documenti/My Games/*’: No such file or directory
stat: cannot stat ‘/home/user/Documenti/Video/*’: No such file or directory
stat: cannot stat ‘/home/user/Documenti/Video/*’: No such file or directory
stat: cannot stat ‘/home/user/home/user/*’: No such file or directory
stat: cannot stat ‘/home/user/home/user/*’: No such file or directory
stat: cannot stat ‘/home/user/Modelli/*’: No such file or directory
stat: cannot stat ‘/home/user/Modelli/*’: No such file or directory
stat: cannot stat ‘/home/user/Musica/*’: No such file or directory
stat: cannot stat ‘/home/user/Musica/*’: No such file or directory
stat: cannot stat ‘/home/user/Pubblici/*’: No such file or directory
stat: cannot stat ‘/home/user/Pubblici/*’: No such file or directory
stat: cannot stat ‘/home/user/Video/*’: No such file or directory
stat: cannot stat ‘/home/user/Video/*’: No such file or directory
%
Один способ зафиксировать, который проверил бы, существует ли файл / каталог перед вызовом display_owner_and_size
, так, чтобы пропустить текущее повторение, если мы пытаемся к статистике / пересекают каталог, который не существует (так как каталог пуст нет никакой причины для stat
его содержание, ни продолжать пересекать то ответвление дерева):
[ -e "$elem" ] && display_owner_and_size "$elem" || continue
Добавляя к этому, другие ошибки:
owner=`stat --format "%s" "$1"`
должен быть owner=`stat --format "%U" "$1"`
и size=`stat --format "%U" "$1"`
должен быть size=`stat --format "%s" "$1"`
;>
сделать числовые сравнения. Использовать -gt
: if [[ $owner == $2 && $size -gt $3 ]]
.Таким образом, исправленный сценарий был бы:
#!/bin/bash
owner="valdsilviufarcas"
size=0
function display_owner_and_size()
{
owner=`stat --format "%U" "$1"`
size=`stat --format "%s" "$1"`
}
function search()
{
for elem in "$1"/*
do
[ -e "$elem" ] && display_owner_and_size "$elem" || continue
if [[ $owner == $2 && $size -gt $3 ]]
then
echo $elem
fi
if test -d "$elem"
then
search "$elem" "$2" "$3"
fi
done
}
search "$1" "$2" "$3"