当输出符合预期时,为什么 `bash` 不适用于管道输出?

当输出符合预期时,为什么 `bash` 不适用于管道输出?

我正在运行以下命令来为整个脚本文件夹添加别名:

ls | grep '\.sh$' | sed 's/\.sh$//' | awk '{print "alias "$1"=\"./"$0".sh\""}' | xargs -L1 bash

似乎有问题,bash或者可能xargs处理了这个问题。别名不起作用。

当使用运行命令时echo,我得到了预期的输出(或几乎,不确定为什么缺少双引号)

ls | grep '\.sh$' | sed 's/\.sh$//' | awk '{print "alias "$1"=\"./"$0".sh\""}' | xargs -L1 echo

输出:

alias test_script1=./test_script1.sh
alias test_script2=./test_script2.sh

单独运行这些命令时,它们会按预期工作。

抱歉,我可能还是个 Bash 菜鸟。我试图通过一个命令来解决这个问题,我可以把这个命令放在我的目录中.zshrc并引用一个脚本目录。

答案1

xargs -L1 bash例如运行bash alias test_script=/test_script.sh。 Bash 将尝试运行命令alias,但这不是您想要的 - 您需要一个 shell 内置命令。为此,您需要bash -c

如果您运行xargs -L1 bash -c,它会为每个别名运行不同的实例bash。实例立即结束,其中定义的别名不会影响当前 shell 中定义的别名。

要在当前 shell 中运行别名,请改用eval

eval "$(ls
        | grep '\.sh$'
        | sed 's/\.sh$//'
        | awk '{print "alias "$1"=\"./"$0".sh\""}' 
        | xargs  -L1)"

请注意,别名仅在当前目录中有效,一旦您移至cd其他位置,它们很可能会失效。使用完整路径代替来./script修复它。

一种更安全、更标准的方法是重命名文件,删除.sh(或者如果需要原始名称,则创建链接),然后将目录添加到环境变量中$PATH

答案2

你可以通过以下方式获得你想要的效果

  • 将文件重命名为不带.sh. — 这将删除.sh
  • 将目录添加到PATH。—这将删除./并允许从任何目录使用。

如果出于某种原因您无法.sh从文件名中删除。那么请创建指向没有它的原始文件的同步链接。


文件扩展名违背了 Unix 哲学:想象一下用另一种语言重写这些程序。您必须告诉程序的所有客户端更改其运行程序时使用的名称。

答案3

为了达到预期效果,您可以通过删除 .sh 扩展名来重命名文件,然后将目录添加到 PATH。如果出于特定原因无法从文件名中删除 .sh,则可以创建指向原始文件的符号链接,但不带 .sh 扩展名。

相关内容