web-dev-qa-db-ja.com

端末でgedit(および他のプログラム)がGTK警告などを出力しないようにするにはどうすればよいですか?

Raringからアップグレードした後、trustyで素晴らしいウィンドウマネージャーを実行しています。私のデスクトップ環境では、意図的にすべてのGnome/Freedesktopデーモンが実行されているわけではありません。

次のような端末からgeditを実行すると:

gedit file

Enterキーを押すか、保存するか、その他のさまざまな機会に、このようなメッセージを端末全体に出力します。

(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

私はこの警告の意味を理解しており、それは私には関係ないと判断しました。

オフにするこの種の警告はどうすればよいですか? 「オフにする」ということは、これらの回避策や同様の回避策を意味するものではありません。

  • geditの出力を/dev/nullにパイプする
  • geditの出力を/dev/nullにパイプするラッパースクリプトを記述する
  • geditの出力を/dev/nullにパイプするエイリアスを作成する

これらの回避策は、各Gnomeアプリケーションに個別に適用する必要があるため、受け入れられません。端末を台無しにするのが好きなのはgeditだけではありません。

29
FUZxxl

最初に、これらの警告がすぐに使えるUbuntuに表示され、それらを無効にする「適切な」方法がないために見つけることができます(最も一般的な「解決策」はインストールすることです) gir1.2-gtksource-3.0は既にインストールされているため機能しない、またはそれらを無視するように見えますが、端末が騒がしいだけなので完全に抑制したいです)。

次のコードを思いついたのですが、これまでのところ期待どおりの動作をしているようで、TuKsnの答えに基づいていますが、少し拡張しています:

  • デフォルトで動作します(gedit ...)。F12やその他のショートカットを使用する必要はありません(フィルターなしの使用/usr/bin/gedit ...を呼び出すため)。
  • バックグラウンドタスクとして終了したときに入力されたコマンド名を表示します。

少し一般化できますが、今のところ、他のコマンドに同じ処理が必要な場合は、同じフィルターを必要とする他のコマンド名ごとにgedit()関数を複製します。

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

そして、より良いバージョン(より小さく、完全に汎用的で、そのまま呼び出されるので履歴を書き換える必要がなく、出力全体ではなく行ごとにフィルタリングする方が良い):

# 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

これも回避策ですが、すべてのアプリケーションに適用する必要はありません。

これを.bashrcに書き込むと、このラッパーをF12で使用して(または別のキーを選択して)警告を抑制することができます。

# 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

実際に hide-warningsツール をCで書いたので、上記のスクリプトよりもずっと使いやすいと思います。また、デフォルトでstdoutに書き込まれるすべての出力を書き込みます(Gtkおよびその他の警告がstderrに送信されるため、デフォルトではstderrではなくstdoutを解析します)。

上記のスクリプトの大きな問題の1つは、正規表現と一致しなくても、完了するまでコンソールに何も書き込まないことです。これは、すべてのデータを変数に保存し、一度その変数をgrepするためです。また、おそらく大量のメモリを使用して、その変数に出力を保存することを意味します(少なくとも一時ファイルに保存する必要があります)。 。たぶんあなたが望むものではないかもしれません。

このツールは、次のような簡単なエイリアスで使用できます。

alias gvim="hide-warnings gvim"

gvimを使用します... geditでも機能すると確信しています。)

ファイルは自己完結型であり、Cライブラリ以外の依存関係がないため、コピーを取得して簡単にコンパイルおよびインストールできます。

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

このファイルにはさらにドキュメントがあり、クイックドキュメント用にコンパイルされたら--helpを使用できます。

1
Alexis Wilke

私は自分でこの種の問題を解決するユーティリティを探していました。

提供された回答に関する私の問題は次のとおりです。

  • stdoutとstderrが1つのストリームに集約されないことが重要です
  • コマンドを呼び出し、終了するまですべての出力をフィルター処理し、最後に出力することはできません(つまり、ソリューションは出力を適切にストリーミングする必要があります)
  • Stdoutおよびstderrメッセージの順序を可能な限り保持したい

Bashを使用してこれを実行しようとする試みを感謝していますが、上記の3つの条件すべてを達成した解決策を特定できませんでした。

私の究極のソリューションはNodeJSで書かれており、多くのLinuxボックスにはインストールされないことを理解しています。 JSバージョンの作成を選択する前に、Pythonでコーディングしようとしましたが、非同期のIOライブラリは非常にく、pythonの非常に最近のバージョン(〜3.5いくつかの新しいディストリビューションですぐに利用できます)。

依存関係を最小限に抑えることがPythonを選択する唯一の理由だったので、NodeJSにはそれを放棄しました。NodeJSには、やや低レベルの非同期指向のIO用の顕著なライブラリセットがあります。

ここにあります:

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

このスクリプトを使用するには、次の行を.bashrcに追加します。

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

実行することを選択したサブプロセスはstdinを継承するため、BASHパイプまたはリダイレクトを自由に使用できます。

0
Shane