Як не допустити, щоб gedit (та інші програми) виводили попередження GTK та подібне в мій термінал?


32

Я запускаю дивовижного менеджера вікон на надійному рівні після модернізації з рейтингу. У моєму робочому середовищі навмисно не працюють усі демони 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 не єдиний, хто любить псувати термінал.


2
Чому ви не можете використовувати 3 згадані вами варіанти?
Тім

Я не думаю, що ви можете вимкнути ці попередження, але, як @Tim запитав, що ви маєте проти використання трьох варіантів, які вирішили б вашу проблему?
ElefantPhace

7
Дякую, я знаю, як зробити перенаправлення оболонки. Причина, чому я не хочу цього робити (і прямо заявляю, що), полягає в тому, що ці попередження також з’являються у багатьох інших програмах. Параметр конфігурації для dbus або будь-якого компонента, який генерує ці попередження, вимкне попередження для всіх програм, які його генерують. Під час перенаправлення я повинен застосувати вирішення (що не є рішенням) до кожної програми окремо.
FUZxxl

@FUZxxl Я не можу заставити gedit послідовно виводити помилки. Але мені цікаво, чи export GCONF_DEBUG="no"зробили б щось
Dan

@ dan08 Ні, не роби трюку.
FUZxxl

Відповіді:


17

По-перше, мені також дратує те, що ці попередження з’являються у нестандартному 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"

Це чудова відповідь. Я буду використовувати це в майбутньому.
FUZxxl

2

Це також вирішення, але не потрібно застосовувати це для кожної програми.

Напишіть це своєму, .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"'

Це виглядає трохи краще. Я збираюся це перевірити.
FUZxxl

1

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

Одна з великих проблем із вищевказаним сценарієм полягає в тому, що він нічого не запише на вашу консоль, навіть якщо це не відповідає регулярному вираженню, поки не буде зроблено. Це відбувається тому, що він зберігає всі дані у змінній, а потім знімає цю змінну після завершення. Це також означає, що він збереже висновок у цій змінній, можливо, використовуючи багато пам'яті (принаймні, ви повинні зберегти це у тимчасовому файлі.) Нарешті, з того, що я бачу, grep запобіжить будь-який показ, якщо будь-який один рядок збігається . Можливо, не зовсім те, що ви хочете.

Інструмент можна використовувати в простому псевдонімі, як це:

alias gvim="hide-warnings gvim"

(Я використовую gvim... Я впевнений, що це теж спрацює gedit.)

Файл є автономним, немає ніяких залежностей, крім бібліотеки C, тому ви можете отримати копію та легко скомпілювати та встановити її:

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

У цьому файлі є додаткова документація, яку ви можете використовувати, --helpяк тільки складені для швидких документів.

Новіша версія , яка в якийсь момент скористається бібліотекою advgetopt, знаходиться в C ++.


Посилання мертва.
Армін Ріго

@ArminRigo, Ах! Це рушило. Тут я поклав нове посилання на останнє, перш ніж воно перейшло, тому що зараз це C ++. Також є посилання на версію C ++. Версія C більше не зміниться.
Алексіс Вілке

0

Я шукав собі утиліту для вирішення подібної проблеми.

Мої питання з наданими відповідями такі:

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

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

Моє остаточне рішення написано в NodeJS, який, наскільки я розумію, не буде встановлений на багатьох скриньках Linux. Перш ніж вибрати версію JS, я спробував її зашифрувати у python, і виявив, що бібліотека асинхронних вводу-інтерфейсу є досить некрасивою та зламаною, поки ДУЖЕ останніх версій 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-труби або перенаправлення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.