为什么在交互式 bash 进程中获取的脚本中的别名没有展开?

为什么在交互式 bash 进程中获取的脚本中的别名没有展开?
$ alias bb=hello

$ cat test.sh 
#! /bin/bash

alias bb
echo "$bb"

$ ./test.sh 
./test.sh: line 3: alias: bb: not found

是否因为子 bash 进程没有从父 bash 进程继承脚本的别名?

$ source ./test.sh 
alias bb='hello'

脚本中的内容是在bash进程中执行的,所以别名存在。但别名未扩展。

Bash 手册说

当 shell 非交互式时,别名不会展开,除非使用 shopt 设置 Expand_aliases shell 选项

但是正在获取的脚本中的内容是在交互式 bash 进程中执行的,那么为什么别名没有扩展呢?

谢谢。

答案1

如果您运行脚本

./test.sh

然后它在自己的非交互式 shell 中运行,而不是在当前的交互式 shell 中运行。你需要

. ./test.sh

这相当于

source ./test.sh

在你的第二个例子中。

采购(“.”或“源”)和在 bash 中执行文件有什么区别?

对于echo "$bb",参数扩展不扩展别名:

别名当单词用作简单命令的第一个单词时,允许用字符串替换单词。

答案2

Shell 脚本在子 shell 中运行(而不是在打印提示符的当前进程中)。

为了使 shell 脚本的执行可预测,在运行该脚本之前会在子 shell 中清除别名。如果没有发生这种情况,脚本将解释未知的别名并可以执行任何操作,具体取决于哪些别名处于活动状态。

警告:如果您获取脚本,这会影响主 shell,但至少会影响遗传 shell(依赖于历史 Bourne Shell 源的 shell,例如kshbosh)将脚本文件作为一个整体进行解析(就好像所有换行符都已被分号替换)在从源脚本运行代码之前。这会导致alias源脚本内部的定义不会在该源脚本本身中变为活动状态。

相关内容