use*_*074 6 bash d-bus notifications
我正在尝试编写一个 BASH 脚本,每次在 dbus-monitor 的输出中找到某个字符串(稍后在帖子中指定的参数)时,该脚本都会创建一个时间戳(要写入文件)。我的脚本的主要目的是在 Spotify 上开始播放歌曲时节省时间(包括毫秒)和日期,因为它使用通知。
string "Spotify"
每当播放歌曲时,就会输出以下命令。
dbus-monitor --session interface='org.freedesktop.Notifications',member='Notify' | grep 'string "Spotify"'
Run Code Online (Sandbox Code Playgroud)
我的尝试:
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
Run Code Online (Sandbox Code Playgroud)
我假设代码功能障碍的原因是 dbus-monitor 持续运行,因此阻止了 while 循环的执行。
使用awk
而不是grep
- 类似:
dbus-monitor ... | awk '/Spotify/ {
system("date -u +%Y%m%d-%H%M%S.%N >> timestamp.txt")
}'
Run Code Online (Sandbox Code Playgroud)
(注意使用%Y%m%d
代替%Y%M%D
- 大写-M 是分钟,而不是月。大写-D 相当于%m/%d/%y
)
每当在输入中看到“Spotify”时,这将使用 awk 的system()
函数在子 shell 中运行 date 命令。或者,使用 awk 的内置日期格式和重定向:
dbus-monitor ... | awk '/Spotify/ {
print strftime("%Y%m%d-%H%M%S") >> "timestamp.txt"
}'
Run Code Online (Sandbox Code Playgroud)
此版本不会在时间戳中打印纳秒,因为strftime()
不支持%N
.
或者,使用 perl 而不是 awk。这将允许您使用 perl 的Desktop::Notify模块来获取通知或Net::DBus来直接与 dbus 进行通信。
由于您有 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
Run Code Online (Sandbox Code Playgroud)
dbus-monitor
已经禁用缓冲,所以stdbuf -oL
没有必要。
-u
GNU 的选项会sed
禁用输出缓冲,并使其在此处不可查找时一次读取一个字节的输入。我们不需要后者,但我们需要前者,以便它在读取时立即输出一行。
在这里,每次找到包含 的行时我们都会sed
输出。now
string "Spotify"
那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"'
)
Run Code Online (Sandbox Code Playgroud)
这应该有效:
\nstdbuf -oL dbus-monitor --session interface='org.freedesktop.Notifications',member='Notify' |\nwhile grep -q 'string "Spotify"'; do\n date -u +%Y%M%d-%H%M%S.%N >> timestamp.txt\ndone\n
Run Code Online (Sandbox Code Playgroud)\n在 @St\xc3\xa9phaneChazelas 评论后编辑:
\nstdbuf -oL dbus-monitor --session interface='org.freedesktop.Notifications',member='Notify' |\ngrep --line-buffered 'string "Spotify"' |\nwhile read trash; do\n stdbuf -oL date -u +%Y%M%d-%H%M%S.%N >> timestamp.txt\ndone\n
Run Code Online (Sandbox Code Playgroud)\n+1 个其他答案,但为了完整性我保留这个答案
\n