내 노트북의 배터리를 확인하고 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에게서 배웠고 그 이후로 나 자신도 꽤 능숙해졌습니다. 실행되는 코드는 두 값에 따라 달라지므로 두 값을 동시에 테스트하는 것이 가장 간단한 솔루션입니다.
case
패턴 블록은 처음부터 마지막까지 순서대로 평가됩니다. 패턴이 일치하면 해당 코드가 실행되어 case
반환됩니다. 일치하는 첫 번째 패턴은 평가된 마지막 패턴이기도 합니다.
$percent
따라서 및 값이 각각 다음과 $full
같은 경우:
100과 1
- 빈 코드 블록과 연결된 첫 번째 패턴이 일치했습니다. 아무 조치도 취하지 않고
case
로 돌아갑니다while
.
- 빈 코드 블록과 연결된 첫 번째 패턴이 일치했습니다. 아무 조치도 취하지 않고
100과 0
- 두 번째 패턴이 일치하고 1로 설정되며
$full
쉘 함수가 인수와 함께 호출됩니다.push
Battery Charged
push()
여기서는 목적에 따라 코드를 구성하기 위해서만 정의합니다.
- 두 번째 패턴이 일치하고 1로 설정되며
<=20 및 무엇이든
- 세 번째 패턴 일치는
$full
0으로 설정되고push
arg로 호출됩니다.Plug in Now
.
- 세 번째 패턴 일치는
무엇이든 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
루프를 완전히 종료합니다. 향후 반복에 영향을 미치려는 경우에는 두 가지 접근 방식 모두 유용하지 않습니다. 이렇게 하려면 무언가가 다른 정보를 나타내야 한다는 것을 기억해야 합니다. 일부 정보를 기억하는 방법은 해당 정보를 변수에 저장하는 것입니다.
원하는 것을 달성하는 한 가지 방법은 의 이전 값을 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