Ваш скрипт не рекурсивный, так как он не вызывает сам себя.
Вот вариант, который рекурсивно реализует что-то вроде того, что у вас есть:
#!/bin/bash
walk_dir () {
shopt -s nullglob dotglob
for pathname in "$1"/*; do
if [ -d "$pathname" ]; then
walk_dir "$pathname"
else
printf '%s\n' "$pathname"
fi
done
}
DOWNLOADING_DIR=/Users/richard/Downloads
walk_dir "$DOWNLOADING_DIR"
Функция walk_dir
принимает путь к каталогу в качестве единственного аргумента и перебирает его содержимое. Если каталог найден, он рекурсивно вызывает себя для обхода этого подкаталога -.
Изменение для поиска файлов с суффиксом имени файла .txt
или.doc
:
#!/bin/bash
walk_dir () {
shopt -s nullglob dotglob
for pathname in "$1"/*; do
if [ -d "$pathname" ]; then
walk_dir "$pathname"
else
case "$pathname" in
*.txt|*.doc)
printf '%s\n' "$pathname"
esac
fi
done
}
DOWNLOADING_DIR=/Users/richard/Downloads
walk_dir "$DOWNLOADING_DIR"
Обратите внимание, что под «файлом» выше мы действительно подразумеваем все, что не является каталогом или символической ссылкой на каталог, который может не совпадать с обычным файлом . Установив параметры оболочки dotglob
и nullglob
в bash
, мы сможем находить скрытые пути и не будем проводить специальную проверку на наличие возможных пустых каталогов.
Вариант для /bin/sh
, который не заботится о скрытых именах:
#!/bin/sh
walk_dir () {
for pathname in "$1"/*; do
if [ -d "$pathname" ]; then
walk_dir "$pathname"
elif [ -e "$pathname" ]; then
case "$pathname" in
*.txt|*.doc)
printf '%s\n' "$pathname"
esac
fi
done
}
DOWNLOADING_DIR=/Users/richard/Downloads
walk_dir "$DOWNLOADING_DIR"
С параметрами оболочки globstar
и exglob
в bash
можно даже сделать следующее (без рекурсии )для перемещения файлов:
shopt -s globstar extglob
mv "$DOWNLOADING_DIR"/**/*.@(txt|doc) "$destdir"
... если результирующий список файлов не окажется слишком длинным. **
соответствует косой черте в путях (, включенных globstar
), а *.@(txt|doc)
соответствует любому имени файла, которое заканчивается на .txt
или .doc
(, включенномуextglob
).
Гораздо более эффективный и портативный способ поиска обычных файлов с суффиксом имени файла .txt
или .doc
в каком-либо каталоге верхнего -уровня $topdir
или под ним и для перемещения их в какой-либо другой каталог$destdir
:
find "$topdir" -type f \( -name '*.txt' -o -name '*.doc' \) \
-exec mv {} "$destdir" \;
С помощью GNU mv
вы можете сделать его немного более эффективным,
find "$topdir" -type f \( -name '*.txt' -o -name '*.doc' \) \
-exec mv -t "$destdir" {} +
Этот вариант будет перемещать пакеты файлов вместо одного файла за раз. Используйте mv
с -v
, чтобы увидеть, что перемещается,или добавьте -print
перед -exec
, чтобы получить список путей, с которыми вызывается mv
.
На это ответил пользователь Minix на Stack Overflow:
Ответом на это конкретное сообщение об ошибке является ломаная строка в заданном скрипте /etc/init.d/trousers
.
Линия нарушения 32:
31:
32: if [ ! -e /dev/tpm* ]
33: then
расширяется до:
if [ ! -e /dev/tpm /dev/tpm0 ]
Что вызывает ошибку. Изменение этой строки на что-то вроде:
31:
32: if [ ! -e /dev/tpm ] && [ ! -e /dev/tpm0 ]
33: then
должен хотя бы заставить скрипт работать.
if [ ! -e /dev/tpmrm ]
then
log_warning_msg "device driver not loaded, skipping."
exit 0
fi
for tpm_dev in /dev/tpmrm; do
TPM_OWNER=$(stat -c %U $tpm_dev)
if [ "x$TPM_OWNER" != "xtss" ]
then
log_warning_msg "TPM device owner for $tpm_dev is not 'tss', this can cause problems."
fi
done