I think something like this would work, without needing to use GNU extensions.
set -- # clear positional arguments
for file in /home/dir1/dir2/dir3/*
do
[ -e "$file" ] || continue
set -- "$@" "$file"
if [ "$#" -eq 40 ]
then
commandname "$@"
set --
fi
done
# in case the number of files is a number not divisible by 40
if [ "$#" -gt 0 ] && [ "$#" -lt 40 ]
then
commandname "$@"
fi
I don't know what the command is, but when I made a function like
commandname()
{
printf 'received %d arguments\n' "$#"
printf 'listing received filenames\n'
counter=0
for par in "$@"
do
counter="$(( counter+1 ))"
printf 'argument number %d: %s' "$counter" "$par" | LC_ALL=POSIX tr -d '[:cntrl:]'
printf '\n'
done
}
it showed a proper number of them received, and listed all of them correctly, as far as I have seen. I tested that on most of the filenames listed here How can I test my shell script's file-handling robustness? (53 files).
It's also worth noting that this won't find hidden files (ones that start with a dot), but what you wrote in OP doesn't either, so I assume that's fine. If you want only regular files, change -e "$file" ]
to [ -f "$file" ]
.