Предполагая, что ваш main_script.sh
довольно стандартный и проходит 0
для успешного запуска и 1
для неудачного запуска, вы можете проверить статус через $?
следующим образом:
./main_script.sh
if [ $? -eq 0 ]; then
./report_success.sh
else
./report_failure.sh
fi
Предполагая, что вы используете инструменты GNU, вы можете использовать GNU basename
для получения имен всех подкаталогов в конкретном каталоге. Затем вы можете использовать paste
, чтобы отформатировать это как список, разделенный пробелом -.
basename -a /some/path/*/ | paste -d ' ' -s -
Приведенная выше команда использует тот факт, что GNU basename
имеет параметр -a
для возврата части имени файла из нескольких путей, заданных в качестве операндов в его командной строке.
Мы используем шаблон файла -подстановки, оканчивающийся на /
, чтобы сгенерировать пути для GNU basename
. Только каталоги могут соответствовать такому шаблону.
В конце концов, paste
создает список, разделенный пробелами -, из списка, разделенного новой строкой -, созданного GNU basename
.
Обратите внимание, что было бы трудно проанализировать сгенерированный список имен файлов, если какое-либо из исходных имен каталогов содержит символы пробела.
Обратите внимание: если каталог содержит символические ссылки, этот метод попытается перейти по этим символическим ссылкам.
Ограничив нас от использования каких-либо внешних инструментов, мы могли бы использовать массив в оболочке bash
для хранения путей к каталогам и управления ими.
shopt -s nullglob
topdir=/some/path
dirpaths=( "$topdir"/*/ )
dirpaths=( "${dirpaths[@]#$topdir/}" )
dirpaths=( "${dirpaths[@]%/}" )
printf '%s\n' "${dirpaths[*]}"
Приведенный выше код оболочки расширяет тот же шаблон подстановки, который мы использовали в первой части этого ответа, но сохраняет полученные пути к каталогам в массиве dirpaths
. Затем он удаляет известный префикс $topdir/
из каждого элемента массива и конечный /
перед печатью массива в виде одной строки имен, разделенных пробелом -. Разделителем, используемым между именами в последней строке, будет первый символ из $IFS
, который по умолчанию является пробелом.
Используя find
, вы можете искать подкаталоги в конкретном верхнем каталоге, который вас интересует, не возвращая при этом сам верхний каталог. Вы также должны остановить find
от перехода в подкаталоги.
topdir=/some/path
find "${topdir%/}/." ! -name. -prune -type d -exec basename {} \; | paste -d ' ' -s -
Приведенная выше команда избегает начальной точки поиска, используя отрицательный тест -name
.и он обрезает дерево поиска с помощью -prune
, так что find
не рекурсивно спускается в какие-либо подкаталоги. Мы вызываем basename
для каждого найденного каталога, который выводит имена файлов каталогов на отдельные строки. В качестве последнего шага мы передаем результат от find
до paste
для форматирования вывода в список, разделенный пробелом -в одной строке.
В GNU find
это можно записать как
find /some/path -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | paste -d ' ' -s -
Использование find
подобным образом приведет к отображению каталогов со скрытыми именами, и вы не увидите никаких каталогов, связанных символически.
В оболочке zsh
вы могли бы использовать более продвинутый шаблон подстановки оболочки, чтобы выбирать имена файлов только для каталогов и печатать их за один раз.
print -r -- /some/path/*(/:t)
В этой команде используется квалификатор glob, /:t
, состоящий из двух частей, влияющий на предыдущий шаблон подстановки /some/path/*
. /
заставляет шаблон соответствовать только каталогам (, не связанным символически; для этого используйте -/
), а :t
извлекает «хвост» каждого сгенерированного имени пути, то есть компонент имени файла.
Команда print -r
печатает свои аргументы с пробелами в качестве разделителей, избегая расширения управляющих последовательностей, таких как \n
или \t
, в данных. Использование --
для отделения операндов от опций (также работает с -
, как в оболочке ksh
), гарантирует, что имена каталогов, полученные в результате расширения glob, не будут приниматься в качестве опций, даже если они начинаются с -
.
Вы можете использовать это в оболочке bash
для создания списка.
zsh -c 'print -r -- /some/path/*(/:t)'
Поскольку вы уже знаете каталог, из которого вы перечисляете подкаталоги, вы можете использовать следующее...
find /home/x/y -maxdepth 1 -type d -printf '%P '
Вот мое предложение с использованием цикла for
:
$ echo "$(for node in $(ls ~/); do if test -d "${node}"; then printf "${node} "; fi; done)"
Desktop Documents Downloads Music Pictures Public Templates Videos
Альтернативное использованиеfind
:
$ echo "$(for node in $(find ~/ -mindepth 1 -maxdepth 1 -type d); do printf "$(basename ${node}) "; done)"
.mozilla Videos Pictures Music Documents Public Templates Downloads.gnupg.config.local.cache Desktop
Редактировать:Что касается их комментария , вам нужно будет изменить переменную IFS
для каталогов с пробелами:
$ IFS_orig=${IFS}
$ IFS=$'\n'
$ echo "$(for node in $(ls ~/); do if test -d "${node}"; then printf "'${node}' "; fi; done)"
'Desktop' 'Documents' 'Downloads' 'Music' 'My Test' 'Pictures' 'Public' 'Templates' 'Videos'
$ IFS=${IFS_orig}
Редактировать:Самый простой вариант — использоватьls -d *
:
$ ls -d *
Desktop Documents Downloads Music 'My Test' Pictures Public Templates Videos
Также забыл, что в циклах for
следует test
использовать абсолютный или относительный путь:
$ echo "$(for node in $(ls "${HOME}"); do if test -d "${HOME}/${node}"; then printf "'${node}' "; fi; done)"
'Desktop' 'Documents' 'Downloads' 'Music' 'My Test' 'Pictures' 'Public' 'Templates' 'Videos'