$ 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,例如ksh
或bosh
)将脚本文件作为一个整体进行解析(就好像所有换行符都已被分号替换)在从源脚本运行代码之前。这会导致alias
源脚本内部的定义不会在该源脚本本身中变为活动状态。