37

I am running the 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.

5
  • 2
    Why can't you use the 3 options you mentioned?
    – Tim
    Aug 1, 2014 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? Aug 1, 2014 at 20:08
  • 8
    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, 2014 at 20:13
  • 1
    @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, 2014 at 20:54
  • @dan08 Nope, not doing the trick.
    – FUZxxl
    Aug 1, 2014 at 20:55

5 Answers 5

18

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"
1
  • This is a great answer. I will use this in the future.
    – FUZxxl
    Jan 12, 2015 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"'
1
  • That looks slightly better. I'm going to test that.
    – FUZxxl
    Aug 2, 2014 at 10:19
2

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.

The newer version, which at some point will make use of the advgetopt library, is in C++.

4
  • The link is dead.
    – Armin Rigo
    Oct 25, 2019 at 6:05
  • @ArminRigo, Ah! It moved. Here I put a new link to the latest before it moved because now it's C++. There is also a link to the C++ version. The C version won't change any more. Oct 25, 2019 at 6:19
  • 1. When compile with gcc hide-warnings.c -o hide-warnings: hide-warnings.c:67:20: fatal error: iostream: No such file or directory. 2. Tried g++: -> g++ hide-warnings.c -o hide-warnings hide-warnings.c:90:33: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11 [enabled by default] size_t f_pos = 0; ^ 3. ./hide-warnings gvim hide-warnings.c can't hide warnings. (gvim:4787): Gdk-CRITICAL **: 10:44:43.426: IA__gdk_drawable_get_size: assertion 'GDK_IS_DRAWABLE (drawable)' failed
    – Fisher
    Mar 3, 2021 at 9:46
  • @Fisher, which version are you trying to compile? The link above gives you access to a C version which hasn't changed for a while and will give you what you need. The gcc command should still work as is against it. Otherwise, you could install the advgetopt package (2.0.17+) which includes the tool now. To install a PPA, you first need to add it. Instructions are on this other page. Packages are not available for all versions, but it's 16, 18, and 20 already. Mar 3, 2021 at 22:39
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.

0

One solution is to create a function to suppress the Gtk error messages.

Sometimes, it's not obvious where the error is coming from.

For example, if you have the following in your .gitconfig, which tells git to use meld to as it's git difftool:

[diff]
    tool = meld
[difftool]
    prompt = false
[difftool "meld"]
    cmd = meld "$LOCAL" "$REMOTE"

And then you attempt to diff a your .bashrc file:

$ git difftool .bashrc

You might get a lot of annoying Gtk error messages:

2021-04-12 18:01:59,905 CRITICAL Gtk: gtk_widget_get_scale_factor: assertion 'GTK_IS_WIDGET (widget)' failed
2021-04-12 18:01:59,905 CRITICAL Gtk: gtk_widget_get_scale_factor: assertion 'GTK_IS_WIDGET (widget)' failed
2021-04-12 18:01:59,905 CRITICAL Gtk: gtk_widget_get_scale_factor: assertion 'GTK_IS_WIDGET (widget)' failed
2021-04-12 18:01:59,905 CRITICAL Gtk: gtk_widget_get_scale_factor: assertion 'GTK_IS_WIDGET (widget)' failed
2021-04-12 18:01:59,905 CRITICAL Gtk: gtk_widget_get_scale_factor: assertion 'GTK_IS_WIDGET (widget)' failed
. . .

Create a function that will redirect your output and stderr to /dev/null

$ function git-difftool(){ git difftool ${@} & &>/dev/null; }

Now, when you run git-difftool .bashrc, you'll see no more Gtk error messages.

A side benefit is that by adding the ampersand control operator in the definition of the git-difftool function, you can run this command in the background, which will free up your terminal, s.t., you can run other commands along with your meld difftool window.

1
  • I couldn't redirect error output from meld until I commented out line in /usr/bin/meld: # disable_stdout_buffering()
    – d9k
    Feb 2, 2022 at 22:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .