我对 bash 很陌生,我想为 bash 别名包含一个环境。我想做类似以下的事情
alias foo="bar $(baz)"
这样我就可以执行以下操作
> baz=40
> foo
并且 foo 将扩展为 command bar 40
。目前上述方法不起作用,因为在制作别名时会扩展 $(baz) 。我是否必须将其包装在一个函数或其他东西中?
我对 bash 很陌生,我想为 bash 别名包含一个环境。我想做类似以下的事情
alias foo="bar $(baz)"
这样我就可以执行以下操作
> baz=40
> foo
并且 foo 将扩展为 command bar 40
。目前上述方法不起作用,因为在制作别名时会扩展 $(baz) 。我是否必须将其包装在一个函数或其他东西中?
您需要使用单引号 ( '
) 来防止 bash 在创建别名时扩展变量:
$ alias foo='echo "$bar"'
$ bar="hello"
$ foo
hello
别名没有“环境”。别名只是一个“愚蠢的”文本替换。在这个问题中,没有使用环境变量 - 只有一个 shell 变量。如果要使用环境,请使用函数。在这种情况下,别名对函数没有任何优势。
$ alias foo='echo "$bar"'
$ bar=hi foo
这不会产生任何输出,因为为简单命令设置的环境不适用于扩展。
$ alias foo=$'eval \'echo "$bar"\''
$ bar=hi foo
hi
如果用一个函数代替,就不会有问题。
$ foo() { echo "$bar"; }
$ bar=hi foo
hi
如有疑问,请始终使用函数。
编辑
从技术上讲,以上内容仅适用于 bash。以完全可移植的方式做到这一点几乎是不可能的。
在 dash、mksh、bash POSIX 模式和其他 POSIX shell 中,您可以执行以下操作:
foo() { echo "$bar"; }
bar=hi command eval foo
但是,这在 ksh93 或 zsh 中不起作用。(我已经报告了 ksh93 的错误,但它可能永远不会被修复。)在 mksh 和 ksh93 中,您应该使用function
关键字定义函数,但这不是 POSIX。我不知道任何可以在任何地方都有效的解决方案。
更糟糕的是,POSIX 2008-TC1 添加了额外的例外,因此环境分配的工作方式将更加复杂。我建议不要使用它们,除非你真的知道你在做什么。
我执行以下操作以延迟别名中环境变量的扩展,直到它们运行,
alias foo="ls \${FOO_DIR}"
例如显示动态定义的值的内容FOO_DIR
。