Hi Henrik. It's not a bug, and it's described in the manpage:
When type is binary, grep may treat non-text bytes as line terminators even without the -z option. This means choosing binary versus text can affect whether a pattern matches a file. For example, when type is binary the pattern q$ might match q immediately followed by a null byte, even though this is not matched when type is text. Conversely, when type is binary the pattern . (period) might not match a null byte. Despite its appearance, /proc/*/cmdline is a binary file, because args are separated by zero bytes, instead of blanks. It happens that the cmdline for the first command contains ...NUL^(telegram-desktop)$NUL... and does not match the ERE '^(telegram-desktop)$' (or the equivalent '^telegram-desktop$'), while the cmdline for the second contains ...NULtelegram-desktopNUL... which DOES match -x 'telegram-desktop' because the surrounding NULs are treated as line boundaries. By the way, parsing files under /proc, or the output of the ps command, requires special care when done with grep and friends. One popular trick to avoid matching itself is to make some little changes to the ERE. E.g. ps -elf | grep '\<some[t]hing\>' mathes "run something" without matching the grep process. However, the easiest way to cope with process tables is pgrep(1). Best, g1