On Thu, Oct 22, 2026 at 22:45:21 +0700, Max Nikulin wrote:
> On 22/10/2026 1:48 am, Nicolas George wrote:
> > By the way, it seems what you want is not just distinct elements but all
> > the elements too: a permutation. For that, there is a much more
> > efficient algorithm: swap the first element randomly with any of the
> > elements, then the second with any of the elements except the first,
> > etc.
>
> shuf(1) or, as it is recommended there,
> (info "(coreutils) shuf invocation")
> Unless the real goal is to explore BASH arrays.
Harnessing shuf(1) to shuffle a list of filenames presents its own flavor
of challenge. It's not trivial, because of the nature of filenames.
It's not exactly *hard*, but you do have to know what you're doing.
(shuf(1) is also non-portable, but since this is a Debian list, I guess
we can assume it will be available.)
If you don't want to puzzle it out yourself, here's a shuf-based
example. This one requires bash 4.4 or higher (for readarray -d):
#!/bin/bash
cd /wherever || exit
readarray -t -d '' playlist < <( printf '%s\0' * | shuf -z )
for file in "${playlist[@]}"; do
mpv -- "$file"
done
If you're targeting older versions of bash, you'd need a while loop to
load the array.
"But Greg," I hear you say, "why are you messing around with NUL bytes?
Why not just use newlines?"
Filenames may contain newlines. NUL is the only safe delimiter for
filenames. Any tool that processes filenames as input or output, or
which may be *expected* to be used in that way, needs to have a -z or -0
or --null option. And your bash script needs to use that option, and
perform all the other steps necessary to accomodate hostile filenames,
or else it *will* break.