我从 raring 升级到 trusty 后,开始使用 awesome 窗口管理器。我的桌面环境故意不运行所有 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 并不是唯一一个喜欢弄乱终端的应用程序。
答案1
首先,我发现这些警告出现在开箱即用的 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"
答案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"'
答案3
我实际上写了隐藏警告工具我发现用 C 编写的脚本比上面显示的脚本更容易使用。此外,默认情况下,它会写入所有输出stdout
(因为 Gtk 和其他警告被发送到,因此默认情况下stderr
它stderr
不会解析)。stdout
上述脚本的一个大问题是,即使它与正则表达式不匹配,在完成之前它也不会将任何内容写入控制台。这是因为它将所有数据保存在一个变量中,然后在完成后 grep 该变量。这也意味着它将把输出保存在该变量中,可能会使用大量内存(至少您应该将其保存在临时文件中)。最后,据我所知,如果有一行匹配,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++ 编写的。
答案4
一个解决方案是创建一个函数来抑制 Gtk 错误消息。
有时,错误来自何处并不明显。
例如,如果你的 .gitconfig 中有以下内容,它告诉 git 使用融合就像 git difftool 一样:
[diff]
tool = meld
[difftool]
prompt = false
[difftool "meld"]
cmd = meld "$LOCAL" "$REMOTE"
然后你尝试比较你的.bashrc文件:
$ git difftool .bashrc
您可能会收到很多烦人的 Gtk 错误消息:
2021-04-12 18:01:59,905 CRITICAL Gtk: gtk_widget_get_scale_factor: assertion 'GTK_IS_WIDGET (widget)' failed
2021-04-12 18:01:59,905 CRITICAL Gtk: gtk_widget_get_scale_factor: assertion 'GTK_IS_WIDGET (widget)' failed
2021-04-12 18:01:59,905 CRITICAL Gtk: gtk_widget_get_scale_factor: assertion 'GTK_IS_WIDGET (widget)' failed
2021-04-12 18:01:59,905 CRITICAL Gtk: gtk_widget_get_scale_factor: assertion 'GTK_IS_WIDGET (widget)' failed
2021-04-12 18:01:59,905 CRITICAL Gtk: gtk_widget_get_scale_factor: assertion 'GTK_IS_WIDGET (widget)' failed
. . .
创建一个函数,将输出和 stderr 重定向到 /dev/null
$ function git-difftool(){ git difftool ${@} & &>/dev/null; }
现在,当您运行时git-difftool .bashrc
,您将不再看到任何 Gtk 错误消息。
一个附带的好处是,通过在定义中添加 & 控制运算符git-difftool功能,您可以在后台运行此命令,这将释放您的终端,st,您可以与 meld difftool 窗口一起运行其他命令。