Использованиеzsh
:
setopt extendedglob nullglob
for pathname in /**/*(/e{'[[ -n $REPLY/(#i)*.htm(l#)(#q.) ]]'}); do
printf '%s:\n' $pathname
ls -l $pathname
done
Это печатает путь к каждому каталогу, содержащему любой обычный файл, имя которого заканчивается на .htm
или.html
(независимо от регистра ), за которым следует вывод ls -l
для этого каталога.
Цикл перебирает все каталоги внутри или ниже /
, содержащие файл HTML. Он делает это, используя глобус /**/*
, который сам по себе соответствует всему во всей иерархии каталогов /
. Этот список фильтруется, чтобы содержать только пути к каталогам с помощью квалификатора /
glob (, начального /
в первой скобке ), и далее список фильтруется, чтобы содержать только те записи, для которых [[ -n $REPLY/(#i)*.htm(l#)(#q.) ]]
истинно. Это выражение, где $REPLY
является одним из проверяемых путей каталога, будет истинным, если каталог содержит хотя бы один обычный файл с суффиксом имени файла .htm
или .html
(без учета регистра ).
Часть e{...}
шаблона подстановки, вероятно, могла бы быть записана более кратко.
Использованиеbash
:
shopt -s globstar nullglob extglob nocaseglob
for pathname in /**/*/; do
set -- "$pathname"/*.htm?(l)
if [[ -f $1 ]]; then
printf '%s:\n' "${pathname%/}"
ls -l "$pathname"
fi
done
При этом используется параметр оболочки globstar
, чтобы включить использование шаблона подстановки **
(, включенного по умолчанию в оболочке zsh
). Он перебирает все пути к каталогам во всей иерархии каталогов, начиная с /
и вниз, и пытается расширить глобус *.htm?(l)
в каждом каталоге (, это соответствует интересующим нас HTML-файлам ). Если первое совпадение с этим глобусом является обычным файлом или символической ссылкой на него, то выводится путь к каталогу и список ls -l
.
Если у вас могут быть каталоги с суффиксом имени файла .htm
на .html
, вам нужно будет проверить совпадения расширения внутри цикла в отдельном цикле, просто чтобы убедиться, что вы поймаете любые обычные файлы (или символические ссылки на обычные файлы )с суффиксами HTML:
shopt -s globstar extglob nocaseglob
for pathname in /**/*/; do
for match in "$pathname"/*.htm?(l); do
if [[ -f $match ]]; then
printf '%s:\n' "${pathname%/}"
ls -l "$pathname"
break
fi
done
done
Я удалил параметр оболочки nullglob
в этом варианте, так как мы больше не зависим от него.
В оболочке POSIX sh
у вас нет доступа к глобусу **
, поэтому вам придется использовать find
для создания путей к каталогам для цикла:
find / -type d -exec sh -c '
for pathname do
for match in "$pathname"/*.[hH][tT][mM] "$pathname"/*.[hH][tT][mM][lL] ; do
if [ -f "$match" ]; then
printf "%s:\n" "${pathname%/}"
ls -l "$pathname"
break
fi
done
done' sh {} +
Здесь find
действует как своего рода генератор путей для встроенного скрипта sh -c
и передает ему пути к каталогам.
Сценарий sh -c
делает почти то же, что и второй bash
вариант ответа, т. е. он итерирует расширение глобуса, которое должно соответствовать нужным именам, проверяя каждое имя, чтобы увидеть, является ли оно обычным файлом (или символическая ссылка на один ). Как только он находит файл, он печатает путь к каталогу, за которым следует вывод ls -l
.
Как прокомментировал user414777 , отсутствует системный вызов clock _nanosleep _time64 . Первоначально это было добавлено в ядро на ветке 5.6 как часть решения проблемы 2038 года , и оно было портировано на каждую ветку, начиная с 5.1.
Библиотека GNU C начала использовать эти 64 -битовые функции времени в версии 2.31, а проблема, с которой я столкнулся при работе с OpenSSH, упоминается в примечаниях к выпуску :
.System call wrappers for time system calls now use the new time64 system calls when available. On 32-bit targets, these wrappers attempt to call the new system calls first and fall back to the older 32-bit time system calls if they are not present. This may cause issues in environments that cannot handle unsupported system calls gracefully by returning -ENOSYS. Seccomp sandboxes are affected by this issue.
Чтобы решить мою проблему, я мог бы:
Я решил пойти по пути обновления ядра, так как этот вариант казался самым -будущим доказательством.