Você confundiu, as aspas duplas "$b" não impedem a expansão dos parâmetros, isso impede a expansão do nome do caminho (aka globbing) e divisão de campos .
Se você quiser evitar a expansão de parâmetros, use citando , como orçamento simples '$b' ou escapando \$b :
$ echo '$b'
ou:
$ echo \$b
então $b é literal de saída.
No exemplo, nada impede a expansão dos parâmetros.
Quando o shell lê a entrada c=$(b=2; echo $b) , ele executa o reconhecimento de token , viu que $( é token para substituição de comando. Então, ele trata o resto da string entre $( e ) a ser interpretado em subshell criado por substituição de comando, não pelo shell atual.