我创建了一个别名,以免每次进入新目录时都写ls:
alias cl='cd_(){ cd "$@" && ls; }; cd_'
假设我有一个名为“ Downloads”的文件夹(我当然有),所以我只需在终端中键入以下内容:
cl Downloads
现在,我将在“下载”文件夹中找到自己,并接收该文件夹中包含的内容的列表,例如:example.txt,hack.hs,picture.jpg,...
如果我想移至目录并查看是否存在hack.hs,可以尝试执行以下操作:
cl Downloads | grep hack
我得到的只是输出:
黑客
但是我将保留在原来的文件夹中(这意味着我不在“下载”中)。
我知道发生这种情况是因为每个命令都在子shell中执行,因此cd Downloads && ls在其自身的子shell中执行,然后输出(即我拥有的东西的列表)通过管道重定向到grep。这就是为什么我不在新文件夹中的原因。
我的问题如下:
为了能够编写“ cl Downloads | grep hack”之类的东西并获得“ hack”式的东西清单并位于Downloads文件夹中,我该怎么做?
谢谢你,波尔
对于曾经使用此工具的任何人:@gniourf_gniourf提出了一个快速解决方案:
cl Downloads > >(grep hack)
有人将此问题标记为Make bash别名可能与重复项重复,但我的bash别名已接受参数的事实表明事实并非如此。当前的问题是关于如何在当前shell中执行命令,同时将输出重定向到另一个命令。
如您所知(以及BashFAQ#24中所述),原因是
{ cd "$@" && ls; } | grep ...
...防止在cd
外壳中可见的结果是POSIX不能保证在外壳中运行管道的任何组件。(某些外壳程序,包括ksh [开箱即用]和启用了非默认选项的非常现代的bash,有时会或可选地运行父外壳程序中的管道的最后一部分,但这无法移植在)。
适用于所有POSIX shell的一种避免这种情况的方法是将输出定向到命名管道,从而避免建立管道:
mkfifo mypipe
grep ... <mypipe &
{ cd "$@" && ls; } >mypipe
在现代的ksh和bash中,有一种较短的语法可以为您完成此操作-/dev/fd
如果操作系统提供该功能,则使用条目而不是设置命名管道:
{ cd "$@" && ls; } > >(grep ...)
在这种情况下,>(grep ...)
将其替换为指向FIFO或/dev/fd
条目的文件名,当该文件写入相关进程时,该文件名将输出重定向到grep
-但没有管道。
顺便说一句-我确实希望您ls
以此方式作为示例。ls
对于所有可能的文件名的范围,输出的规范都不够明确,因此grepping本质上是不可靠的。printf '%s\0' *
如果您确实想生成流式结果,请考虑使用发出NUL分隔的目录中非隐藏名称的列表。或使用glob表达式检查匹配特定模式的文件(BashFAQ#4涵盖了类似情况);如果您需要比POSIX模式支持更全面的regex匹配支持,则可以使用extglobs。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句