Estou escrevendo um script de shell para baixar a versão mais recente de algum software. Depois de analisar a saída de curl
eu percorro várias etapas para encontrar a string de versão exata (no momento em que escrevo isso é 0.65.3
):
(Em todos os exemplos de código abaixo, >
está meu prompt. A saída do Bash 3.2 ou Zsh está em uma linha sem >
prefixo.)
> url="https://github.com/gohugoio/hugo/releases/latest"
> latest=$(curl --silent --head "$url" | grep Location)
> tag=$(echo "$latest" | cut -d'/' -f8)
> version=$(echo "${tag//v}")
> echo "hugo_${version}_Linux-64bit.tar.gz"
_Linux-64bit.tar.gz
A saída que eu esperava era hugo_0.65.3_Linux-64bit.tar.gz
, mas na saída da chamada para echo
com a string citada, parece que os bytes a seguir ${version}
foram usados para substituir os bytes no início da string citada.
Aqui eu uso duas strings entre aspas diferentes para esclarecer o que está acontecendo:
> echo "hugo_${version}test"
test_0.65.3
> echo "hugo_${version}lorem ipsum dolor sit amet"
lorem ipsum dolor sit amet
Eu recebo o mesmo resultado inesperado se eu fizer isso:
> version=$(echo "${tag:1}")
> echo "hugo_${version}_Linux-64bit.tar.gz"
_Linux-64bit.tar.gz
Mas, recebo o resultado esperado se eu fizer isso:
> version=0.65.3
hugo_0.65.3_Linux-64bit.tar.gz
Este último resultado é o que é necessário, mas é claro que torna meu script estático em vez de dinâmico e, portanto, não é muito útil para mim. Como posso obter o resultado desejado sem codificar o valor de $version
no meu script?
A linha retornada por
curl
termina com alimentação de linha de retorno de carro. (final da linha MS-dos). O avanço de linha é removido pelas ferramentas Unix, porém isso deixa um retorno de carro no final.Corrija esta linha para usar
dos2unix
(e cite seu argumento paraecho
, evitando os bugs descritos em BashPitfalls #14 ):...ou, usando a sintaxe interna do shell para decretar ambas as mudanças de uma vez:
dos2unix
faz algumas outras alterações (como adicionar uma nova linha à direita após a última linha de texto, que o UNIX requer, mas o DOS não), mas nenhuma delas importa para uma string de linha única como esta.A resposta de ctrl-alt-delor explica por que você está vendo esse comportamento; mas para abordar seu objetivo subjacente, recomendo usar a API do GitHub em vez de interpretar o redirecionamento “mais recente”:
Isso solicita à API as informações sobre a versão mais recente do Hugo e extrai o nome da tag usando
jq
, removendo qualquer “v” inicial.Idealmente, você extrairia os nomes e URLs dos ativos do JSON retornado.