27

I am running awesome window manager on trusty after having upgraded from raring. My desktop environment intentionally does not have all the Gnome / Freedesktop daemons running — I don't want them.

When I execute gedit from a terminal like this:

gedit file

It outputs messages like this all over my terminal whenever I hit enter or save or on various other occasions:

(gedit:5700): Gtk-WARNING **: Calling Inhibit failed: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name org.gnome.SessionManager was not provided by any .service files

I understand the meaning of this warning and I have decided that it doesn't matter to me.

How can I turn off this kind of warning? By "turn off", I don't mean any of these or similar workarounds:

  • piping the output of gedit into /dev/null
  • writing a wrapper script that pipes the output of gedit into /dev/null
  • creating an alias that pipes the output of gedit into /dev/null

These workarounds are not acceptable as they have to be applied individually to each Gnome application — gedit is not the only one that likes to mess up the terminal.

  • 2
    Why can't you use the 3 options you mentioned? – Tim Aug 1 '14 at 20:05
  • I don't think you can turn off those warnings, but as @Tim asked, what do you have against using the 3 options that would solve your issue? – ElefantPhace Aug 1 '14 at 20:08
  • 7
    Thanks, I know how to do shell redirection. The reason why I don't want to do this (and explicitly state that) is that these warnings also appear in many other programs. A configuration option for dbus or whatever component that generates these warnings will turn off the warning for all programs that generates it. With redirection, I have to apply the workaround (which is not a solution) to each program individually. – FUZxxl Aug 1 '14 at 20:13
  • @FUZxxl I can't get my gedit to output errors consistently. But I'm curious if export GCONF_DEBUG="no" would do anything – Dan Aug 1 '14 at 20:54
  • @dan08 Nope, not doing the trick. – FUZxxl Aug 1 '14 at 20:55
12

First, I also find it annoying that these warnings show up on an out-of-the-box Ubuntu, with no "proper" method to disable them which I could find (it seems that the most common "solution" is either to install gir1.2-gtksource-3.0 which doesn't seem to work since it's already installed, or to ignore them - but I want to suppress them completely since they just make my terminal noisy).

I came up with the following code which so far seems to behave exactly how I'd expect it to, and is based on the answer by TuKsn, but enhances it a bit to:

  • Work by default (gedit ...) without needing to use F12 or some other shortcut (to invoke unfiltered use /usr/bin/gedit ...).
  • Displays the entered command name when it terminates as a background task.

Can still be generalized a bit, but for now, if you need the same treatment for other commands, duplicate the gedit() function for each other command name which needs the same filter.

# solution adapted from: http://askubuntu.com/questions/505594
# TODO: use a list of warnings instead of cramming all of them to a single grep.
# TODO: generalize gedit() to allow the same treatment for several commands
#       without duplicating the function with only a different name
# output filter. takes: name_for_history some_command [arguments]
# the first argument is required both for history, but also when invoking to bg
# such that it shows Done <name> ... instead of e.g. Done /usr/bin/gedit ...
suppress-gnome-warnings() {
    # $1 is the name which should appear on history but is otherwise unused.
    historyName=$1
    shift

    if [ -n "$*" ]; then
        # write the real command to history without the prefix
        # syntax adapted from http://stackoverflow.com/questions/4827690
        history -s "$historyName ${@:2}"

        # catch the command output
        errorMsg=$( $* 2>&1 )

        # check if the command output contains not a (one of two) GTK-Warnings
        if ! $(echo $errorMsg | grep -q 'Gtk-WARNING\|connect to accessibility bus'); then
            echo $errorMsg
        fi
    fi
}
gedit() {
  suppress-gnome-warnings $FUNCNAME $(which $FUNCNAME) $@
}

And a better version (way smaller, fully generic, no need to rewrite history since invoked as is, and better for filtering per line rather than the whole output):

# generates a function named $1 which:
# - executes $(which $1) [with args]
# - suppresses output lines which match $2
# e.g. adding: _supress echo "hello\|world"
# will generate this function:
# echo() { $(which echo) "$@" 2>&1 | tr -d '\r' | grep -v "hello\|world"; }
# and from now on, using echo will work normally except that lines with
# hello or world will not show at the output
# to see the generated functions, replace eval with echo below
# the 'tr' filter makes sure no spurious empty lines pass from some commands
_supress() {
  eval "$1() { \$(which $1) \"\$@\" 2>&1 | tr -d '\r' | grep -v \"$2\"; }"
}

