I have this bash script
while true ; do for i in * ; do cp "$i" ~/slideshow.jpg ; echo $i ; sleep 5 ; done ; done
How can I randomize this process?
I feel like this question is a homework assignment. Let me do it for you.
*
in that script is likely returning an alphabetized listing of a directory. So you could intercept that listing and randomize at that point.
You could also load the directory contents in to an array, randomly pick a number - mod the array size and if the result was empty, advance forward until you hit an non-empty entry. Then empty that entry as you consume it. You'd need a counter or something to then keep track of how many elements you've used so you know when you've consumed all entries.
Further, you could instead load the entries in to something like a linked-list and come up with a random entry # to consume and then discard from the data structure.
There are likely many other options. But I just gave you sketches for 3 crude approaches. Sure I didn't write code for you, but I did the hard part. You're welcome ;)
The following should AFAIK work on any POSIX system.
A random ordered list of files can be obtained with:
for i in *; do echo "$i"; done | \
awk 'BEGIN { OFS="\t"; srand (); } { print rand (), $0 }' | \
sort | \
cut -f2-
Explanation:
for i in *; do echo "$i"; done
gives a list of files, one per line.awk 'BEGIN { OFS="\t"; srand (); } { print rand (), $0 }'
adds a field with a random number in [0,1) range to each line.sort
sorts using that random number as index, therefore randomizing the file list.cut -f2-
removes the random number field.The original command (with copying and sleeping) can then be constructed as:
for i in $(for i in *; do echo "$i"; done | \
awk 'BEGIN { OFS="\t"; srand (); } { print rand (), $0 }' | \
sort | \
cut -f2-); \
do \
cp "$i" ~/slideshow.jpg; \
echo "$i"; \
sleep 5; \
done
Of course you can remove backslashes and newlines if you like one-liners ;)