我正在使用带有指令“SH -c command”的脚本,其中 command 是 bash 的别名,该别名无法解释为 Bourne shell。您是否有任何想法将此别名设置到 Bourne shell 并使其在新 shell 中工作?感谢大家 !
答案1
如果这是 Linux 上真正的 Bourne shell,我会感到惊讶。尽管 Bourne shell 现在已经移植到 Linux,但它通常不会安装,甚至不会默认打包。
您只能出于考古目的安装它。
也许您对 Bourne shell sh
(现在也称为解释器或另一种 POSIXsh
语言)感到困惑(一种古老的 shell,也曾被称为sh
(现代的 s 源自它sh
,但也有所不同))。
Bourne shell 没有别名。现代sh
做。
然而,别名是当前 shell 的本地别名。如果您执行一个新 shell(无论是bash
、sh
、csh
、zsh
...),该新 shell 将不会继承这些别名。
您需要在新 shell 中重新定义这些别名。
bash
有一种方法可以用与 的语法兼容的语法转储其别名之一的定义sh
。所以你可以这样做:
alias foo='echo foo' # alias defined in bash
foo_definition=$(alias foo)
sh -c "$foo_definition
foo"
或者简单地:
sh -c "$(alias foo)
foo"
现在,有一个问题是它并不适用于sh
.首先你会注意到我们没有这样做:
sh -c "$(alias foo);foo"
哪个会起作用不 sh
执行。
这是因为别名实际上就像某种形式的宏扩展。因为别名扩展是在解析之前完成的,所以alias foo='echo foo'; foo
在运行命令时alias
,该行已经被解析。
将别名定义放在一行并在下一行使用它可以解决某些 shell 的问题,但其他一些 shell(如yash
或zsh
)将整个sh -c
代码解析为一个整体,因此别名扩展在那里不起作用。
但是,由于别名或多或少是宏,即用其他文本替换某些文本,因此您最好手动进行替换。
您可以通过执行以下操作获取别名的值:
eval "$(alias foo | sed '1s/ /_/')"
这会将别名的定义存储foo
到$alias_foo
变量中。
然后,你可以这样做:
sh -c "$alias_foo"
将别名的值foo
作为 shell 代码传递给sh
.
为此,您可能更喜欢使用函数而不是别名。与别名一样,函数是当前 shell 的本地函数。某些 shell 喜欢rc
或bash
可以将函数导出到同一解释器的其他调用。
foo() { echo foo; }
export -f foo
sh -c foo
仅适用于sh
实现的系统bash
(主要仅 Apple OS/X 和一些基于 Linux 的系统)。
一种更可移植的方法是使用别名将函数的定义转储到传递给的代码中sh -c
:
sh -c "$(typeset -f foo); foo"
这次,扩展时间、解析时间作为函数而不是别名没有问题,因为函数是语言的真实结构。
但是,您需要确保函数的定义包含语法有效sh
且不使用任何bash
扩展的代码。
答案2
特别是谈到 Bash——
发生这种情况是因为当使用 给 Bash 发出命令时-c
,它会以非交互模式启动,特别是别名扩展被禁用。
一般来说,您不应在脚本中使用别名,而应使用 shell 函数或其他脚本。如果你真的想使用别名,尝试一下bash -ic <alias_command>
。将以-i
交互模式启动 shell,读取您的配置文件,例如/.bashrc
,然后启用别名扩展。
注意 - Bash 看到的别名将来自配置文件,而不是来自父 shell。