web-dev-qa-db-fra.com

Comment empêcher gedit (et d'autres programmes) d'émettre des avertissements GTK et autres dans mon terminal?

J'exécute le gestionnaire de fenêtres génial sur trusty après avoir mis à niveau à partir de raring. Mon environnement de bureau n'a intentionnellement pas tous les démons Gnome/Freedesktop en cours d'exécution - je ne les veux pas.

Quand j'exécute gedit à partir d'un terminal comme celui-ci:

gedit file

Il envoie des messages comme celui-ci sur mon terminal chaque fois que j'appuie sur entrée ou sauvegarde ou à d'autres 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

Je comprends le sens de cet avertissement et j'ai décidé que cela ne m'importait pas.

Comment puis-je désactiver ce type d'avertissement? Par "désactiver", je ne parle d'aucune de ces solutions de contournement ou d'une solution similaire:

  • piping la sortie de gedit dans /dev/null
  • écrire un script wrapper qui dirige la sortie de gedit dans /dev/null
  • créer un alias qui dirige la sortie de gedit dans /dev/null

Ces solutions de contournement ne sont pas acceptables car elles doivent être appliquées individuellement à chaque application Gnome - gedit n'est pas le seul à vouloir gâcher le terminal.

29
FUZxxl

Premièrement, je trouve également ennuyeux que ces avertissements apparaissent sur un Ubuntu prêt à l'emploi, sans méthode "appropriée" pour les désactiver, ce que je pourrais trouver (il semble que la "solution" la plus courante consiste à installer gir1.2-gtksource-3.0 qui ne semble pas fonctionner car il est déjà installé, ou les ignorer - mais je veux les supprimer complètement car ils ne font que rendre mon terminal bruyant).

Je suis arrivé avec le code suivant qui semble jusqu'à présent se comporter exactement comme je l'aurais souhaité, basé sur la réponse de TuKsn, mais l'améliorant un peu pour:

  • Travaillez par défaut (gedit ...) sans avoir à utiliser F12 ou un autre raccourci (pour appeler une utilisation non filtrée /usr/bin/gedit ...).
  • Affiche le nom de la commande entrée quand elle se termine en tâche de fond.

Peut encore être généralisé un peu, mais pour l'instant, si vous avez besoin du même traitement pour les autres commandes, dupliquez la fonction gedit() pour chaque nom de commande nécessitant le même filtre.

# 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) $@
}

Et une meilleure version (beaucoup plus petite, entièrement générique, pas besoin de réécrire l’historique puisque invoquée telle quelle, et meilleure pour le filtrage par ligne plutôt que l’ensemble de la sortie):

# 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"
13
avih

C'est aussi une solution de contournement, mais vous n'avez pas à l'appliquer à chaque application.

Ecrivez ceci dans votre .bashrc et vous pouvez utiliser ce wrapper avec F12 (ou choisir une autre clé) pour supprimer les avertissements:

# 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"'
2
TuKsn

J'ai en fait écrit le outil de masquage d'avertissements en C, que je trouve beaucoup plus facile à utiliser que le script présenté ci-dessus. En outre, il écrira par défaut toutes les sorties écrites dans stdout(car Gtk et d'autres avertissements sont envoyés à stderrafin d'analyser stderret non stdoutpar défaut).

Un gros problème avec le script ci-dessus est qu'il n'écrira rien sur votre console, même si cela ne correspond pas à la regex, jusqu'à ce que l'opération soit terminée. En effet, toutes les données d'une variable sont sauvegardées, puis cette variable est ensuite renvoyée à grep. Cela signifie également que cela enregistrera la sortie dans cette variable en utilisant éventuellement beaucoup de mémoire (au moins, sauvegardez-la dans un fichier temporaire). . Peut-être pas exactement ce que vous voulez.

L'outil peut être utilisé dans un alias simple comme celui-ci:

alias gvim="hide-warnings gvim"

(J'utilise gvimname __... Je suis sûr que cela fonctionnerait aussi avec geditname__.)

Le fichier est autonome, il n’ya pas de dépendances autres que la bibliothèque C, vous pouvez donc en obtenir une copie, le compiler et l’installer facilement:

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

Il existe une documentation supplémentaire dans le fichier et vous pouvez utiliser --help une fois compilé pour une documentation rapide.

1
Alexis Wilke

Je cherchais moi-même un utilitaire pour résoudre ce type de problème.

Mes problèmes avec les réponses fournies sont les suivantes:

  • il est important que stdout et stderr ne soient pas regroupés en un seul flux
  • Je ne peux pas appeler une commande, filtrer toute la sortie jusqu'à ce qu'elle se termine et l'imprimer à la fin (c'est-à-dire que la solution doit diffuser correctement la sortie)
  • Je souhaite préserver autant que possible l'ordre des messages stdout et stderr

J'apprécie les tentatives que j'ai vues faire cela avec Bash, cependant, je n'ai pas réussi à identifier une solution qui remplit les trois conditions décrites ci-dessus.

Ma solution ultime est écrite dans NodeJS, qui, à ce que je comprends, ne sera pas installée sur de nombreuses boîtes Linux. Avant de choisir d’écrire la version JS, j’ai essayé de la coder en python et j’ai trouvé que la bibliothèque async. IO est assez moche et cassée jusqu’à ce que les versions TRES récentes de python (~ 3.5, qui est disponible en option sur CERTAINES nouvelles distributions).

Minimiser les dépendances était la SEULE raison de choisir python. Je l’ai donc abandonné pour NodeJS, qui possède un ensemble remarquable de bibliothèques pour des E/S asiatiques de bas niveau.

C'est ici:

#!/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))

Pour utiliser ce script, vous pouvez ajouter ces lignes à votre fichier .bashrc:

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

Le sous-processus que vous choisissez d'exécuter héritera de stdin. Vous êtes donc libre d'utiliser les canaux BASH ou la redirection.

0
Shane