为什么“source

为什么“source

我想要一个使用参数调用的脚本,该脚本会为我当前的 shell 添加一些别名。必须根据调用参数和我启动它的当前目录来构建别名。如果可能的话,我希望不必获取脚本的源代码,只需像运行其他脚本一样运行它即可。

这是我到目前为止所做的:

我编写了一个小脚本来生成一些别名,例如

echo 'alias foo="$1"'

并将其保存为文件“myscript”,并赋予 +x 权限。然后我通过控制台执行它来设置别名

$(myscipt hello)

很好

当我更改我的shell脚本时

echo 'alias foo="bar $1 -param"'

并像上面一样再次执行,结果是

bash: alias hello" not found
bash: alias -param" not found

???。我已经转义了 bar 和 -param 之间的空格,但仍然无法让它工作。

当我执行时

source <(myscript hello)

一切都像预期的那样顺利(这是我现在的解决方案,但不确定它是否是最好的)。

关于如何获得更好的解决方案的一些想法?

答案1

你使用的source命令是错误的。我假设你有一个文件,myscript其中包含这些命令。而不是有东西要产生文件中的正确命令,如下所示

echo 'alias foo="bar -param"'

你应该只需要这样的命令

alias foo="bar -param"

然后将脚本直接传递给source命令,该命令在当前 shell 中运行它,以便脚本中所做的更改反映在当前 shell 会话中:

source myscript

此外,该.命令等效于:

. myscript

.(请注意,和之间有一个空格myscript。)


更新

回应您的评论:您仍然应该只使用文件。由于可以使用变量值设置别名的名称,因此您只需在文件中添加逻辑即可执行所有动态别名。这是一个非常简单的例子:

$ foo=hello
$ alias $foo='echo hi'
$ hello
hi

您可以使用条件、循环等为动态别名构建更复杂的逻辑。

答案2

set -x结果很有启发:

: $; set -x
: $; $(./alias-builder)
++ ./alias-builder
+ alias 'foo="bar' '$1' '-param"'
bash: alias: $1: not found
bash: alias: -param": not found
: $; 

因此,这里发生的情况是,当 bash 将alias-builder(我为包含 echo 命令的脚本起的名称) 的输出视为要内联替换为参数的内容时,它会将输出按单词分离,这通常会发生,但将引号视为单词的一部分,而不是您所期望的,即按照输入的方式解析输出。

我认为最终您的答案是使用该source选项。

现在,如果输入不方便,你可以这样做:

metamyscript() {
    source <(myscript "$@")
}

然后你应该能够做到,简单地:

: $; metamyscript hello

它将运行myscript hello,并获取其输出。

(当然,您可以根据自己的喜好更改名称。)

相关内容