设置环境变量加不加export有什么区别?

使用 etcdctl put kv的时候,没有 ETCDCTL_API 环境变量会报错 No help topic for 'put'

所以我设置了环境变量 ETCDCTL_API=3 ,但是不起作用,只有使用 export ETCDCTL_API=3 才能正常。

我想知道:

  • ETCDCTL_API=3
  • export ETCDCTL_API=3

这两种方式有什么区别?

╭─csy@Yoga14S-yjc /mnt/c/Users/17293
╰─➤  echo $ETCDCTL_API

╭─csy@Yoga14S-yjc /mnt/c/Users/17293
╰─➤  etcdctl put testkey "Hello world"
No help topic for 'put'
╭─csy@Yoga14S-yjc /mnt/c/Users/17293
╰─➤  ETCDCTL_API=3                                                                                                                                                              3 ↵
╭─csy@Yoga14S-yjc /mnt/c/Users/17293
╰─➤  echo $ETCDCTL_API
3
╭─csy@Yoga14S-yjc /mnt/c/Users/17293
╰─➤  etcdctl put testkey "Hello world"
No help topic for 'put'
╭─csy@Yoga14S-yjc /mnt/c/Users/17293
╰─➤  export ETCDCTL_API=3                                                                                                                                                       3 ↵
╭─csy@Yoga14S-yjc /mnt/c/Users/17293
╰─➤  echo $ETCDCTL_API
3
╭─csy@Yoga14S-yjc /mnt/c/Users/17293
╰─➤  etcdctl put testkey "Hello world"
OK

image.png

阅读 7.2k
1 个回答

export表示为全局变量,不止对当前shell有效,对子进程也有效,否则则为局部变量,只对当前shell有效,子进程无效。

注意shell环境天然的隔离性,无论你怎么设置,都不可能影响到其他非关联进程的环境变量的。也就是你同时运行两个shell,无论你怎么设置变量,都不会干扰到另一个,他们是隔离的。

一个简单的范例,我们写一个test.sh:

#!/bin/bash

echo "a = ${a}"

加可执行权限: chmod +x test.sh

我们运行下:

# 直接运行,没有赋值环境变量,可预期的结果:
$ ./test.sh
a = 

# 赋值 a 为局部变量,可以看到在子进程依然看不到这个变量 a
$ a=valA
$ ./test.sh
a =

# 输出成全局变量,再试一次,由于上面已经赋值过了,不需要重新赋值
$ export a
$ ./test.sh
a = valA

解释一下上面的运行结果,./test.sh并不是在当前shell中运行的,而是在当前shell开了一个子进程bash单独运行的,所以如果你不加export是无法在子进程中看到这个环境变量的。

如果你确实需要在当前shell中运行,而不是开一个子进程运行呢?那么可以用source,你试试上面的实验用source test.sh执行,你就不需要加export照样能读取到a

值得注意的是还有一个非常特殊的用法,可以把变量赋值追加到命令运行之前,成为传递给子进程的临时变量,参考bash官方的简单命令扩展文档描述: https://www.gnu.org/software/...,这个变量只作用于子进程,不会干扰当前shell。

还是刚才那个例子,我们删掉变量定义继续再看看:

# 删掉 a 变量定义
$ unset a

# 现在看子进程已经看不到这个变量了
$ ./test.sh
a =

# 我们使用简单命令扩展的语法,不需要export就可以给子进程传递环境变量
$ a=VALB ./test.sh
a = VALB

# 上面的环境变量只会传递给子进程,我们在当前进程依旧是无法使用的
$ echo "${a}"
  # 输出为空
$ ./test.sh
a = 

# 那如果用简单命令扩展方式覆盖已存在的变量呢?
$ export a=VALC
$ echo "${a}"
VALC
$ a=VALD ./test.sh
a = VALD
$ echo "${a}"
VALC  # 简单命令扩展不会覆盖当前已有的全局变量
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