管道comand列的输出

科希尔·奥尼尔

我正在使用lolcat获得ls颜色的输出。为此,我已将/ usr / bin / ls复制到/ usr / bin / lsslss(以避免死循环,因为别名不能接受$ *或$ @),并且添加了以下功能:

ls(){ lsslss $* | lolcat; } 到.bashrc

问题是,当我使用ls时,管道一次通过管道传输每个文件,因此它显示为如下所示的长列表:

在此处输入图片说明

而不是像这样的表:

在此处输入图片说明

要将其更改为表,我可以将输出通过管道传递到columns命令。但是当我这样做时,它又变回了一个长长的列表(可能是因为列只格式化了它,而不是将它变成了行)

我本来打算做的:

ls(){ lsslss $* | columns | lolcat; }

无论如何,我想知道是否有一种方法可以通过管道传递原始输出,而不是使用| 能够将列的输出通过管道传输到lolcat?

提前致谢。抱歉,我的问题措辞不当或难以理解。我几乎总是找到已经问过的问题,所以我不会经常发布问题。

字节指挥官

扩展@dessert的答案,您需要做更多的工作才能使彩色ls版本ls在所有情况下都像真实情况一样(希望吗?)。问题在于,这ls不是要解析的,而仅是供人眼使用的。为此,它会根据环境(例如是连接到终端还是输出到管道)强烈适应其工作方式。

首先,您不需要单独的/bin/lsslss可执行文件来避免递归。使用内置的外壳command程序从磁盘调用可执行文件,而忽略任何外壳程序功能或同名别名。

其次,$*为您提供所有函数参数作为单个字符串,然后将其进行分词,因为它未加引号。如果您使用带空格的参数,这可能会出乎意料的错误结果。始终使用"$@",它会完全保留最初给出的所有参数,而不会串联或进一步拆分。

第三,根据定义的放置位置,ls () { ... ;}如果函数ls已经是别名,则定义函数的语法可能不起作用,因为别名会首先发生扩展,从而导致语法错误。通过在显式语法function之前编写来使用显式语法

然后,我们可以使用ls'-C标志来手动启用列输出:

function ls() { command ls -C "$@" | lolcat ;}

但是,如果我们只是这样做,然后将输出通过管道传输lolcat(或其他方式),您会注意到它不再使用终端的整个宽度,而最多仅使用80列。这是因为如果不再将其标准输出直接连接到端子上,则无法检测端子宽度。您的外壳程序仍然知道终端,并且COLUMNS将检测到的宽度填充到变量中。但是,由于默认情况下未导出此变量,因此ls不会看到该值。我们可以仅为此命令手动传递它,例如:

function ls() { COLUMNS="$COLUMNS" command ls -C "$@" | lolcat ;}

现在,我们应该总是获得正确的宽度,但是如果我们真的想ls通过其他管道传输,会发生什么呢?通常,您不应该那样做,因为正如我在开始时所说,ls永远都不应被解析。尽管有时它可能仍然有用(并且某些脚本可能不幸地依赖它),所以让我们至少尝试保留原始行为。现在,我们将始终将这些列作为eg的输出ls | cat(那里不再有颜色,因为lolcat还要检查它是否输出到端子或管道并在后一种情况下关闭颜色)

让我们在函数中添加一个检查,该函数使用纯实数(ls如果已通过管道传输),并且使用花哨的彩虹列版本(仅用于终端视图)。可以使用以下命令检查标准输出(文件描述符1)是否为终端/ TTY [[ -t 1 ]]

function ls() { 
    if [[ -t 1 ]] ; then COLUMNS="$COLUMNS" command ls -C "$@" | lolcat ; else command ls "$@" ; fi
}

我认为这应该足以应付所有ls预期会有特殊/不同行为的情况,以便您的函数仅在直接在终端中查看时才添加颜色,否则不会改变任何内容。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章