Fix ‘Unmatched Double Quote’ Error with dbus-monitor and xargs

command linedbusscriptsxargs

To intercept (notify-osd) notifications on Linux (Ubuntu), I am using the dbus-monitor script below. Subsequently, the script runs another script (/opt/nonotifs/nonotifs/silent) with the intercepted notification as argument, for further processing:

#!/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 {}

This works flawlessly, except with notifications by hplip.

enter image description here

When run from a terminal, the script above shows:

xargs: unmatched double quote; by default quotes are special to xargs unless you use the -0 option

When using the option -0 however, the script delivers no argument at all.

What I tried

In some cases, the script subsequently breaks. If that would always be the case, It could be worked around by running it in a "keep alive" -wrapper, which I tried. Often however, The script does not terminate, but it stops returning the intercepted notifications nevertheless.

How can I solve this?

Edit

As suggested by @Serg, I replaced the xargs... section by cat -A, to see what is passed to xargs. This shows that indeed there is an unmatched double quote in the notification of hplip (the third line), which seems to be a bug in the notification.

The output when running with cat -A, calling the notification:

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

Best Answer

From man xargs:

--delimiter=delim
-d delim
      Input  items  are terminated by the specified character.  Quotes
      and backslash are not special; every character in the  input  is
      taken  literally.   Disables  the  end-of-file  string, which is
      treated like any other argument.  This  can  be  used  when  the
      input consists of simply newline-separated items, although it is
      almost always better to design your program to use --null  where
      this  is  possible.   The  specified  delimiter  may be a single
      character, a C-style character escape such as \n, or an octal or
      hexadecimal escape code.  Octal and hexadecimal escape codes are
      understood as for the printf command.   Multibyte characters are
      not supported.

As an example:

$ 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 ' ' 
"""

Of course, using either may break things, but perhaps not as much as -0.