在 Linux 下,最常见的 pager(翻页器)就是 less 了,所以很多时候,我都忘记了还有$PAGER
这个环境变量,直到有一天我写了这么个 shell 函数:
repodo () { for f in $(cat ~/workspace/.my-repos); do echo "\n>>> $f\n" cd ~/workspace/$f && stdoutisatty $@ cd - > /dev/null done | less }
这个函数对于~/workspace/.my-repos
中记录的每一个项目,在对应的目录下执行同一条命令,并使用 less 来查看输出。其中,stdoutisatty 是一个把标准输出伪装成 tty 的脚本,这样一些命令就不会因为实际输出到管道而关掉彩色高亮之类的了。
比如
repodo git st
st
是status
的 git 别名。
这一句命令就可以查看所有项目的工作区状态了。
后来,我执行这样一条命令,它就出问题了:
repodo git grep string
因为 stdoutisatty 的缘故,git grep 会自动调用翻页器。于是,出现了两个 less 同时要读终端输入。
首先想到的是 git 的--no-pager
参数,但这个很显然对其它命令无效。于是才想起自设置之后一直没再搭理的$PAGER
环境变量:
repodo () { for f in $(cat ~/workspace/.my-repos); do echo "\n>>> $f\n" cd ~/workspace/$f && PAGER=cat stdoutisatty $@ cd - > /dev/null done | less }
把PAGER
指定为cat
直接输出,这样就不会有多个 less 在运行了。
但这样还没有结束,因为我的不少脚本里都是直接调用 less 的,现在得改成这样子了:
command | ${PAGER:-less}
或者在 Python 里:
p = subprocess.Popen([os.environ.get('PAGER', 'less')], stdin=subprocess.PIPE, universal_newlines=True)
附:less 默认是会转义来自输入的彩色转义字符序列的。我使用了-FRXM
参数,也是通过环境变量传递的:
export LESS=-FRXM
这四个选项的意义是:
-
-F
- 如果一屏能显示下,那么显示完就退出
-
-R
- 不要转义 ANSI 彩色转义字符序列
-
-X
-
不要发布终端初始化和结束字符串。这样才不会使用终端的备用屏幕,less 的输出才会留在主屏幕上(使用
-F
选项时必须,不然可能看不到东西) -
-M
- 在 less 提示符(最后一行)显示更多信息(比如文件的百分比位置)