_supress gedit          "Gtk-WARNING\|connect to accessibility bus"
_supress gnome-terminal "accessibility bus\|stop working with a future version"
_supress firefox        "g_slice_set_config"
  • This is a great answer. I will use this in the future. – FUZxxl Jan 12 '15 at 13:39
2

Its also a workaround, but you don't have to apply this for every application.

Write this to your .bashrc and you can use this wrapper with F12 (or chose another key) to suppress the warnings:

# output filter
of() { 
    if [ -n "$*" ]; then   
        # write the real command to history without the prefix "of" 
        history -s "$*"

        # catch the command output
        errorMsg=$( $* 2>&1 )

        # check if the command output contains not a GTK-Warning
        if ! $(echo $errorMsg | grep -q 'Gtk-WARNING'); then
            echo $errorMsg 
        fi
    fi
}

# write the function "of" before every command if the user presses F12
bind '"\e[24~": "\e[1~ of \e[4~\n"'
  • That looks slightly better. I'm going to test that. – FUZxxl Aug 2 '14 at 10:19
1

I actually wrote the hide-warnings tool in C which I find much easier to use than the script shown above. Also, it will write all the output written to stdout by default (because the Gtk and other warnings are sent to stderr so it parses stderr not stdout by default).

One big problem with the script above is that it won't write anything to your console, even if it does not match the regex, until done. This is because it saves all the data in a variable and then grep that variable once done. It also means that it will save the output in that variable possibly using a lot of memory (at least you should save that in a temporary file.) Finally, from what I can see, the grep will prevent any display if any one line matches. Maybe not exactly what you want.

The tool can be used in a simple alias like this:

alias gvim="hide-warnings gvim"

(I use gvim... I'm sure it would work with gedit too.)

The file is self contained, no dependencies other than the C library, so you can get a copy and easily compile and install it:

gcc hide-warnings.c -o hide-warnings
sudo cp hide-warnings /usr/bin/.

There is some further documentation in the file and you can use --help once compiled for quick docs.

0

I was looking to find a utility to solve this sort of problem, myself.

My issues with the provided answers are as follows:

  • it's important that stdout and stderr don't get aggregated into one stream
  • I cannot invoke a command, filter all the output until it terminates, and print it at the end (i.e. the solution must stream the output properly)
  • I would like to preserve the order of stdout and stderr messages as much as possible

I appreciate the attempts I've seen to do this with Bash, however, I failed to identify a solution that achieved all 3 of the conditions outlined above.

My ultimate solution is written in NodeJS, which I understand will not be installed on many linux boxes. Before choosing to write the JS version, I attempted to code it in python, and found the async IO library is pretty ugly and broken until VERY recent versions of python (~3.5 which is available out-of-box on SOME newer distros).

Minimizing dependencies was the ONLY reason to choose python, so I abandoned it for NodeJS, which has a remarkable set of libraries for somewhat low-level, async-oriented IO.

Here it is:

#!/usr/bin/env nodejs

const spawn = require('child_process').spawn

function usage() {
    console.warn('Usage: filter-err <error regex> <cmd> [<cmd arg> ...]')
    process.exit(1)
}

function main(err_regex, cmd_arr) {
    let filter = new RegExp(err_regex)

    let proc = spawn(cmd_arr[0], cmd_arr.slice(1), {
        shell: true,
        stdio: ['inherit', 'inherit', 'pipe']
    })

    proc.stderr.on('data', (err) => {
        err = err.toString('utf8')

        if (! err.match(filter))
            process.stderr.write(err)
    })

    proc.on('close', (code) => process.exit(code))
}

const argv = process.argv

if (argv.length < 4)
    usage()
else
    main(argv[2], argv.slice(3))

To use this script, you might add these lines to your .bashrc:

alias gimp='filter-err "GLib-[^ ]*-WARNING" gimp'

The subprocess you choose to run will inherit stdin, so you are free to use BASH pipes or redirection.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.