shell脚本中export命令未生效,原因详解
Posted 渔夫数据库笔记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了shell脚本中export命令未生效,原因详解相关的知识,希望对你有一定的参考价值。
1.问题发现
安装 jemalloc 后,执行 /usr/bin/jemalloc.sh 脚本生效环境变量 LD_PRELOAD。执行过后发现环境变量并未生效。过程如下:
[root@10-27-30-48 shao]# more jemalloc.sh
#!/bin/sh
prefix=/usr
exec_prefix=/usr
libdir=/usr/lib64
LD_PRELOAD=$libdir/libjemalloc.so.1
export LD_PRELOAD
exec "$@"
[root@10-27-30-48 shao]# sh jemalloc.sh
[root@10-27-30-48 shao]# env|grep LD_PRELOAD
NOTE:当时意识到可能是脚本执行姿势不对,因为通常使用 source /root/.bash_profile 命令来生效用户环境变量。换成 source 执行后,环境变量确实生效了,如下:
[root@10-27-30-48 shao]# source jemalloc.sh
[root@10-27-30-48 shao]# env|grep LD_PRELOAD
LD_PRELOAD=/usr/lib64/libjemalloc.so.1
#NOTE:只是在当前shell中该环境变量生效
2.解决方案
着急的朋友可以直接看解决方案如果想shell 脚本中的 export 生效,需要通过 source 命令执行脚本,如:
source jemalloc.sh
3.问题原因分析
讲解这个问题前,我们需要先知道如下三个知识点:
3.1 变量(环境变量,自定义变量)
1)环境变量和自定义变量区别
变量分为环境变量和自定义变量。环境变量是全局的,可以被子进程继承。自定义变量是局部变量,不可被子进程继承。
2)子进程可以继承父进程环境变量
启动一个shell,os会分配一个记忆块给shell使用,此内存内的变量可以让子进程取用。若父进程使用export 命令定义了一个环境变量,该环境变量会写入到上述的内存中。当该父进程启动一个子进程时,子进程会把父进程该内存块中记录的环境变量导入到自己的记忆块中。
3)变量显示命令
显示环境变量的命令:
env 或者 export
显示环境变量+自定义变量+shell函数
set
3.2 父进程和子进程
3.3 脚本执行方式区别
source , sh, ./ 不同方式执行脚本的区别:
source某脚本时,是在当前shell中执行,并未创建子进程(子shell)。
sh某脚本或./某脚本时,会创建子shell,在子进程中进行脚本的执行。
./要求该用户对执行的脚本有执行权限,sh无要求。
用户登录到Linux系统后,系统将启动一个用户shell。在这个shell中,可以使用shell命令或声明变量,
也可以创建并运行shell脚本程序。运行shell脚本程序时,系统将创建一个子shell。此时,系统中将有两个shell,
一个是登录时系统启动的shell,另一个是系统为运行脚本程序创建的shell。当一个脚本程序运行完毕,它的脚本shell将终止,
可以返回到执行该脚本之前的shell。从这种意义上来说,用户可以有许多 shell,每个shell都是由某个shell(称为父shell)派生的。
在子 shell中定义的变量只在该子shell内有效。如果在一个shell脚本程序中定义了一个变量,当该脚本程序运行时,
这个定义的变量只是该脚本程序内的一个局部变量,其他的shell不能引用它,要使某个变量的值可以在其他shell(子shell)中被使用,
可以使用export命令对已定义的变量进行输出。 export命令将使系统在创建每一个新的shell时定义这个变量的一个拷贝。
这个过程称之为变量输出。
以上是关于shell脚本中export命令未生效,原因详解的主要内容,如果未能解决你的问题,请参考以下文章