Как остановить gedit (и другие программы) для вывода предупреждений GTK и т.п. в моем терминале?

Я запускаю потрясающий оконный менеджер на верном после обновления с raring. В моей рабочей среде преднамеренно не запущены все демоны Gnome / Freedesktop - я не хочу их.

Когда я выполняю gedit из терминала следующим образом:

gedit file

Он выводит подобные сообщения по всему моему терминалу всякий раз, когда я нажимаю ввод или сохранение или в других других случаях:

(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 не единственный, кто любит портить терминал.

32
задан 7 September 2017 в 21:01

4 ответа

Во-первых, я также нахожу это раздражающим, который эти предупреждения разоблачают на out-of-the-box 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"
14
ответ дан 7 September 2017 в 21:01

Также обходное решение, но Вы не должны применять это для каждого приложения.

Запишите это в Ваш .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
ответ дан 7 September 2017 в 21:01

Я на самом деле записал эти инструмент скрывать-предупреждений в C, который я нахожу намного легче использовать, чем сценарий, показанный выше. Кроме того, это запишет весь вывод, записанный в stdout по умолчанию (потому что Gtk и другие предупреждения отправляются в stderr, таким образом, это анализирует stderr не stdout по умолчанию).

Одна большая проблема со сценарием выше состоит в том, что он ничего не запишет в Вашу консоль, даже если он не будет соответствовать regex, пока не сделано. Это вызвано тем, что это сохраняет все данные в переменной и затем grep та переменная, однажды сделанная. Это также означает, что это сохранит вывод в той переменной возможно с помощью большой памяти (по крайней мере, необходимо сохранить это во временном файле.) Наконец, от того, что я вижу, grep предотвратит любой дисплей, если какая-либо строка будет соответствовать. Возможно, не точно, что Вы хотите.

инструмент может использоваться в простом псевдониме как это:

alias gvim="hide-warnings gvim"

(я использую gvim... Я уверен, что это работало бы с gedit также.)

файл сам содержавший, никакие зависимости кроме библиотеки C, таким образом, можно получить копию и легко скомпилировать и установить ее:

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

существует некоторая дальнейшая документация в файле, и можно использовать --help когда-то скомпилированный для быстрых документов.

1
ответ дан 7 September 2017 в 21:01

Я надеялся находить, что утилита решает этот вид проблемы, сам.

Мои проблемы с предоставленными ответами следующие:

  • важно, чтобы stdout и stderr не становились агрегированными в один поток
  • Я не могу вызвать команду, отфильтровать весь вывод, пока он не завершается, и распечатайте его в конце (т.е. решение должно передать вывод потоком правильно),
  • Я хотел бы сохранить порядок stdout и сообщений stderr как можно больше

Я ценю попытки, которые я видел, чтобы сделать это с Bash, однако, мне не удалось определить решение, которое достигло всех 3 из условий, обрисованных в общих чертах выше.

Мое окончательное решение записано в NodeJS, который я понимаю, не будет установлен на многих полях Linux. Прежде, чем принять решение записать версию JS, я попытался кодировать его в Python и нашел, что асинхронная библиотека IO довольно ужасна и повреждается до ОЧЕНЬ последних версий Python (~3.5, который доступен из поля на НЕКОТОРЫХ более новых дистрибутивах).

Уменьшение зависимостей было ЕДИНСТВЕННОЙ причиной выбрать Python, таким образом, я отказался от него для 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
ответ дан 23 November 2019 в 00:40

Другие вопросы по тегам:

Похожие вопросы: