The way the expansion happens is not how you would expect.
test -v X[$index]
Does not expand to:
test -v X["a'b"]
But instead it expands like this:
test -v 'X[a'\''b]'
bash splits and escapes the array syntax in a way that prevents test -v
from seeing a valid array element. test -v
expects a fully valid variable name or array element as a single argument.
As Kusalananda suggested you could use test -v 'X[$index]'
however I think a much more correct way would be to use the extended test syntax instead:
if [[ -n $index && -v 'X[$index]'X["$index"] ]]; then