dbus-monitor의 출력에서 특정 문자열이 발견될 때마다 타임스탬프(파일에 기록될)를 생성하는 BASH 스크립트를 작성하려고 합니다(매개변수는 나중에 지정됨). 내 스크립트의 주요 목적은 알림을 사용하기 때문에 Spotify에서 노래가 재생되기 시작하는 시간(밀리초 포함)과 날짜를 절약하는 것입니다.
string "Spotify"
노래가 재생될 때마다 다음 명령이 출력됩니다.
dbus-monitor --session interface='org.freedesktop.Notifications',member='Notify' | grep 'string "Spotify"'
내 시도:
search='string "Spotify"'
found=$(dbus-monitor --session interface='org.freedesktop.Notifications',member='Notify' | grep 'string "Spotify"')
while [ ${search} == ${found} ]; do
date -u +%Y%M%d-%H%M%S.%N >> timestamp.txt
done
코드 기능 장애의 원인은 dbus-monitor가 계속 실행되어 while 루프의 실행을 차단하기 때문이라고 가정합니다.
답변1
awk
대신 사용하십시오 grep
. 다음과 같습니다.
dbus-monitor ... | awk '/Spotify/ {
system("date -u +%Y%m%d-%H%M%S.%N >> timestamp.txt")
}'
( 월이 아닌 분 동안 -M %Y%m%d
대신 대문자 M이 사용됩니다 . CAPS-D는 동일합니다 .)%Y%M%D
%m/%d/%y
이것은 입력에 "Spotify"가 표시될 때마다 awk의 system()
기능을 사용하여 하위 쉘에서 date 명령을 실행합니다 . 또는 awk에 내장된 날짜 형식과 리디렉션을 사용하세요.
dbus-monitor ... | awk '/Spotify/ {
print strftime("%Y%m%d-%H%M%S") >> "timestamp.txt"
}'
strftime()
이 버전은 지원되지 않기 때문에 타임스탬프에 나노초를 인쇄하지 않습니다 %N
.
아니면 awk 대신 perl을 사용하세요. 이렇게 하면 Perl을 사용할 수 있습니다.데스크탑::알림알림을 받기 위한 모듈 또는네트워크::DBusdbus와 직접 통신하세요.
답변2
GNU 유틸리티가 있으므로 다음을 수행할 수 있습니다.
dbus-monitor --session interface='org.freedesktop.Notifications',member='Notify' |
sed -un 's/^.*string "Spotify".*$/now/p' |
stdbuf -oL date -uf - +%Y%m%d-%H%M%S.%N >> timestamp.txt
dbus-monitor
이미버퍼링 비활성화, 그래서 stdbuf -oL
거기에는 필요가 없습니다.
-u
GNU의 옵션은 sed
출력 버퍼링을 비활성화하고 여기에서 검색할 수 없는 경우 입력을 한 번에 한 바이트씩 읽도록 합니다. 후자가 필요하지는 않지만, 읽자마자 한 줄을 출력하려면 전자가 필요합니다.
여기서는 sed
포함된 줄이 발견될 때마다 인쇄합니다.now
string "Spotify"
그것은 표준 입력 에서 읽고 인쇄하는 Feed.use now
입니다 . 각 읽기에 대해 현재 시간을 지정된 형식으로 인쇄합니다. 출력이 청크 단위가 아닌 즉시 파일에 들어가도록 보장합니다.date
-f -
date
date
now
stdbuf -oL
timestamp.txt
zsh/bash/ksh93을 사용하여 현재 시간을 출력하는 것 외에 임의의 명령을 실제로 실행하려면 다음을 수행할 수 있습니다.
while IFS= read -ru3 line || [ -n "$line" ]; do
any arbitrary command
done 3< <(
dbus-monitor --session interface='org.freedesktop.Notifications',member='Notify' |
grep --line-buffered 'string "Spotify"'
)
답변3
이것은 작동합니다:
stdbuf -oL dbus-monitor --session interface='org.freedesktop.Notifications',member='Notify' |
while grep -q 'string "Spotify"'; do
date -u +%Y%M%d-%H%M%S.%N >> timestamp.txt
done
@StéphaneChazelas의 댓글 이후 편집:
stdbuf -oL dbus-monitor --session interface='org.freedesktop.Notifications',member='Notify' |
grep --line-buffered 'string "Spotify"' |
while read trash; do
stdbuf -oL date -u +%Y%M%d-%H%M%S.%N >> timestamp.txt
done
+1 다른 답변이지만 완전성을 위해 이 답변을 유지합니다.
답변4
dbus-monitor
이 경우 타임스탬프(에포크 시간 + 마이크로초 단위)가 제공된 것처럼 보입니다 . 따라서 date
모든 게임에 대해 이를 수행 할 필요는 없을 것입니다 . 예를 들어 arg0='Spotify'
다음을 사용하여 일치하는 표현식의 범위를 좁힐 수 있습니다 .
이 출력을 확인하십시오.
dbus-monitor "
type='method_call',
interface='org.freedesktop.Notifications',
member='Notify',
arg0='Spotify'"
Spotify의 알림과 관련된 dbus 메시지만 볼 수 있기를 바랍니다. (테스트할 수 없습니다. 이것은 단지 살펴보는 것뿐입니다.버스 사양). 이것이 작동한다면 다음이 적절할 수 있습니다.
dbus-monitor --profile "type='method_call',
interface='org.freedesktop.Notifications', member='Notify', arg0='Spotify'" |
gawk -F '\t' '
$NF=="Notify" {
secs = usecs = $2
sub(/^[^.]+/,"",usecs)
print strftime("%Y%m%d-%H%M%S",int(secs),"UTC") usecs
fflush()
}' > timestamp.log
--profile
기본 출력보다 구문 분석하기가 더 쉬워 보이기 때문에 출력 형식 에 사용됩니다 --monitor
. 타임스탬프를 추출하고 형식을 지정하려면 GNU로 파이프하세요 awk
.