The *
shell globbing pattern does not by default match hidden names.
In bash
, you may make it do that by enabling the dotglob
shell option. You do this with shopt -s dotglob
.
Note that you also would have to quote the expansion of $file
in your code, or the shell would perform word splitting and filename globbing on its value.
listDir () (
shopt -s dotglob
for pathname in "$1"/*; do
printf '%s\n' "$pathname"
done
)
If you need to do other things with $pathname
in the loop above, make sure to double quote the expansion of the variable as "$pathname"
. This would make the function work for filenames that contain all manner of characters.
When calling the function, make sure to quote the directory name if it contains spaces:
listDir "my directory/here somewhere"
Two alternative approaches (assuming that you just need to list the files):
listDir () (
shopt -s dotglob
printf '%s\n' "${1:-.}"/*
)
By enclosing the function body in ( ... )
(a subshell), we ensure that he dotglob
shell option is not set in the calling shell.
By using ${1:-.}
in place of just $1
, we use .
(the current directory) as the default directory to list if no directory (or an empty string) is given.
The printf
utility will reuse its format string if given more arguments than there are placeholders in the formatting string. Here, we use that fact to print out the filenames as a newline-delimited list.
Using find
, which does not need dotglob
:
listDir () {
find "${1:-.}" -maxdepth 1 -mindepth 1 -print
}
If you want to do something else with the found files when you are using find
, then don't try to loop over the output of find
. Instead, use -exec
:
listDir () {
find "${1:-.}" -maxdepth 1 -mindepth 1 -exec sh -c '
for pathname do
# code that does something with "$pathname"
done' sh {} +
}
Related:
find
as he suggested without a loop. – Andy Dalton Oct 05 '18 at 13:36find
, don't loop. If you need to loop, use then loop "withinfind
" using-exec
as I just showed below. – Kusalananda Oct 05 '18 at 15:55