Minhas ideias para abreviar esse script:
#!/bin/sh
if loc=$(curl -sf https://ipinfo.io/json); then
IFS=, read lat lon <<EOF
$(printf '%s' "$loc" | awk -F'"' '/loc/ { print $4 }')
EOF
else
echo 'Conexão ao ipinfo.io falhou, usando coordenadas padrão...' >&2
lat=0
lon=0
fi
set -x
exec redshift -l "$lat:$lon" "$@"
- O
curl
possui a opção-f
, que faz ele dar um status de saída de falha para oif
/&&
não só se a conexão falhar, mas também se a resposta HTTP não for 200/OK. Junto com o fato de que uma linha no estiloVAR=$(comando)
traz o mesmo status de saída docomando
dentro do$()
, isso nos poupa de termos que chamá-lo só para analisar os cabeçalhos comhead -n1
. - O recurso de “encontrar padrões” do
awk
(/expressao-regular/ { script }
em vez de só{ script }
) poupa ogrep "loc"
. - O comando
read
pode ser usado não só para ler o que o usuário digita, mas também para separar strings (inserindo-as como heredocs — usando<<EOF
no fim de uma linha, botando o texto, e uma linha só comEOF
para finalizar, como no exemplo — ou herestringscomando <<< "texto"
) em mais de uma variável – cada argumento do read é o nome de uma variável. Por padrão ele separa nos espaços, mas podemos definir os caracteres que vão servir de delimitador com o prefixoIFS=[caracteres]
, no caso, a vírgula. Assim poupamos os doisawk -F ,
aqui. - O
>&2
noecho
faz a mensagem de erro ir para o terminal (ou seja qual for o local dedicado para a análise de erros) em vez da saída padrão. Para um script pessoal que imediatamente executa outro programa, faz pouca diferença, mas é uma boa prática, especialment para scripts que gerem dados para pipelines. - Prefixei o
redshift
comexec
, que garante que o shell vai encerrar quando o comando executar, e coloquei"$@"
no final, que repassa quaisquer argumentos ou opções que o script recebeu para o Redshift, removendo a necessidade de fazer cópias para colocar opções a mais. - É uma boa prática manter variáveis dentro de aspas (
"$lat:$loc"
em vez de só$lat:$loc
) devido ao wordsplitting.
Por questão de gosto, eu coloquei menos mensagens informativas. Em vez disso, coloquei set -x
, que faz o shell exibir cada linha de código executada, antes de invocar o Redshift; daí a linha de comando vai ter a latitude e longitude.