私のラップトップのバッテリーをチェックしてAndroid通知を送信するBashスクリプトがあります(Pushbullet APIへのcliインターフェースとして機能する私が書いたBashスクリプト、Shuttle経由)。うまくいきますが、バッテリーが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
答え1
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から学び、それ以来私自身もかなり上手になりました。実行されるコードは2つの値に依存するため、2つの値を同時にテストするのが最も簡単なソリューションです。
case
パターンブロックは、最初から最後まで順に評価されます。パターンが一致すると、そのコードが実行されてcase
返されます。一致する最初のパターンは評価された最後のパターンでもあります。
$percent
したがって、値がそれぞれ次$full
の場合:
100と1
- 空のコードブロックに関連付けられた最初のパターンが一致しました。何の処置も取らず
case
に戻りますwhile
。
- 空のコードブロックに関連付けられた最初のパターンが一致しました。何の処置も取らず
100と0
- 2番目のパターンが一致し、1に設定され、
$full
シェル関数が引数で呼び出されます。push
Battery Charged
push()
ここでは、目的に応じてコードを構築するためにのみ定義します。
- 2番目のパターンが一致し、1に設定され、
<= 20と何でも
- 3番目のパターンマッチングは
$full
0に設定され、push
argとして呼び出されます。Plug in Now
。
- 3番目のパターンマッチングは
何でも1
- 最後のパターンが一致して
$full
0に設定されました。
- 最後のパターンが一致して
その他
- 一致するパターンがなく、何もしません。
全体として$full
、これは必要な場合にのみ設定され、push()
0、100、または任意の値で<= 20の場合にのみ呼び出されることを意味します。$full
$percent
$full
$percent
これらすべては、あなたがすでに持っているものよりも向上します。しかし、実際の質問は次のとおりです。
percent=$(acpi | awk '{ print $4}' | sed 's/[,%]//g')
while true
のように何度もフォークしてください。信じられないゴミ。別の方法を見つける必要があります。
答え2
どうですか?
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
答え3
continue
ループの次の繰り返しにジャンプします。break
ループを完全に終了します。今後の反復に影響を与えたい場合は、どちらのアプローチも役に立ちません。これを行うには、何かが他の情報を表す必要があることを覚えておく必要があります。一部の情報を記憶する方法は、その情報を変数に保存することです。
必要なものを達成する1つの方法は、以前の値をpercent
変数に保存することですprevious
。percent
と両方がprevious
100の場合、メッセージは印刷されません。
バッテリーを監視するためにバックグラウンドでこのプログラムを実行しているので、あまりにも多くの電力を使用しないようにしてください。プロセス数を最小限に抑えます。
繰り返すのではなく、true
コマンドを繰り返しますsleep
。このようにして、sleep
スクリプトの実行中(ほとんどの場合)killコマンドを使用してスクリプトを終了できます。
コードをインデントします。ブロック(など)内の項目は、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