Если вы знаете, что текущий каталог содержит хотя бы один не скрытый файл:
set -- *; echo "$#"
Это очевидно обобщается на любой шар.
В сценарии это иногда вызывает нежелательный побочный эффект перезаписи позиционных параметров. Вы можете обойти это, используя subshell или с помощью функции (версия Bourne / POSIX), например:
count_words () {
eval 'shift; '"$1"'=$#'
}
count_words number_of_files *
echo "There are $number_of_files non-dot files in the current directory"
Альтернативное решение есть $(ls -d -- * | wc -l). Если глобус есть *, команда может быть сокращена до $(ls | wc -l). Анализ выходных данных lsвсегда делает меня неловким, но здесь это должно работать до тех пор, пока ваши имена файлов не содержат символов новой строки или вы не можете lsих избежать. И $(ls -d -- * 2>/dev/null | wc -l)имеет преимущество в том, что изящно обрабатывает случай несовпадающего глобуса (т. Е. Возвращает 0 в этом случае, тогда как set *метод требует тщательного тестирования, если глобус может быть пустым).
Если имена файлов могут содержать символы новой строки, альтернативой является использование $(ls -d ./* | grep -c /).
Любое из тех решений, которые полагаются на передачу расширения глобуса, lsможет завершиться ошибкой со слишком длинной ошибкой списка аргументов, если имеется много подходящих файлов.