在 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
,所以如果喜欢使用键盘的话,按d
和u
就可以向下和向上滚动了(翻半页)。
实际上我有一个无极滚轮,用它翻日志真的很好用,只有 systemd 不这么想
重新看了 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
的话,退出之后啥都不剩,不是更不能翻页了吗?
Cat Ericka:
会滚动终端模拟器而不是 less 输出。
我用 tmux,所以滚动的是 tmux,会被解释为上下方向键。less 如果没有退出的话,内容会被滚动。less 如果已经退出的话,一般是看完了、用不着翻回去了。非要翻回去的话,进入 tmux 的 copy mode 再滚也行。
当然是退出前翻它。这里说的是 systemd
使用 -X
的动机。
我不是 tmux 用户,使用的是普通的终端模拟器(比如 Konsole)
终端里翻日志是个很常用的操作,我觉得它和用鼠标滚轮看浏览器 / PDF / 文本文件是有共通点的,那为什么后者就能用鼠标,前者就得忍受不停的按键盘?
当然,最主要的原因是用无极滚轮翻文档真的好用。
至于终端上使用鼠标,我还是很喜欢这一特性的。
Cat Ericka:
这里说的是 systemd
使用 -X
的动机。
这动机和滚动没什么关系啊。
所以我还是没弄明白:究竟 -X
和你用鼠标滚动有啥冲突么?你为什么不能用鼠标滚动你的 less --mouse -X
?
Cat Ericka:
至于终端上使用鼠标,我还是很喜欢这一特性的。
「终端上使用鼠标」和「终端里的程序使用鼠标」是不同的。正因为我要在「终端上使用鼠标」(比如来选择文本),所以我不希望「终端里的程序使用鼠标」。
CatEricka
(Cat Ericka)
2024 年2 月 5 日 16:13
10
systemd
用 -X
做它想做的事,副作用是 less
本来支持的鼠标滚轮滚动页面不能用,所以我要覆盖掉 systemd 的配置,把 systemd 传给 less
的 -X
删掉。
楼上的意思应该是,即使加了-X
选项,也可以再加个--mouse
选项,同样可以支持鼠标滚动。
可以使用LESS
环境变量添加这个选项,可以应用到所有环境,而不仅仅是systemd
。
CatEricka
(Cat Ericka)
2024 年2 月 6 日 01:00
13
你说的对,那我该怎么把 --mouse
告诉 systemd?
刚刚试了下 export LESS='--mouse'
,LESS
不生效,看来 systemd 有自己的想法。
CatEricka
(Cat Ericka)
2024 年2 月 6 日 01:07
14
依云:
应该不影响你滚动的啊。
我不知道,但是使用 -X
就会这样。这也许是什么转义序列魔法,也许是 less
的奇怪特性。但是我没什么兴趣去挖掘几十年前的 termcap 魔法。
我试了下,确实不生效。
然后我又看了man journalctl
中关于SYSTEMD_LESS
的说明,感觉你的做法是对的,没有问题。
CatEricka
(Cat Ericka)
2024 年2 月 6 日 01:37
16
好吧我还是去研究了。结论是,这是 less
和终端模拟器的 hack:
终端模拟器支持“备用屏幕”(苹果这么翻译的)这一特性,很多全屏交互程序会激活这一功能。然后许多终端模拟器决定在这个模式下把鼠标滚轮事件转换成方向键事件。
less
默认情况下根本不支持鼠标,但是默认情况下它会启用备用屏幕,因此 less
在启用备用屏幕时会收到鼠标滚轮事件转换成的(上/下)方向键事件。在这种组合下,鼠标滚轮能“正常”工作。
当启用开关 -X
时,less
不再发送激活(和关闭)备用屏幕的转义序列,这时候 less
得自己处理鼠标滚轮事件,当然,它不支持。因此鼠标滚轮事件被忽略,鼠标滚轮不再工作。
这是上古时期的故事。
然后到了现代,less
真的支持鼠标滚轮事件了,只要使用参数 --mouse
。所以我只要启用这个开关,一切都会好起来的。遗憾的是我完全不了解怎么样让 systemd 正确解析这个选项,所以只得从 systemd 的默认选项里删掉 X
了事。
CatEricka
(Cat Ericka)
2024 年2 月 6 日 02:11
17
为什么 systemd 不受欢迎我觉得已经完全理解了:
opened 03:51PM - 06 Oct 23 UTC
RFE 🎁
journal
documentation
### Component
journalctl
### Is your feature request related to a problem?… Please describe
In the `journalctl` man page:
- About `SYSTEMD_LESS`:
> Override the options passed to `less` (by default "FRSXMK").
- About `SYSTEMD_LESSCHARSET`:
> Override the charset passed to `less` (by default "utf-8", if the invoking terminal is determined to be UTF-8 compatible).
The man page should actually say that these environment variables `SYSTEMD_LESS` and `SYSTEMD_LESSCHARSET` (or their default) actually override the `LESS` and `LESSCHARSET` environment variables.
Otherwise one can be surprised by the behavior, because
- the way to override options with `less` is normally done via command-line options, as documented in the `less` man page: "so command line options override the `LESS` environment variable" (note that the user may configure his pager to call `less` with command-line options, and `journalctl` will not override these options by setting `LESS`);
- the `LESS` and `LESSCHARSET` environment variables are set by `journalctl` even if the pager is not `less`.
### Describe the solution you'd like
_No response_
### Describe alternatives you've considered
_No response_
### The systemd version you checked that didn't have the feature you are asking for
254.5
显然 systemd 手册根本没有说明 $SYSTEMD_LESS
不是由 systemd 解析的,而是覆盖了 $LESS
!
现在问题解决了,只要设置环境变量:
export SYSTEMD_LESS='FRSXMK --mouse'
即可。
一切都很完美。
编辑:
经过测试,FRSXMK --mouse
、FRSXMK mouse
、FRSXMKmouse
都能生效。所以 systemd 对这个变量有神秘的处理… 因为后两个配置给 $LESS
似乎对单独运行 less
不生效。
总之能用
编辑2:
/* In the child start the pager */
if (dup2(fd[0], STDIN_FILENO) < 0) {
log_error_errno(errno, "Failed to duplicate file descriptor to STDIN: %m");
_exit(EXIT_FAILURE);
}
safe_close_pair(fd);
if (setenv("LESS", less_opts, 1) < 0) {
log_error_errno(errno, "Failed to set environment variable LESS: %m");
_exit(EXIT_FAILURE);
}
/* Initialize a good charset for less. This is particularly important if we output UTF-8
* characters. */
less_charset = getenv("SYSTEMD_LESSCHARSET");
if (!less_charset && is_locale_utf8())
less_charset = "utf-8";
if (less_charset &&
我搞不懂。看上去并没有特殊处理,而是直接覆盖 $LESS
了。
systemd 的用户体验和 PulseAudio 一样,难兄难弟。