Isso porque a expansão de variável de $? é executada antes do código ser passado para bash para execução, portanto o código de saída echo ed é do comando que foi executado antes de bash :
bash-4.1$ ( exit 42 )
bash-4.1$ bash <<EOF
cat asdfasdf
echo $?
EOF
cat: asdfasdf: No such file or directory
42
Apenas cite uma única citação no delimitador aqui para impedir a expansão da variável:
bash-4.1$ bash <<'EOF'
cat asdfasdf
echo $?
EOF
cat: asdfasdf: No such file or directory
1