如何使用dbus-monitor结合xargs解决"unmatched double quote"错误?

在Linux(Ubuntu)上拦截(notify-osd)通知,我使用下面的dbus-monitor脚本。随后,该脚本会运行另一个脚本(/opt/nonotifs/nonotifs/silent),并将拦截到的通知作为参数进行进一步处理:
#!/bin/bash

dbus-monitor "interface='org.freedesktop.Notifications'" | \
grep --line-buffered "string" | \
grep --line-buffered -e method -e ":" -e '""' -e urgency -e notify -v | \
grep --line-buffered '.*(?=string)|(?<=string).*' -oPi | \
grep --line-buffered -v '^\s*$' | \
xargs -I '{}' /opt/nonotifs/nonotifs/silent {}

这个工作非常顺利,除了hplip的通知有关。

enter image description here

当从终端运行上述脚本时,会显示:
xargs: unmatched double quote; by default quotes are special to xargs unless you use the -0 option

当使用选项-0时,脚本不提供任何参数。

我尝试过的方法

在某些情况下,脚本随后会出现错误。如果总是这样,可以通过在“保持活动”包装器中运行它来解决,我已经尝试过了。然而,通常情况下,脚本不会终止,但它仍然停止返回拦截的通知。

我该如何解决这个问题?

编辑

如@Serg所建议的那样,我用cat -A替换了xargs...部分,以查看传递给xargs的内容。这表明,在hplip的通知中确实存在一个未匹配的双引号(第三行),这似乎是通知中的一个错误。

使用cat -A调用通知时的输出:

"hplip"$ 
"HPLIP Device Status"$ 
"Officejet_Pro_8600$ 
"transient"$

1我猜测传递给 xargs 的内容中有双引号。尝试用 cat -A 替换 xargs 来验证一下。 - Sergiy Kolodyazhnyy
@Serg 你说得完全正确!这似乎是HP通知中的一个错误。它输出了"hplip"$ "HPLIP设备状态"$ "Officejet_Pro_8600$ "transient"$,其中确实显示了一个不匹配的双引号(在"Officejet_Pro_8600$)。 - Jacob Vlijm
是的,猜对了。可能是他们通知系统的一个错误,也可能不是。你有很多带有grep的管道,请在最终得出结论之前检查它们。 - Sergiy Kolodyazhnyy
@Serg 是的,显然是hplip的一个错误:"Officejet_Pro_8600$ - 一个不正确的通知... - Jacob Vlijm
在这种情况下,也许可以使用 tr -d '"' 命令删除双引号? - Sergiy Kolodyazhnyy
tr -d '"' 是用来删除特定字符的命令。所以,你想把它放在最后一个 grepxargs 之间,试试这样:grep --line-buffered -v '^\s*$' | tr -d '"' | xargs . . . . 当然,并不是理想的解决方案,但至少你不必再处理无法匹配的双引号了。 - Sergiy Kolodyazhnyy
让我们在聊天中继续这个讨论:http://chat.stackexchange.com/rooms/47615/discussion-between-jacob-vlijm-and-serg。 - Jacob Vlijm
1个回答

man xargs中:

--delimiter=delim
-d delim
      输入项以指定的字符终止。引号和反斜杠不是特殊字符;输入中的每个字符都被视为字面值。禁用文件结束字符串,该字符串与任何其他参数一样对待。当输入仅由换行符分隔的项组成时,可以使用此选项,尽管最好设计程序以使用--null(如果可能)。指定的分隔符可以是单个字符、C风格的字符转义(如\n)或八进制或十六进制转义码。八进制和十六进制转义码的理解方式与printf命令相同。不支持多字节字符。

例如:

$ echo '"""' | xargs
\xargs: unmatched double quote; by default quotes are special to xargs unless you use the -0 option
$ echo '"""' | xargs -d '\n'
"""

$ echo '"""' | xargs -d ' ' 
"""

当然,使用任何一个都可能会出现问题,但也许不会像-0那样严重。

第二个使输出始终显示倒数第二个。第一个似乎做得很好,但是到目前为止我尝试的所有东西都可以正确显示hplip通知:)。谢谢! - Jacob Vlijm