export和declare命令

Last Updated: 2023-06-02 09:54:14 Friday

-- TOC --

export命令用于向子进程输出环境变量和Shell Functionexport将环境变量和shell function的有效范围延伸到了所有子进程中。是所有!

export相当于定义一个环境变量,使其在子进程中也有效。在bash中执行非builtin的程序,都会开启新的子进程。基本语法如下:

$ export name=value

测试:

$ ABC=123
$ echo $ABC
123
$ bash
$ echo $ABC
  # nothing here
$ exit
exit
$ export ABC=$ABC
$ echo $ABC
123
$ bash
$ echo $ABC
123

修改PATH的常见手段是:

$ export PATH=$PATH:/new/path/to

如果直接执行export,会看到一大堆declare -x命令,这两个命令是等效的。declare是bash的一个builtin命令。

显示所有bash函数

declare -f

显示某个具体的函数及其定义

declare -f functionName

显示所有函数名

declare -F

export环境变量

export 也是 bash 的一个内置命令。它主要是用来将父 shell 里的环境变量导出供子 shell 使用。它有如下特征:

  1. 用 export 导出的变量放在导出变量列表中,它可以被子 shell(子 shell 的子 shell 也是如此)拷贝并使用。
  2. 被 export 出来的变量虽然可以被子 shell 使用,但它也只是一个拷贝,而不会影响到父 shell 中的值以及其它子 shell 中的值。子进程可以读写 ,但是如果是写,改变了变量的值,新的值只对当前及派生的所有子进程有效!

export shell function

$ export -f <shell_func_name>

重要细节

当我们在一个 shell 里运行一个脚本时,该 shell 就会 fork 出一个新进程,从而启动了另一个命令解释器(由脚本中第一行的 #!/bin/xxx 指定,如 bash shell)来解释运行我们这个脚本。也就是说,这个新进程是一个子 shell,而之前的 shell 是个父 shell 。

在我们所运行的脚本里,我们还可以启动新的子 shell 进程,这些子 shell 进程使脚本并行地运行着多个子任务。一般而言,在一个脚本里执行一个外部命令(普通的可执行二进制文件)时,shell 会 fork 出一个子进程,然后再用 exec 来执行这个程序。但是,bash shell 的内置命令(builtin)却不会这样,它们是直接在当前进程中执行的。所以,等价的内置命令的执行速度会比执行外部命令要来的快。

在一对括号 (...) 里可以放置一组指令,这些指令是在一个子 shell 里执行的。在子 shell 里的变量不能被这段子 shell 外的代码直接访问,也就是说子 shell 里的变量不能被父 shell 所存取,就像是局部变量。

only export to sub-process

bash有一种机制,可以只export变量到子进程,而当前进程没有此变量!

$ ABC=12345 bash  # a space between

此时,在子bash以及后续的子孙进程中,都将能看到ABC变量,规则与本文其它内容相同。

$ ABC=12345 echo $ABC
$ # Nothing here, why? Because echo is a builtin running in current process

因为echo是一个builtin命令,在当前进程中执行!

下面这样,将环境变量写后程序或脚本后面,它就不再是环境变量了,而成为参数:

$ ./tt.sh CC=12345   # CC=12345 is $1, not env variable

而著名的configure,可以支持CC和CFLAGS等,是在其内部进行了复杂的计算:

$ ./configure CC=/usr/bin/clang CFLAGS='...'  # $1, $2...

本文链接:https://cs.pynote.net/sf/linux/shell/202111229/

-- EOF --

-- MORE --