I've been reading through the parameter expansion portion of the GNU bash manual guide and I can't seem to understand what is going on in the final echo
command if the titular script (IFS=';' read -sdR -p $'\E[6n' ROW COL; echo ${ROW#*[};
). I understand that the sequence of commands is trying to get the current cursor row by correctly setting the IFS
to ;
which is the separator of the output of the escape sequence \E[6n
(tangentially I don't completely understand why this needs a pre-pended $
-sign but maybe that's in the manual somewhere).
What I don't get is, directly from the manual,
${parameter#word} ${parameter##word} The word is expanded to produce a pattern and matched according to the rules described below (see Pattern Matching). If the pattern matches the beginning of the expanded value of parameter, then the result of the expansion is the expanded value of parameter with the shortest matching pattern (the ‘#’ case) or the longest matching pattern (the ‘##’ case) deleted. If parameter is ‘@’ or ‘’, the pattern removal operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with ‘@’ or ‘’, the pattern removal operation is applied to each member of the array in turn, and the expansion is the resultant list.
what setting word
to *[
is doing exactly. The manual seems to say that *
is special and used for more of a string or array-style expansion where positional parameters are needed but ROW
shouldn't be a string or an array, or if it is it only has the 1 element so why even use *
? Also what is the [
for? The manual says that word
will be expanded to produce a pattern but what would *[
expand to exactly? (Especially when ROW
will just be a number and have no [
characters to match with???)
Thanks in advance!
CodePudding user response:
What I don't get is, [...] what setting
word
to*[
is doing exactly.
$ IFS=';' read -sdR -p $'\E[6n' ROW COL
$ declare -p ROW
declare -- ROW=$'\E[24'
It removes \E[
from $ROW
.
The terminal responds to \E[6n
with cursor position in this format (source):
\E[<row>;<column>R
With IFS
set to ;
and line delimiter R
, ROW
is assigned \E[<row>
; and ${ROW#*[}
is for taking the row number only.
CodePudding user response:
(Especially when ROW will just be a number and have no [ characters to match with???)
This is wrong. Getting the cursor position returns an escape sequence not just the positions that's why you need to remove the ESC
and [
.
(IFS=';' read -sdR -p $'\E[6n' ROW COL; echo ${ROW#$'\E'[};)
this also works and it's perhaps more precise as it removes the expected \E
not just anything.