How can I solve "unmatched double quote" error using dbus-monitor in combination with xargs?

8,368

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.

Share:
8,368

Related videos on Youtube

Jacob Vlijm
Author by

Jacob Vlijm

Team member of the Ubuntu Budgie team as developer of o.a. Window Shuffler. Professional musician & teacher. Always triggerd to achieve what seems impossible.

Updated on September 18, 2022

Comments

  • Jacob Vlijm
    Jacob Vlijm over 1 year

    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"$
    
    • Sergiy Kolodyazhnyy
      Sergiy Kolodyazhnyy over 7 years
      my guess would be that what gets passed to xargs has double quote in it. Try verifying that with substituting cat -A instead of xargs there
    • Jacob Vlijm
      Jacob Vlijm over 7 years
      @Serg you are totally right! Be it that it seems a bug in the HP -notification. It outputs "hplip"$ "HPLIP Device Status"$ "Officejet_Pro_8600$ "transient"$, which indeed shows an unmatched double quote (in "Officejet_Pro_8600$)
    • Sergiy Kolodyazhnyy
      Sergiy Kolodyazhnyy over 7 years
      Yup, the guess was right. Might be a bug in their notification, might be not. You have whole lot of pipes with grep, so check those too before making final conclusion.
    • Jacob Vlijm
      Jacob Vlijm over 7 years
      @Serg Yeah, clearly a bug in hplip: "Officejet_Pro_8600$ - an incorrect notification...
    • Sergiy Kolodyazhnyy
      Sergiy Kolodyazhnyy over 7 years
      in that case maybe use tr -d '"' to delete the double quotes ?
    • Sergiy Kolodyazhnyy
      Sergiy Kolodyazhnyy over 7 years
      tr -d '"' is used to delete specific characters. So , you want to place it between last grep and xargs so , try grep --line-buffered -v '^\s*$' | tr -d '"' | xargs . . . . Not ideal solution, of course, but at least you don't have to deal with unmatched double quotes then
    • Jacob Vlijm
      Jacob Vlijm over 7 years
  • Jacob Vlijm
    Jacob Vlijm over 7 years
    The second one makes the output always show the before-latest -one. The first one seems to do the job well however with about everything I tried so far, even shows the hplip notification correctly :). Thanks for this!