私はラップトップのバッテリーをチェックしてAndroid通知を送信するBashスクリプトを持っています(シャトル経由で、Pushbullet APIのcliインターフェースとして機能する私が書いたBashスクリプトです)。バッテリーが100%に達すると、ラップトップのプラグを抜くように繰り返し通知します。代わりに、100%の充電を一度通知するだけで、それだけです(つまり、チェックを続けますが通知しません)。ただし、バッテリーが少なくなったときに繰り返し通知するようにしたいので、ラップトップを接続するのを忘れないでください(これは現在、ラップトップに接続しています)。
ループ内でcontinueコマンドとbreakコマンドを使用してこれが可能であると考えていましたが、それが私が望んでいるものかどうかはわかりません(あまり詳しくありません)。
とにかく、Bashを使用してこれを最適に実装する方法に関する提案をいただければ幸いです。これは非常に単純だと思いますが、何らかの理由で取得できません。
これが私のスクリプトです:
#! /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
どうですか:
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
_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
_
シェルのcase
ステートメントを使用すると、シェルパターンをシェル展開の値と照合できるかどうかに基づいて、任意のコードブロックを実行できます。このようにして、まったく同じテストの複数の可能な結果を非常に簡単に処理できます。
上記では、_$percent
_と_$full
_の値を_:
_コロン区切り文字で連結しています。これは、自分でかなり上手になったとしても、もともとStephane Chazelasから採用した手法です。以来。実行されるコードは両方の値に依存する必要があるため、両方を同時にテストすることが最も簡単なソリューションです。
case
パターンブロックは、最初から最後の順に評価されます。パターンが一致するとすぐに、関連するコードが実行され、case
が返されます。最初に一致したパターンは、最後に評価されたパターンでもあります。
そして、もし_$percent
_と_$full
_の値がそれぞれ:
100と1
case
はwhile
に戻ります。100と0
$full
_を1に設定し、引数_Battery Charged
_を使用してシェル関数Push
を呼び出しますPush()
は、目的に応じてコードを編成するためにここでのみ定義されています。<= 20および何でも
$full
_が0に設定され、Push
が引数_Plug in Now
_で呼び出されます。まったく何でも1
$full
_が0に設定されます。他に何か
つまり、_$full
_が必要な場合にのみ設定され、_$full
_が0で_$percent
_が100または_$full
_である場合にのみPush()
が呼び出されます。何でも、_$percent
_は<= 20です。
これらはすべて、すでに持っているものを改善するものです。しかし、実際の問題は次のとおりです。
_percent=$(acpi | awk '{ print $4}' | sed 's/[,%]//g')
_
そのような_while true
_での複数回のフォークは信じられないほど無駄です。あなたはそれを行う別の方法を考え出さなければならない。
continue
は、ループの次の反復にジャンプします。 break
はループを完全に終了します。将来の反復に何らかの影響を与えたい場合は、どちらも役に立ちません。そのためには、何かが異なる動作をする必要があるという情報を覚えておく必要があります。一部の情報を記憶する方法は、それを変数に格納することです。
必要なことを行う1つの方法は、percent
の以前の値を変数previous
に格納することです。 percent
とprevious
の両方が100の場合、メッセージを出力しません。
バッテリーを監視するためにこれをバックグラウンドで実行していることを考えると、電力を使いすぎないように努力する必要があります。プロセスの数を最小限に抑えます。
true
でループする代わりに、sleep
コマンドでループします。このように、ほとんどの場合、実行中のsleep
コマンドを強制終了することにより、スクリプトを強制終了できます。
コードをインデントします。ブロック内のすべて(do
、then
など)は、一貫した番号によって、左側に空白を追加する必要があります。
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