我想要一个使用参数调用的脚本,该脚本会为我当前的 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
,并获取其输出。
(当然,您可以根据自己的喜好更改名称。)