См. Ответ Жиля на Почему bash игнорирует SIGTERM?
Во-первых, это не относится к bash. ATT ksh, dash и zsh ведут себя одинаково: они игнорируют SIGTERM и SIGQUIT во время редактирования командной строки; что касается mksh, он также не завершает работу, но обрабатывает их как SIGINT.
Как руководство по ksh, так и руководство по bash оправдывают игнорирование SIGTERM в следующих терминах:
so that kill 0 does not kill an interactive shell
kill 0 уничтожает все процессы в группе процессов, в которой находится оболочка¹. Вкратце, группа процессов состоит из всех процессов, выполняемых на переднем плане на терминале, или всех процессов в фоновом или приостановленном задании.
Есть два основных способа решить эту проблему:
Измените команду find
так, чтобы она входила только в интересующие вас каталоги, а затем печатала один символ (, например.x
)для каждого найденного файла внутри. Затем подсчитайте количество этого символа, созданного с помощью wc -l
. Безопаснее выводить символ, чем путь, поскольку пути в Unix потенциально могут содержать символы новой строки. Это решение немного сложное, так как оно включает использование -prune
для игнорирования каталогов, которые нам не интересны, или альтернативно ! -path
.
Найдите каталоги точно так же, как вы это делали до сих пор, но затем используйте внутристрочный скрипт -для подсчета файлов внутри. Это проще, и то, что я показываю ниже.
find /path/to/cool/stuff -maxdepth 4 -type d -name "*Magic Data*' \
-exec bash -O dotglob -c '
dir=$1
set -- "$dir"/*
printf "%s %d\n" "$dir" "$#"' bash {} ';'
Здесь мы находим каталоги, как и вы, затем для каждого каталога запускаем этот короткий bash
скрипт:
dir=$1
set -- "$dir"/*
printf "%s %d\n" "$dir" "$#"
Это берет путь к каталогу из командной строки (, заданной find
), и расширяет шаблон глобуса *
внутри него. Установив параметр оболочки dotglob
в командной строке скрипта, мы гарантированно также будем считать скрытые файлы и каталоги (удалить -O dotglob
, чтобы не считать скрытые имена ).
Мы делаем расширение всех имен в качестве аргумента для set
, что установит позиционные параметры для расширенных записей.Количество позиционных параметров доступно как $#
, что также является количеством файлов в этом конкретном каталоге.
Связанные:
Вы также можете использовать следующую команду для достижения желаемого
Здесь я использую exec
для запуска оболочки sh
, которая затем выполняет команду, переданную ей с помощью опции -c
. В вашем случае это командаls -1 | wc -l
find /path/to/cool/stuff -maxdepth 4 -type d -name '*Magic Data*' -print0 -exec sh -c "ls -1 {} | wc -l" \;
Исходя из вашей попытки решения, вот как можно выполнить эту задачу:
find /path/to/cool/stuff \
-maxdepth 4 \
-type d \
-name '*Magic Data*' \
-exec sh -c '
for d do
printf "%s: " "$PWD/$d"
find "$d/." -maxdepth 1 ! -name. -printf "\\n" | wc -l
done
' find_sh {} +
Пояснение:
find
-просмотра целевых каталогов ваш рецепт соблюдается. {} +
и передаем их оболочке sh
через список аргументов:sh -c '...' find_sh {} +
sh
, который является нулевым аргументом $0
, и поэтому ему можно присвоить любое имя, и в данном случае мы называем его find_sh
. Это имя будет отображаться в списке процессов. {} +
и формирует аргументы $1 $2 $3...
для создаваемой нами оболочки. ! -name.
OTW, имя целевого каталога также учитывается в выводе wc -l.