Estou usando o Openbox no Arch, e com isso precisei instalar o Redshift, para ter aquele filtro de luz azul. Porém, por algum motivo, a localização automática dele pelo geoclue não funcionou e como o Redshift tem uma forma manual, decidi por usar ele.
Mas, me veio uma questão: Será que é possível obter a localização para usar no Redshift de outra forma?
Uma solução
Pesquisando um pouco, encontrei uma solução que envolvia o curl e o site ipinfo.io. No site, tem um arquivo que exibe a localização e outros dados do seu IP e usando o curldá pra exibir essas informações no terminal. E com um…
curl -s ipinfo.io
Teremos uma saída nesse modelo:
{
"ip": "<SEU IP AQUI>",
"hostname": "<SEU PROVEDOR DE INTERNET AQUI>",
"city": "<SUA CIDADE AQUI>",
"region": "<SUA REGIÃO/ESTADO AQUI>",
"country": "PAÍS",
"loc": "<LATITUDE>,<LONGITUDE>",
"org": "<NOME DO PROVEDOR AQUI>",
"postal": "<CÓDIGO POSTAL>",
"timezone": "<FUSO HORÁRIO AQUI>",
"readme": "https://ipinfo.io/missingauth"
}
Mas queremos apenas a informação da Latitude e Longitude. Com isso, vamos para outro comando:
curl -s https://ipinfo.io | grep "loc"
Com a adição do | grep “loc”, filtraremos a linha com a Latitude e Longitude, que ficará mais ou menos assim:
"loc": "<LATITUDE>,<LONGITUDE>",
Mas isso não é o suficiente. Precisamos refinar um pouco mais a saída. Nesse “trenzinho”, podemos adicionar mais um comando:
curl -s https://ipinfo.io | grep "loc" | awk -F ‘"’ ‘{ print $4 }’
O | awk -F ‘"’ ‘{ print $4 }’ irá cortar tudo o que está antes das ". Com esse comando, a saída ficará mais ou menos assim:
<LATITUDE>,<LONGITUDE>
Para alguns casos, isso é o suficiente. Mas e se quisermos extrair somente a Latitude ou a Longitude?
Aqui entra mais um awk, nesse caso, o | awk -F ‘,’ ‘{ print $1}’) para extrair somente o que está antes da vírgula (ou seja, a Latitude) ou | awk -F ‘,’ ‘{ print $2}’) para extrair somente o que está depois da vírgula (ou seja, a Longitude).
Aplicando isso num Script
Dada essa explicação, para aplicar isso num Script, ficaria mais ou menos assim:
#! /bin/bash
loc=$(curl -s https://ipinfo.io | grep "loc" | awk -F '"' '{ print $4 }')
lat=$(echo $loc | awk -F ',' '{ print $1}')
lon=$(echo $loc | awk -F ',' '{ print $2}')
redshift -l $lat:$lon
Melhorando um pouco mais
Mas dá pra melhorar isso um pouco mais: Como verificar a conexão com a Internet? Com outro curl, nesse caso, o curl -Is ``https://ipinfo.io/json, em que o I diz para o curl exibir o cabeçalho de resposta HTTP. O que dá esse calhamaço aqui:
HTTP/2 200
access-control-allow-origin: *
x-content-type-options: nosniff
content-type: application/json; charset=utf-8
content-length: 326
date: Thu, 31 Jul 2025 01:41:48 GMT
via: 1.1 google
strict-transport-security: max-age=2592000; includeSubDomains
alt-svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000
Mas, só precisamos da primeira linha (HTTP/2 200). Com isso, vem um | head -n 1, que filtra somente a primeira linha dessa saída. O que deixa esse comando mais ou menos assim:
curl -Is https://ipinfo.io/json | head -n 1
E a saída desse comando, quando não tem a conexão com a internet é vazia, então dá pra juntar com um if -z, e assim tratar o que fazer quando não ter a conexão com a Internet.
Aplicando a melhoria num Script
O Script completo, ficou assim, com essa melhoria da conexão com a Internet ficou assim:
#! /bin/bash
if [ -z "$(curl -Is https://ipinfo.io/json | head -n 1)" ]; then ## Baixando um arquivo para detectar a conexão da Internet
echo "## ERROR: Connection not found!"
echo "## Using Latitude and Longitude 0:0"
## Se não houver a conexão com a Internet, usar a Latitude e Longitude 0:0
lat=0
lon=0
else
echo "## Connection OK"
echo "## Detecting Latitude and Longitude..."
# Se houver conexão com a Internet, baixar um arquivo do ipinfo.io, com as informações do IP, filtrar o campo localização e com isso, extrair a Latitude e Longitude.
loc=$(curl -s https://ipinfo.io/json | grep "loc" | awk -F '"' '{ print $4 }')
lat=$(echo $loc | awk -F ',' '{ print $1}')
lon=$(echo $loc | awk -F ',' '{ print $2}')
echo -e "\n## Latitude: $lat"
echo "## Longitude: $lon"
fi
echo -e "\n##Starting Redshift..."
redshift -l $lat:$lon