![为什么“less”接受空文件名,并显示一些环境变量?](https://linux22.com/image/1071714/%E4%B8%BA%E4%BB%80%E4%B9%88%E2%80%9Cless%E2%80%9D%E6%8E%A5%E5%8F%97%E7%A9%BA%E6%96%87%E4%BB%B6%E5%90%8D%EF%BC%8C%E5%B9%B6%E6%98%BE%E7%A4%BA%E4%B8%80%E4%BA%9B%E7%8E%AF%E5%A2%83%E5%8F%98%E9%87%8F%EF%BC%9F.png)
我意外地less
使用了一个空文件名运行,我以为它会失败,但令我惊讶的是,它打印了一些环境变量:
$ less -XE ""
export LESSOPEN="| /usr/bin/lesspipe %s";
export LESSCLOSE="/usr/bin/lesspipe %s %s";
(-XE
基本上使其表现得像cat
。)
cat
另一方面,失败了:
$ cat ""
cat: '': No such file or directory
如果你完全省略文件名,less
则会出现错误:
$ less -XE
Missing filename ("less --help" for help)
为什么less
要这样做?我只能想象这是有问题的,因为如果你的代码中有一些错误导致文件名为空,你就会得到虚假的输出。(比如说。less "$(which nonexistent-script)"
)
当我们在这里时,为什么它会打印这些环境变量?它们来自我的环境吗?它们是相同的:
$ declare -p LESSOPEN LESSCLOSE
declare -x LESSOPEN="| /usr/bin/lesspipe %s"
declare -x LESSCLOSE="/usr/bin/lesspipe %s %s"
我检查过了man less
,但是文件名参数似乎没有明确记录。其他提及它似乎与此行为无关。我还检查了less
常问问题。
答案1
根本问题是less
没有正确引用传递给命令的文件名LESSOPEN
:它所做的是“在每个元字符前插入一个反斜杠”,这意味着它根本不处理空字符串。如果你绕过,你会看到它按预期工作LESSOPEN
:
$ less --no-lessopen ''
: No such file or directory
在 Ubuntu 上(我相信还有 Debian),默认情况下,LESSOPEN
通过运行lesspipe
无参数,它会打印必要的环境变量以将自身设置为LESSOPEN
处理程序。请参阅你能解释一下默认 .bashrc 中的 eval 表达式吗。因此,当less
使用空参数运行时,不正确的引用会删除传递给的参数lesspipe
,并lesspipe
打印其配置。
附言
我考虑过针对 开一个 bug less
,但这对我来说不是什么大问题。如果有人想主动出击,请务必告诉我,如果您需要什么。一个可能的解决方案(但不向后兼容)是less
根本不会尝试引用文件名,而是需要在配置中引用文件名,例如LESSOPEN='| /usr/bin/lesspipe "%s"'
。
打开一个错误来lesspipe
推荐更详细的配置使用可能也是一个好主意。