Fix.
#!/bin/shNUM=10
BIG_LIST="${HOME}/BigList";
SHORT_LIST="${HOME}/ShortList";
discover() {
cd "${1}";
DIR="${PWD}";
for FILE in .* *; do
if [ "${FILE}" = "." -o "${FILE}" = ".." ]; then
continue;
fi
if [ -d "${FILE}" ]; then
# Включая директории.
# COUNT=$((${COUNT:-0}+1));
if [ ! -x "${FILE}" ]; then
echo 1>&2 "${FILE}: no execute (or search) permission on file";
else
(discover "${FILE}");
fi
else
COUNT=$((${COUNT:-0}+1));
fi
done
if [ "${COUNT:-0}" -gt "${NUM}" ]; then
echo "${DIR}" >> "${BIG_LIST}";
else
echo "${DIR}" >> "${SHORT_LIST}";
fi
}
if [ -z "${*}" ]; then
set "${PWD}";
fi
for DIR in "${@}"; do
if [ ! -e "${DIR}" ]; then
echo 1>&2 "${DIR}: No such file ir directory";
continue;
fi
if [ ! -d "${DIR}" ]; then
echo 1>&2 "${DIR} is a file, not a directory";
continue;
fi
(discover "${DIR}");
done
Проверяем, были ли переданы параметры скрипту.
if [ -z "${*}" ]; then
set "${PWD}";
fi
${*} - все позиционные параметры одной строкой
$ script.sh a b c
«a» - первый позиционный параметр, $1.
«b» - второй позиционный параметр, $2.
«c» - третий позиционный параметр, $3.
$ a() { echo "\$1 = $1, \$2 = $2, \$3 = $3, \$* = $*"; }
$ a a b c
Если строка пустая, то это означает, что скрипту не были переданы параметры
$ a() { if [ -z "${var}" ]; then echo "var is empty"; else echo "var is $var"; fi }
$ a
$ var="text"
$ a
$ unset var
$ a
Логичнее использовать
if [ $# -gt 0 ]; then
…
fi
$# - количество позиционных параметров.
Если скрипту не переданы параметры, то сохраняем абсолютный путь к текущей директории в первом позиционном параметре.
# Удалим все позиционные параметры.
$ shift $#
$ if [ -z "${1}" ]; then echo "\$1 is empty"; else echo "\$1 is $1"; fi
$ set "${PWD}"
$ if [ -z "${1}" ]; then echo "\$1 is empty"; else echo "\$1 is $1"; fi
Переменная $PWD всегда содержит абсолютный путь к текущей директории.
Нет необходимости выполнять команду pwd.
for DIR in "${@}"; do
…
done
Сохраняем (поочерёдно) значение каждого позиционного параметра в переменную DIR.
$ set /tmp/dir "/tmp/d i r" /tmp
$1 - /tmp/dir
$2 - /tmp/d i r
$3 - /tmp
$ for DIR in "${@}"; do echo "\$DIR id ${DIR}"; done
"${@}" - экранируется (цитируется, ориг. quoting), поскольку в именах директорий (файлов) могут содержаться «специальные символы» (например, пробелы).
Сравните результат.
$ set /tmp/dir "/tmp/d i r" /tmp
$ for DIR in "${@}"; do echo "\$DIR id ${DIR}"; done
$ for DIR in ${@}; do echo "\$DIR id ${DIR}"; done
Проверяем, существует ли файл.
if [ ! -e "${DIR}" ]; then
echo 1>&2 "${DIR}: No such file ir directory";
continue;
fi
Вывод сообщения об ошибке:
echo 1>&2 "${DIR}: No such file ir directory";
перенаправляем в stderr (поток номер 2).
То есть, если файл не существует, то выводим сообщение об ошибке и возвращаемся (при помощи оператора continue) в начало цикла (переменной DIR присваивается значение следующего позиционного параметра.
Проверяем, является ли файл директорией.
if [ ! -d "${DIR}" ]; then
echo 1>&2 "${DIR} is a file, not a directory";
continue;
fi
Если файл не является директорией, то нам не нужно его обрабатывать, ведь нам нужно «посчитать количество файлов в каждой директории».
То есть если скрипту в качестве параметры передан файл, а не директория, то мы сообщаем об этом и переходим к следующему параметру.
Вызываем функцию discovery в subshell, передав значение переменной DIR.
$ a() { echo "\$1 is $1"; }
$ a /tmp
Нужно использовать «экранирование».
Сравните результат.
$ a() { echo "\$1 is $1"; }
$ a "/tmp/d i r"
$ a /tmp/d i r
Нам нужен отдельный счётчик для каждой директории, для этого мы используем subshell (В bash, можно использовать массив).
Сравните результат.
$ a() { var="$1"; echo "var is $var"; }
$ unset var
$ echo $var
$ (a text)
$ echo $var
$ a text
$ echo $var
discover() {
# Переходим в директорию.
cd "${1}";
DIR="${PWD}";
# Сохраняем (поочерёдно) имя каждого файла (в директории) в переменную FILE.
# Нам нужно обработать все файлы, в том числе и скрытые.
# Сравните результат.
# $ mkdir /tmp/dir
# $ touch /tmp/dir/.file
# cd /tmp/dir
# $ ls .*
# $ ls *
for FILE in .* *; do
# Игнорируем родительский каталог ".."
# Игнорируем «синоним» для текущей директории "."
# $ mkdir /tmp/dir
# $ cd /tmp/dir
# «..» - /tmp
# «.» - /tmp/dir
# Если значение переменной FILE равно «..» или «.»
if [ "${FILE}" = "." -o "${FILE}" = ".." ]; then
# Переходим к следующим файлу (возвращаемся в начала цикла).
continue;
fi
# Проверяем, является ли файл директорией.
if [ -d "${FILE}" ]; then
# Включая директории.
# COUNT=$((${COUNT:-0}+1));
# Проверяем, есть ли у текущего пользователя право на выполнение (поиск), если нет, то мы не сможем в неё перейти.
if [ ! -x "${FILE}" ]; then
echo 1>&2 "${FILE}: no execute permission on file";
else
(discover "${FILE}");
fi
else
# Инкрементируем счётчик.
# Если, переменная COUNT не имеет значения, то подставляем 0.
COUNT=$((${COUNT:-0}+1));
fi
done
# Если значение счётчика больше значения переменной NUM.
if [ "${COUNT:-0}" -gt "${NUM}" ]; then
echo "${DIR}" >> "${BIG_LIST}";
else
echo "${DIR}" >> "${SHORT_LIST}";
fi
}