Linux env 与 export 等

故事提要

项目开发中,我在 docker file 中,将需要执行的命令写入到 /etc/rc.d/rc.local 文件中,目的是为了容器启动时,将自动执行此命令。命令等价如下:

1
env abc=abc java -jar test.jar ${abc}

但实际运行时,我们发现没有获取到 abc 此变量。

首先,分析,如果环境变量中已经有了 abc 此变量,那么是否有 env abc=abc 这段,后面都将获取到其变量值。至于为什么不会生效,则会在接下来的章节中说明。

然后我们查看了 env export 的作用。因此将命令进行了修改。

1
env abc=abc sh test.sh

test.sh :

1
2
3
#!/bin/bash

java -jar test.jar ${abc}

这样执行时,即可读取到对应的变量值。

Linux 多文件执行顺序

  1. 通过 /boot/vm 进行启动 vmlinuz
  2. init /etc/inittab
  3. 启动相应的脚本,并且打开终端
    • rc.sysinit
    • rc.d (里面的脚本)
    • rc.local
  4. 登陆 login
  5. profile 等
    • /etc/profile.d/file
    • /etc/profile
    • /etc/bashrc
    • /root/.bashrc
    • /root/.bash_profile

从这儿可以看出 rc.local 文件是在 profile 之前执行的,而环境变量的设置通常是在 profile 中进行设置的,因此一般读取环境变量无法生效。(一种解决办法是将环境变量从 proc/1/env 读取出来拼接成命令,在执行需要环境的命令一起执行,类似上述 env 命令)

env export 等命令的区别

env

1
env

显示当前用户的环境变量。

1
env abc=abc

仅为将要执行的子进程设置环境变量,临时启用指定的环境变量执行子进程,不影响之后的其他进程与当前进程。

export

1
export

查看已存在的环境变量。按照名称排序。

1
export abc=abc

通过调用 putenv 将一个本地变量输出为当前 shell 的环境变量,从而被子进程自动继承,但子进程 export 的变量无法改变父进程的环境变量。

和 env 的最大区别点是,export 在当前 shell 中生效,而 env 只有子进程生效。

set / declare

显示当前 shell 中的所有变量,包括环境变量和自定义变量。declare 会按照名称进行排序。