Se a postagem contiver o código real, o problema provavelmente é o --data-urlencode DATA na solicitação de curl. Isso fará com que &DATA seja anexado à solicitação, o que certamente não é o que você deseja. Acredito que você precise url codificar a assinatura ("A assinatura resultante deve ser codificado em base 64 e, em seguida, URI codificado.") Que você pode fazer com:
curl --get --data-urlencode "Signature=$sig" "https://ec2.amazonaws.com/?Action=DescribeRegions&AWSAccessKeyId=<aws access key>&SignatureMethod=HmacSHA256&SignatureVersion=2&Timestamp=$dt&Version=2013-02-01"
Sugiro usar a opção de linha de comando -v para curl para fins de depuração; Ele permitirá que você veja a linha de solicitação real, que você pode comparar com o formato esperado.
Além disso, verifique se não há espaços à direita na definição de q .
Como um problema secundário, não há motivos para especificar o -e flag para echo . -e é usado para fazer com que \ -sequências como \n sejam alteradas para os caracteres reais (hex 0A neste caso); você não tem \ em $q , portanto, não há necessidade de recodificação. -e é não necessário para fazer com que novas linhas reais no argumento sejam ecoadas.