如何在系统范围内用 bat 替换 cat Ubuntu 22.04

如何在系统范围内用 bat 替换 cat Ubuntu 22.04

我正在使用带有 bash 的 Ubuntu 22.04,非常原始,并且已添加到alias cat="batcat"。可以在此处找到所引用的程序~/.bashrcbatcatbathttps://github.com/sharkdp/bat

因此,cat ~/.bashrc例如,当我运行 时,它会使用 输出文件的内容batcat。但是,当我运行诸如 之类的命令时crontab -l,输出似乎正在使用cat而不是batcat

任何帮助都将不胜感激!

由于 的输出,似乎crontab -l未使用。这是否意味着我无能为力?catstrace 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 上的别名,但batbc对我来说似乎是不错的别名。

在 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

为了实现这一点,您可以符号链接batcatbat某个地方。$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/catcat
  • 安装/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 | batcatcrontab -l | catcrontab -l | bat

相关内容