# 加或不加env的命令临时环境变量赋值的差异
先说结论:
- 对于bash内建命令,二者不等价:`env`只执行外部命令,而不加`env`则默认执行内建命令
- 对于非bash内建命令,二者等价
## 对于bash内建命令,二者不等价
### bash内建命令
在 Bash 中,许多常用命令都是内建(built-in)的,这意味着它们由 Shell 自身实现,不需要调用外部程序。但有些内建命令��时也有同名的外部可执行文件(如 echo、test/\\[、pwd、kill、printf),而有些则只有内建版本(cd、type、(un)alias、jobs/fg/bg/wait)。
如果命令既是内建又有外部可执行文件,那么在调用时通常会优先使用内建版本,除非你明确指定调用外部命令。
如:
```bash
$ type echo
echo is a shell builtin
$ type $(which echo)
/usr/bin/echo is /usr/bin/echo
$ type cd
cd is a shell builtin
$ type $(which cd)
# 输出为空
```
### 而 `env` 只会执行外部命令
**echo的例子**:
```bash
$ env POSIXLY_CORRECT=1 echo -e "hello\tworld"
-e hello world
$ POSIXLY_CORRECT=1 echo -e "hello\tworld"
hello world
```
行为不一致,因为执行的并不是同一个`echo`。前者是`/bin/echo`或`/usr/bin/echo`,后者是内建命令`echo`。
**cd的例子**:
```bash
$ env ANY_VAR=any cd ~
env: ‘cd’: No such file or directory
$ ANY_VAR=any cd ~
# 输出为空,并且成功进入用户主目录
```
## 对于非bash内建命令,二者等价
二者在结果上等价,没有反例。
## 补充材料:`env` 的具体实现
`env` 在本质上是一个外部命令(即执行 `env` 本身就会开启新进程):
<https://git.savannah.gnu.org/cgit/coreutils.git/tree/src/env.c>