让 journalctl 查看日志时支持鼠标滚轮

在 shell 初始化文件里加一行

alias journalctl='SYSTEMD_LESS=FRSMK journalctl'

这样做可以保证 journalctl 的命令补全正常工作。感谢神秘莫测的 bash 特性。


编辑2:

正确处理方法参见本贴“解决方案

编辑:

systemd 使用 less 的开关 -X 实现 less 输出时不会清除屏幕的效果。不使用 export SYSTEMD_LESS=FRSMK 是为了再其它 systemd cli 上保持这一特性。

具体相关讨论如下:

https://bugzilla.redhat.com/show_bug.cgi?id=1655316

The reason why ‘X’ is passed is that we want stuff like ‘journalctl -n5’ to print stuff to the console
just like ‘tail -n5’ would. If ‘X’ is removed from the options, less output is only visible when
less is running, and gone afterwards. We could try to be smart and add ‘X’ only in certain circumstances,
e.g. when ‘-n’ is given and such, but this would be quite confusing, because the pager behaviour
would be substantially different based on some (seemingly unrelated) options. So sorry,
this isn’t really a bug, but a limitation of less, or maybe even the terminal. Thinking about this
some more, it seems likely that it simply isn’t possible to do “output to the console but scroll with
the mouse”. Users may override this if they wish (as described in the comments above), but the current
default should stay.

man: describe $LESS options more fully by keszybz · Pull Request #13126 · systemd/systemd · GitHub

journalctl默认使用less作为pager,所以如果喜欢使用键盘的话,按du就可以向下和向上滚动了(翻半页)。

实际上我有一个无极滚轮,用它翻日志真的很好用,只有 systemd 不这么想 :confused:

其实我不明白你们遇到了什么问题(

重新看了 less 手册和相关评论,systemd 的所有 cli 工具使用 less 作为 pager,但是它传递了开关 -X,目的是让 less 输出时不会清除屏幕,这样退出 less 时会把日志内容显示在终端上,副作用是鼠标滚轮不再生效。(我觉得这是滥用特性的典型例子)

-X or --no-init
    Disables sending the termcap initialization and deini‐
    tialization  strings  to  the terminal.  This is some‐
    times desirable if the  deinitialization  string  does
    something unnecessary, like clearing the screen.

因此,在终端模拟器上使用 journalctl 查看日志时,如果下意识使用鼠标滚轮(因为 less 默认支持该功能,即 less 的 --mouse 开关),会滚动终端模拟器而不是 less 输出。

通过修改环境变量 SYSTEMD_LESS,可以覆盖 systemd 的默认设置,这样就可以去掉开关 X 重新让鼠标滚轮生效了。该环境变量在 systemd 的各种 cli 工具手册页中提到。

我挺喜欢用 -X 选项的。

原来 less 还支持鼠标啊。我不太喜欢在终端程序里开启鼠标支持,通常所失大于所得,比如 tmux 和 less 就是如此。

那你退出之后为什么还要翻它呢?你不使用 -X 的话,退出之后啥都不剩,不是更不能翻页了吗?

我用 tmux,所以滚动的是 tmux,会被解释为上下方向键。less 如果没有退出的话,内容会被滚动。less 如果已经退出的话,一般是看完了、用不着翻回去了。非要翻回去的话,进入 tmux 的 copy mode 再滚也行。

当然是退出前翻它。这里说的是 systemd 使用 -X 的动机。

我不是 tmux 用户,使用的是普通的终端模拟器(比如 Konsole)

终端里翻日志是个很常用的操作,我觉得它和用鼠标滚轮看浏览器 / PDF / 文本文件是有共通点的,那为什么后者就能用鼠标,前者就得忍受不停的按键盘?

当然,最主要的原因是用无极滚轮翻文档真的好用。

至于终端上使用鼠标,我还是很喜欢这一特性的。

这动机和滚动没什么关系啊。

所以我还是没弄明白:究竟 -X 和你用鼠标滚动有啥冲突么?你为什么不能用鼠标滚动你的 less --mouse -X

「终端上使用鼠标」和「终端里的程序使用鼠标」是不同的。正因为我要在「终端上使用鼠标」(比如来选择文本),所以我不希望「终端里的程序使用鼠标」。

systemd-X 做它想做的事,副作用是 less 本来支持的鼠标滚轮滚动页面不能用,所以我要覆盖掉 systemd 的配置,把 systemd 传给 less-X 删掉。

应该不影响你滚动的啊。

楼上的意思应该是,即使加了-X选项,也可以再加个--mouse选项,同样可以支持鼠标滚动。
可以使用LESS环境变量添加这个选项,可以应用到所有环境,而不仅仅是systemd

你说的对,那我该怎么把 --mouse 告诉 systemd? :thinking:

刚刚试了下 export LESS='--mouse'LESS 不生效,看来 systemd 有自己的想法。

我不知道,但是使用 -X 就会这样。这也许是什么转义序列魔法,也许是 less 的奇怪特性。但是我没什么兴趣去挖掘几十年前的 termcap 魔法。

我试了下,确实不生效。
然后我又看了man journalctl中关于SYSTEMD_LESS的说明,感觉你的做法是对的,没有问题。

好吧我还是去研究了。结论是,这是 less 和终端模拟器的 hack:

终端模拟器支持“备用屏幕”(苹果这么翻译的)这一特性,很多全屏交互程序会激活这一功能。然后许多终端模拟器决定在这个模式下把鼠标滚轮事件转换成方向键事件。

less 默认情况下根本不支持鼠标,但是默认情况下它会启用备用屏幕,因此 less 在启用备用屏幕时会收到鼠标滚轮事件转换成的(上/下)方向键事件。在这种组合下,鼠标滚轮能“正常”工作。

当启用开关 -X 时,less 不再发送激活(和关闭)备用屏幕的转义序列,这时候 less 得自己处理鼠标滚轮事件,当然,它不支持。因此鼠标滚轮事件被忽略,鼠标滚轮不再工作。

这是上古时期的故事。

然后到了现代,less 真的支持鼠标滚轮事件了,只要使用参数 --mouse。所以我只要启用这个开关,一切都会好起来的。遗憾的是我完全不了解怎么样让 systemd 正确解析这个选项,所以只得从 systemd 的默认选项里删掉 X 了事。

为什么 systemd 不受欢迎我觉得已经完全理解了:

显然 systemd 手册根本没有说明 $SYSTEMD_LESS 不是由 systemd 解析的,而是覆盖了 $LESS

现在问题解决了,只要设置环境变量:

export SYSTEMD_LESS='FRSXMK --mouse'

即可。

一切都很完美。

编辑:

经过测试,FRSXMK --mouseFRSXMK mouseFRSXMKmouse 都能生效。所以 systemd 对这个变量有神秘的处理… 因为后两个配置给 $LESS 似乎对单独运行 less 不生效。

总之能用

编辑2:

我搞不懂。看上去并没有特殊处理,而是直接覆盖 $LESS 了。


systemd 的用户体验和 PulseAudio 一样,难兄难弟。