我正在使用带有 bash 的 Ubuntu 22.04,非常原始,并且已添加到alias cat="batcat"
。可以在此处找到所引用的程序~/.bashrc
:batcat
bat
https://github.com/sharkdp/bat
因此,cat ~/.bashrc
例如,当我运行 时,它会使用 输出文件的内容batcat
。但是,当我运行诸如 之类的命令时crontab -l
,输出似乎正在使用cat
而不是batcat
。
任何帮助都将不胜感激!
由于 的输出,似乎crontab -l
未使用。这是否意味着我无能为力?cat
strace crontab -l |& grep cat
仍然可以使用crontab -l | batcat
或 来获取输出并将其输入到 crontab 中crontab -l | cat
。
答案1
如何在系统范围内用 bat 替换 cat Ubuntu 22.04
我强烈反对这样做。
Cat 不仅可用于 shell 上的交互;它还可用于系统脚本,如cat <file> | filter | ...
、 或DATA="$(cat <file>)"
。如果 Bat 不工作确切地同样在这些情况下,您的系统最终可能会以意想不到的方式发生故障,并且您甚至可能不会想到将这些故障与您的 Cat 替代品联系起来。
(我发现的一个例子是bat /dev/zero | head -c1
耗尽所有系统内存然后崩溃,而cat
工作正常;见问题 #636)
我正在使用带有 bash 的 Ubuntu 22.04,非常原始,并且已将别名 cat="batcat" 添加到 ~/.bashrc。
这危害较小;它只会影响您对 shell 的交互使用;而不会影响脚本,也不会影响其他(系统)用户。
不过,我还是建议不要这么做。同样,如果 Bat 表现不好,确切地作为 Cat,它可能会在某种程度上破坏你的 shell,例如如果你cat
从某处复制/粘贴使用的命令行。
例如,请参阅蝙蝠问题 #2380,有人抱怨zsh-async
做完后就坏了alias cat=bat
。
但是,当我运行诸如这样的命令时
crontab -l
,输出似乎使用的是 cat 而不是 batcat。
某些东西产生输出并不意味着它使用了 Cat。它
crontab -l
只是打印其输出。它不通过 Cat 或系统分页器(见下文)提供。您必须| batcat
手动使用。
(话虽如此,我系统上的 Bat 版本crontab -l | batcat
并没有对任何东西进行着色,所以我不确定这里是否有很大价值)
所以呢能你做?
首先,当您想要彩色输出时,您可以简单地使用batcat <file>
或<command> | batcat
。这使得用法更加明确,因此它不会弄乱任何不该弄乱的东西。
您可以使用 自由定义另一个别名alias XXX="batcat"
,这样您就可以在交互式 shell 会话中使用它而减少输入。我不建议使用 Cat 上的别名,但bat
或bc
对我来说似乎是不错的别名。
在 Zsh 等 shell 中,你可以考虑全局别名以节省更多输入并将命令简化为类似 的内容crontab -l B
。但要小心,全局别名本身就是麻烦。
另一个想法是创建一个别名,重新运行上一个命令,并通过 Bat 传输其输出;例如:alias rebat='$(history -p !!) | batcat'
。
然后,如果您运行crontab -l
并决定宁愿通过 Bat 传输其输出,您只需键入rebat
,它就会crontab -l | batcat
为您运行。
传呼机
Unix 有一个概念寻呼机;可以一次显示一页文本并允许您浏览文本的程序。最普遍的分页程序可能是 Less。一些程序(man、git、systemctl 等)会自动通过分页程序发送其输出。
export PAGER=bat
您可以使用(例如在您的)将 Bat 设置为默认寻呼机.bashrc
,这将使这些程序默认使用 Bat。
请注意,分页程序必须称为bat
,而不是batcat
。Bat 仅对输出进行着色,不提供分页。如果 Bat 发现其输出对于终端来说太长,它会自动将其输出通过 提供$PAGER
。
但是,由于$PAGER=bat
,它将启动一个新的 Bat,并将其输出送入那里。新的 Bat 发现输出太长,因此它将启动一个寻呼机,这是另一个 Bat。这将无限重复(参见2023 年)。
为了防止这种情况,Bat 会检测分页器是否设置为 Bat,并悄悄地使用 Less 进行分页。但这仅有的如果寻呼机设置为bat
,则可工作,而不是batcat
。
为了实现这一点,您可以符号链接batcat
到bat
某个地方。$HOME/bin
这是我的偏好,但您需要设置您的 shell 才能使用它。/usr/local/bin
将是一个系统范围的选项。
答案2
这里发生了两件事:
crontab -e
具有自动分页的输出。cat
用替换系统batcat
。
crontab -l
分页
从man crontab
:
The -l option causes the current crontab to be displayed on standard output.
因此crontab -l
总是会转到标准输出。我看不到为该命令配置分页器的选项。
可以编写自己的包装crontab
函数来检测-l
并自动附加寻呼机,但这可能得不偿失。最好在配置以下替代方案后根据需要手动管道到cat
(或bat
,或)。batcat
更换系统cat
再次,这不会解决您的crontab -l
愿望(因为crontab
首先不使用寻呼机),但您当然可以替换(或添加)cat
替代方案,尽管我同意@马塞尔姆这不是最好的主意。
Ubuntu 包含 Debian Alternatives 系统,其中包括update-alternatives
命令非常适合以“标准”方式创建必要的符号链接。
sudo update-alternatives --install /usr/local/bin/cat cat /usr/bin/batcat 20
sudo update-alternatives --install /usr/local/bin/cat cat /usr/bin/cat 10
这做了几件事:
- 为新的替代方案设置
/usr/local/bin/cat
符号链接。/etc/alternatives/cat
cat
- 安装
/usr/bin/batcat
和/usr/bin/cat
作为潜在cat
替代方案,其中/usr/bin/batcat
优先级较高。 /usr/local/bin/cat
将始终被符号链接到/etc/alternatives/cat
(除非替代方案被删除)。- 由于优先级,
/etc/alternatives/cat
将符号链接到当前选定的替代方案,即/usr/bin/batcat
。
如果您需要暂时恢复替代方案,您可以轻松地这样做:
sudo update-alternatives --config cat
您将可以选择任何可用的cat
替代方案。
当然,好的想要确保使用“真实”cat
以实现兼容性的应用程序或脚本实际上会/usr/bin/cat
显式调用。在这种情况下,替代方案不会覆盖实际的二进制文件,也不应该覆盖。
附注:
我建议继续为其bat
自身创建符号链接,以便“重命名”它batcat
:
sudo update-alternatives --install /usr/local/bin/bat bat /usr/bin/batcat 20
我对 做了同样的事情fdfind
(与 是同一作者bat
):
sudo update-alternatives --install /usr/local/bin/fd fd /usr/bin/fdfind 20
答案3
您可以cat
通过放置指向替代命令的符号链接来覆盖外部命令,即放置在搜索可执行文件batcat
时较早出现的目录中。这可能是因为更改仅影响您的用户,也可能因为更改影响所有用户。PATH
~/.local/bin
/usr/local/bin
假设cat
和都batcat
安装在/usr/bin
,以下命令将创建一个cat
指向的符号链接batcat
:
ln -s /usr/bin/batcat ~/.local/bin/cat
或者进行系统范围的部署:
sudo ln -s /usr/bin/batcat /usr/local/bin/cat
为了在所有情况下都能正常工作,的命令行语法batcat
应支持这些cat
。这里的情况可能就是这样,因为该工具可能被设计为替代品。
答案4
仍然可以使用或或获取输出crontab -l
并将其输入到 bat/batcat 中crontab -l | batcat
crontab -l | cat
crontab -l | bat