Вот такая штука позволяет пройтись по всем директориям:
for i in */; do
Но как?? Не может же он перебирать все возможные сочитания до слэша. Или есть какое-то соглашение, что последовательности в for связаны с файлами, лежащими в текущей директории?
Сначала строит список доступных объектов, потом выбирает те, что подходит под глобы. Либо каждый объект сравнивает с глобой и решает выводить или нет. Но для ls * думаю есть исключение дабы лишнюю работу не делать.
'*' - это шаблон, что-то вроде упрощенного регулярного выражения. Сначала bash раскроет ее так, что '*' будет заменена на все каталоги, разделенные пробелом, потом это в качетсве аргументов будет передано команде. Можешь это проверить на echo */. То есть замена произвойдет еще до того, как for/echo будет вызван. Из этого следует следующее: 1. Это работает для абсолютно любой команды запущеной в bash 2. Если в именах директорий будут пробелы, скорее всего это будет работать не так, как тебе нужно.
~ $ for i in `printf '%s\n' */`; do ls -ld $i; done
....
ls: cannot access 'VirtualBox': No such file or directory
ls: cannot access 'VMs/': No such file or directory
.....
Я напомню, что подстановка * -- это массив строк с именами файлов, подпадающих под глоб, а подстановка $() (``) -- это одна строка с выводом внешнего процесса, которую надо парсить, и которая к тому же рассыпалась по пробелам, не будучи экранированной "".
$ printf '%s\n' */ к чему тогда вообще это нужно было?
Продемонстрировать, что каждый файл из подстановки */ уезжает дальше одним аргументом, не разваливаясь по пробелам, как одному из участников обсуждения показалось ранее. Может быть моя иллюстрация будет нагляднее:
args() {
printf "%d args:" $#
printf " <%s>" "$@"
echo
}
$ args */
3 args: <dir with space 1/> <dir with space 2/> <dir with space 3/>