Я запускаю потрясающий оконный менеджер на верном после обновления с 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
Я понимаю значение этого предупреждения и решил, что оно не имеет значения для меня.
Как мне отключить такого рода предупреждения? Под «выключением» я не подразумеваю ни один из этих или подобных обходных путей:
/dev/null
/dev/null
/dev/null
Эти обходные пути неприемлемы, так как они должны применяться индивидуально для каждого приложения Gnome - Gedit не единственный, кто любит портить терминал.
Во-первых, я также нахожу это раздражающим, который эти предупреждения разоблачают на 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"
Также обходное решение, но Вы не должны применять это для каждого приложения.
Запишите это в Ваш .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"'
Я на самом деле записал эти инструмент скрывать-предупреждений в 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
когда-то скомпилированный для быстрых документов.
Я надеялся находить, что утилита решает этот вид проблемы, сам.
Мои проблемы с предоставленными ответами следующие:
Я ценю попытки, которые я видел, чтобы сделать это с 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 или перенаправление.