IFS= read -rd '' 'tracks[n--]'
How does 'tracks[n--]' here get recognized as an array, and what do the two dashes after the read input var 'n' do?
It doesn't get recognized as an array but as a simple string that
will effectively be seen as an array's access representation by read
To understand this, replace « tracks[n--]
» with, e.g., « tracks
Now, for each iteration, new input read is stored at index 1 of array tracks
(Note that you still need to decrement n
because of the while-loop
condition. See below.)
It's possible to do that because you can assign array offsets directly.
E.g., you can do « tracks=foo
», to implicitly make tracks
which has the string « foo » at its second index (starting from 0).
Basically, as soon as the name[x]
construct is used, name
is seen as an
array, unless name
is an associative array (which needs explicit declaration).
gets assigned, the value at offset x
gets either set or
replaced, after that name
has been binded if it doesn't already exist.
If you want to go into more details, read the source.read.c:bind_read_variable
; set read
(0)'s VAR, i.e., tracks[x]arrayfunc.c:valid_array_reference
; check whether « tracks[x]
» represents an array access (it does)arrayfunc.c:assign_array_element
; prepare tracks[x]
; create tracks
if it doesn't exist, assign tracks[x]
syntax is called a post-decrement.
It's used to subtract 1 from a variable (x
), then re-assign that variable
with the result, only after that the current line has been processed.
In our case, the variable n
has at first the value that
represents the number of random tracks wanted.
is different than 0, we store the current input read at index n
implicit array tracks
, then we post-decrement n
so that at the next iteration n
will have the value of n - 1
, and so on, until it gets to 0 and the while-loop
In the end, you get an array filled from index 1 to n
, so with n
I see that the while loop reads input from the sort|find commands re-directed afterward, but what exactly is the significance of the colon?
I guess 'do' expects/demands some sort of command, but I do not know what the colon means.
is a shell builtin that does only exit with an exit status of 0. It's called the null command
In other words, it does always return success, meaning it always succeeds.
It's used here to do nothing in the while-loop
body, since we're already getting the values in an array thanks to read
As you correctly pointed out, bash
(1) expects to see commands after the keyword do
the keyword done
, that's why we need to use a command that does nothing in this place.
You could instead store the input there, as well as decrement n