Que tal:
if [ "$percent" -eq 100 ] && [ "$full_flag" -eq 0 ];
then
shuttle push note Chrome "Aurora: Battery charged" "Battery is at $percent percent"
full_flag=1
fi
if [ "$percent" -lt 100 ];
then
full_flag=0
fi
Eu tenho um script Bash que verifica a bateria do meu laptop e me envia uma notificação do Android (via shuttle, um script Bash que eu escrevi que serve como interface cli para a API do Pushbullet). Funciona muito bem, mas repetidamente me notificará para desconectar meu laptop quando a bateria atingir 100%. Em vez disso, eu prefiro que apenas me notifique 100% da carga uma vez, e é isso (ou seja, continue verificando, mas não notifique). No entanto, quero que ele me notifique repetidamente quando a bateria estiver fraca, para que eu lembre de conectar o laptop (que é atualmente o que ele faz).
Eu estava pensando que isso é possível usando comandos continue e break dentro do loop, mas não tenho certeza se é isso que eu quero (não estou muito familiarizado com eles).
De qualquer forma, gostaria de receber sugestões sobre como melhor implementar isso usando o Bash. Eu suspeito que isso é muito simples, mas eu não estou entendendo por algum motivo.
Aqui está o meu script:
#! /bin/bash
while true;
do
percent=$(acpi | awk '{ print $4}' | sed -e 's/%//g' | sed -e 's/,//g')
if [ "$percent" -le "20" ];
then
shuttle push note Chrome "Aurora: Plug in now" "Battery is at $percent percent"
fi
if [ "$percent" -eq "100" ];
then
shuttle push note Chrome "Aurora: Battery charged" "Battery is at $percent percent"
fi
sleep 7m
done
push(){
shuttle push note Chrome \
"Aurora: $1" \
"Battery is at $percent percent"
}
full=0
while percent=$(acpi | awk '{ print $4}' | sed 's/[,%]//g')
do case $percent:$full in
(100:1) ;; (100:0)
full=1
push 'Battery charged';;
(?:*|1?:*|20:*)
full=0
push 'Plug in Now';;
(*1) full=0
esac
done
A instrução case
do shell permite que você execute um bloco de código arbitrário baseado em se um padrão de shell pode ou não ser comparado com o valor de uma expansão do shell. Desta forma, você pode simplesmente lidar com múltiplos resultados possíveis do mesmo teste.
Acima eu concateno os valores de $percent
e $full
em um delimitador de :
dois pontos, que é uma técnica que eu peguei originalmente de Stephane Chazelas, mesmo que eu tenha me tornado bastante bom desde então. Como o código executado precisa depender dos dois valores, testá-los simultaneamente é a solução mais simples.
case
são avaliados em ordem do primeiro ao último. Assim que um padrão é correspondido, o código associado é executado e case
é retornado. O primeiro padrão correspondente também é o último padrão avaliado.
E se os valores de $percent
e $full
forem respectivamente:
100 e 1
case
retorna para while
. 100 e 0
$full
para 1 e chama a função de shell push
w / o argumento Battery Charged
push()
só é definido aqui para organizar o código de acordo com a finalidade. < = 20 e qualquer coisa
$full
é definido como 0 e push
é chamado com o arg Plug in Now
. qualquer coisa e 1
$full
está definido como 0. Qualquer outra coisa
Em resumo, isso significa que $full
é definido apenas quando necessário, push()
só é chamado quando $full
é 0 e $percent
é 100 ou $full
é nada e $percent
é < = 20.
Tudo isso seria uma melhoria em relação ao que você já tem. Mas o problema real é:
percent=$(acpi | awk '{ print $4}' | sed 's/[,%]//g')
Bifurcar várias vezes como essa em while true
é incrivelmente um desperdício. Você tem que pensar em outra maneira de fazer isso.
continue
pula para a próxima iteração do loop. break
sai do loop completamente. Nenhum deles é útil se você quiser ter algum efeito em futuras iterações. Para isso, você precisa se lembrar da informação de que algo tem que se comportar de maneira diferente. A maneira de lembrar algumas informações é armazená-las em uma variável.
Uma maneira de fazer o que você deseja é armazenar o valor anterior de percent
em uma variável previous
. Se percent
e previous
forem ambos 100, não imprima uma mensagem.
Dado que você está executando isso em segundo plano para monitorar a bateria, você deve se esforçar para não usar muita energia. Minimize o número de processos.
Em vez de executar o loop em true
, execute o loop no comando sleep
. Dessa forma, você pode matar o script matando o comando sleep
, quando ele estiver em execução, o que acontece na maior parte do tempo.
Recue seu código. Qualquer coisa dentro de um bloco ( do
, then
, etc.) deve ter mais espaço em branco à esquerda, por um número consistente.
previous=
while sleep 7m
do
percent=$(acpi | awk '{ gsub(/[^ 0-9]/, ""); print $4 }')
if [ "$percent" -le "20" ]; then
shuttle push note Chrome "Aurora: Plug in now" "Battery is at $percent percent"
elif [ "$percent" -eq "100" ] && [ "$previous" -ne "100" ]; then
shuttle push note Chrome "Aurora: Battery charged" "Battery is at $percent percent"
fi
done