Linux 环境变量(基础)

什么是环境变量

bash shell用一个叫作环境变量( environment variable)的特性来存储有关shell会话和工作环
境的信息(这也是它们被称作环境变量的原因)。这项特性允许你在内存中存储数据,以便程序
或shell中运行的脚本能够轻松访问到它们。这也是存储持久数据的一种简便方法。
在bash shell中,环境变量分为两类:
 全局变量
 局部变量

全局变量

Linux系统在你开始bash会话时就设置了一些全局环境变量。系统环境变量基本上都是使用全大写字母,以区别于普通用户的环境变量
全局环境变量对于shell会话和所有生成的子shell都是可见的。
局部变量则只对创建它们的shell可
见。

使用env或printenv查看环境变量

 ~]$ printenv
XDG_SESSION_ID=148
HOSTNAME=P1HQMSMDW01
MASTER_DATA_DIRECTORY=/gpmaster/gpseg-1
SHELL=/bin/bash
TERM=xterm
HISTSIZE=1000
GPHOME=/usr/local/greenplum-db-6.15.0
USER=gpadmin
PGPORT=5432
LD_LIBRARY_PATH=/usr/local/greenplum-db-6.15.0/lib:/usr/local/greenplum-db-6.15.0/ext/python/lib
......
PGUSER=gpadmin
PGDATABASE=qmsprd
MAIL=/var/spool/mail/gpadmin
PATH=/usr/local/greenplum-cc-6.4.0/bin:/usr/local/greenplum-db-6.15.0/bin:/usr/local/greenplum-db-6.15.0/ext/python/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/usr/local/greenplum-db-clients/bin:/home/gpadmin/.local/bin:/home/gpadmin/bin:/home/gpadmin/postgresql-9.4.24/contrib/pgbench
PWD=/home/gpadmin
LANG=en_US.UTF-8
PYTHONHOME=/usr/local/greenplum-db-6.15.0/ext/python
HISTCONTROL=ignoredups
SHLVL=1
HOME=/home/gpadmin
PYTHONPATH=/usr/local/greenplum-db-6.15.0/lib/python
LOGNAME=gpadmin
LESSOPEN=||/usr/bin/lesspipe.sh %s
GPCC_HOME=/usr/local/greenplum-cc-6.4.0
_=/bin/printenv

全局环境变量可用于进程的所有子shell

用bash命令生成一个***子shell***后,显示了HOME环境变量的当前值,这个值和
父shell中的一模一样,都是/home/gpadmin

 ~]$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
gpadmin   8521  8519  0 16:31 pts/2    00:00:00 -bash
gpadmin  14673  8521  0 16:41 pts/2    00:00:00 ps -f
 ~]$ bash
 ~]$
 ~]$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
gpadmin   8521  8519  0 16:31 pts/2    00:00:00 -bash
gpadmin  14734  8521  0 16:41 pts/2    00:00:00 bash
gpadmin  14841 14734  0 16:42 pts/2    00:00:00 ps -f
 ~]$ exit
exit
 ~]$ ps -f
UID        PID  PPID  C STIME TTY          TIME CMD
gpadmin   8521  8519  0 16:31 pts/2    00:00:00 -bash
gpadmin  15675  8521  0 16:43 pts/2    00:00:00 ps -f

局部变量

局部环境变量只能在***定义它们的进程中可见***。
set命令会显示为某个特定进程设置的所有环境变量,包括局部变量、全局变量
以及用户定义变量。

如果在当前shell中定义了一个变量
在这里插入图片描述

~]$ set
BASH=/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extquote:force_fignore:histappend:hostcomplete:interactive_comments:login_shell:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="2" [2]="46" [3]="2" [4]="release" [5]="x86_64-redhat-linux-gnu")
BASH_VERSION='4.2.46(2)-release'
COLUMNS=233
DIRSTACK=()
EUID=1000
.......省略

_=444444
colors=/home/gpadmin/.dircolors
tmp=444444

可以看到这个变量在set中可以看得到.
当该session退出之后,该变量将消失,是因为其保存在内存中.

env、 printenv和set的区别?

命令env、 printenv和set之间的差异很细微。 set命令会显示出全局变量、局部变量以
及用户定义变量。它还会按照字母顺序对结果进行排序。 env和printenv命令同set命
令的区别在于前两个命令不会对变量排序,也不会输出局部变量和用户定义变量。在这
种情况下, env和printenv的输出是重复的。

设置用户定义变量

设置局部用户定义变量

一旦启动了bash shell(或者执行一个shell脚本),就能创建在这***个shell进程内可见的局部变
量***了。可以通过***等号***给环境变量赋值
值可以是***数值***或***字符串***。
在这里插入图片描述
如果有空格怎么办?
如果要给变量赋一个含有空格的字符串值,必须用单引号来界定字符串的首和尾。
在这里插入图片描述

注意:
1、所有的环境变量名均使用大写字母,这是bash shell的标准惯例。
2、如果是你自己创建的局部变量或是shell脚本,请使用小写字母。
3、变量名区分大小写。在涉及用户定义的局部变量时坚持使用小写字母,这能够避免***重新定义系统环境变量可能带来的灾难***。
4、变量名、等号和值之间没有空格,这一点非常重要
如果在赋值表达式中加上了空格,
bash shell就会把值当成一个单独的命令:
这个变量能在新的shell中使用吗?
显然是不可以的.
在这里插入图片描述
在这个例子中生成了一个子shell。在子shell中无法使用用户定义变量my_variable。通过命
令echo $my_variable所返回的空行就能够证明这一点。当你退出子shell并回到原来的shell时,
这个局部环境变量依然可用。
类似地,如果你在子进程中设置了一个局部变量,那么一旦你退出了子进程,那个局部环境
变量就不可用。

设置全局环境变量

在设定全局环境变量的进程所创建的子进程中,该变量都是可见的。创建全局环境变量的方法是***先创建一个局部环境变量,然后再把它导出到全局环境中***

通过export 关键字来完成将局部变量变成全局变量
在这里插入图片描述
bash命令启动了一个子shell。在这个子shell
中能够正确的显示出变量v1的值。该变量能够保留住它的值是因为export命令使其
变成了全局环境变量

修改子shell中全局环境变量并不会影响到父shell中该变量的值

在这里插入图片描述
在定义并导出变量v1后, bash命令启动了一个子shell。在这个子shell中能够正
确显示出全局环境变量v1的值。子shell随后改变了这个变量的值。
这种改变仅在子shell中有效,并不会被反映到父shell中。

子shell无法使用export命令改变父shell中全局环境变量的值

在这里插入图片描述

删除环境变量

用***unset***命令
完成这个操作。在unset命令中引用环境变量时,记住不要使用$。
在这里插入图片描述

问题: 什么时候该使用美元符,什么时候不该使用?

1、如果要用到变量,使用 $;

2、如果要操作变量,不使用$。
这条规则的一个例外就是使用printenv显示某个变量的值
在这里插入图片描述
环境变量是严格区分大小写的.

子进程中删除了一个全局环境变量,只对子进程有效

在这里插入图片描述

默认的 shell 环境变量

默认情况下, bash shell会用一些特定的环境变量来定义系统环境。这些变量在你的Linux系
统上都已经设置好了,只管放心使用。 bash shell源自当初的Unix Bourne shell,因此也保留了Unix
Bourne shell里定义的那些环境变量。
最常用的的标注出来
在这里插入图片描述
除了默认的Bourne的环境变量, bash shell还提供一些自有的变量
1、BASH 当前shell实例的全路径名
2、BASHPID 当前bash进程的PID
3、COLUMNS 当前bash shell实例所用终端的宽度BASH_SUBSHELL 当前子shell环境的嵌套级别(初始值是0)
4、BASH_VERSINFO 含有当前运行的bash shell的主版本号和次版本号的数组变量
5、BASH_VERSION 当前运行的bash shell的版本号
HISTFILE 保存shell历史记录列表的文件名(默认是.bash_history)
HISTFILESIZE 最多在历史文件中存多少行

设置 PATH 环境变量

当你在shell命令行界面中输入一个外部命令时, shell必须搜索系统来找到对应
的程序。 PATH环境变量定义了用于进行命令和程序查找的目录

当安装了一个新的程序,如何将其也加入环境变量中来避免每次都要输入一个绝对路径.

使用echo $PATH 可以查看当前的shell用来查找命令和程序。 PATH中的目录使用冒号分隔。

 ~]$ echo $PATH
/usr/local/greenplum-cc-6.4.0/bin:/usr/local/greenplum-db-6.15.0/bin:/usr/local/greenplum-db-6.15.0/ext/python/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/usr/local/greenplum-db-clients/bin:/home/gpadmin/.local/bin:/home/gpadmin/bin:/home/gpadmin/postgresql-9.4.24/contrib/pgbench

最后一个pgbenc就是后来才加入的一个时PATH在这里插入图片描述
这样就可以在任当前添加bash_profile的用户下任何目录使用该命令了.
需要注意:
对PATH变量的修改只能持续到退出或重启系统。这种效果并不能一直持续。
如何永久生效呢?

定位系统环境变量

在你登入Linux系统启动一个bash shell时,默认情况下bash会在几个文件中查找命令。这些
文件叫作启动文件或环境文件。 bash检查的启动文件取决于你启动bash shell的方式。启动bash
shell有3种方式
定位系统

  1. 环境变量
  2. 作为非登录shell的交互式shell
  3. 作为运行脚本的非交互shell

登录 shell

当你登录Linux系统时, bash shell会作为登录shell启动。登录shell会从5个不同的启动文件里
读取命令:
 /etc/profile
 $HOME/.bash_profile
 $HOME/.bashrc
 $HOME/.bash_login
 $HOME/.profile
/etc/profile文件是系统上默认的bash shell的主启动文件。系统上的每个用户登录时都会执行
这个启动文件

另外4个启动文件是针对用户的,可根据个人需求定制

  1. /etc/profile文件
    /etc/profile文件是bash shell默认的的主启动文件。只要你登录了Linux系统, bash就会执行
    /etc/profile启动文件中的命令。不同的Linux发行版在这个文件里放了不同的命令
 ~]# cat /etc/profile
# /etc/profile

# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc

# It's NOT a good idea to change this file unless you know what you
# are doing. It's much better to create a custom.sh shell script in
# /etc/profile.d/ to make custom changes to your environment, as this
# will prevent the need for merging in future updates.

pathmunge () {
    case ":${PATH}:" in
        *:"$1":*)
            ;;
        *)
            if [ "$2" = "after" ] ; then
                PATH=$PATH:$1
            else
                PATH=$1:$PATH
            fi
    esac
}


if [ -x /usr/bin/id ]; then
    if [ -z "$EUID" ]; then
        # ksh workaround
        EUID=`/usr/bin/id -u`
        UID=`/usr/bin/id -ru`
    fi
    USER="`/usr/bin/id -un`"
    LOGNAME=$USER
    MAIL="/var/spool/mail/$USER"
fi

# Path manipulation
if [ "$EUID" = "0" ]; then
    pathmunge /usr/sbin
    pathmunge /usr/local/sbin
else
    pathmunge /usr/local/sbin after
    pathmunge /usr/sbin after
fi

HOSTNAME=`/usr/bin/hostname 2>/dev/null`
HISTSIZE=1000
if [ "$HISTCONTROL" = "ignorespace" ] ; then
    export HISTCONTROL=ignoreboth
else
    export HISTCONTROL=ignoredups
fi

export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL

# By default, we want umask to get set. This sets it for login shell
# Current threshold for system reserved uid/gids is 200
# You could check uidgid reservation validity in
# /usr/share/doc/setup-*/uidgid file
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
    umask 002
else
    umask 022
fi

for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do
    if [ -r "$i" ]; then
        if [ "${-#*i}" != "$-" ]; then
            . "$i"
        else
            . "$i" >/dev/null
        fi
    fi
done

unset i
unset -f pathmunge

for语句。它用来迭代/etc/profile.d目录下的所有文件。
这为Linux系统提供了一个放置特定应用程序启
动文件的地方,当用户登录时, shell会执行这些文件。
在这里插入图片描述
大部分应用都会创建两个启动文件:
一个供bash shell使用(使用.sh扩展名)
一个供c shell使用(使用.csh扩展名)。

lang.csh和lang.sh文件会尝试去判定系统上所采用的默认语言字符集,然后设置对应的LANG
环境变量
2. $HOME目录下的启动文件
剩下的启动文件都起着同一个作用:提供一个用户专属的启动文件来定义该用户所用到的环
境变量。大多数Linux发行版只用这四个启动文件中的一到两个:
 $HOME/.bash_profile
 $HOME/.bashrc
 $HOME/.bash_login
 $HOME/.profile
所以每个用户都可以编辑这些文件并添加自己的环境变
量,这些环境变量会在每次启动bash shell会话时生效。

shell会按照按照下列顺序,运行第一个被找到的文件,余下的则被忽略:
$HOME/.bash_profile
$HOME/.bash_login
H O M E / . p r o f i l e 注 意 , 这 个 列 表 中 并 没 有 HOME/.profile 注意,这个列表中并没有 HOME/.profileHOME/.bashrc文件。这是因为该文件通常通过其他文件运行的。
Centos .bahs_profile的内容

 ~]$ more .bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PGBENCH_HOME=/home/gpadmin/postgresql-9.4.24/contrib/pgbench
PATH=$PATH:$HOME/.local/bin:$HOME/bin:$PGBENCH_HOME

export PATH

.bash_profile启动文件会先去检查HOME目录中是不是还有一个叫**.bashrc的启动文件**。 如果有
的话,会先执行启动文件里面的命令。 这也就是说 可以把pgbench这个变量放在bashrc中.

交互式shell

如果你的bash shell不是登录系统时启动的(比如是在命令行提示符下敲入bash时启动),那
么你启动的shell叫作交互式shell。交互式shell不会像登录shell一样运行,但它依然提供了命令行
提示符来输入命令。
如果bash是作为交互式shell启动的,它就不会访问/etc/profile文件,只会检查用户HOME目录
中的.bashrc文件。
在这里插入图片描述
.bashrc文件有两个作用
1、查看/etc目录下通用的bashrc文件
2、为用户提供一个定制自己的命令别名和私有脚本函数的地方

非交互式shell

系统执行shell脚本时用的就是这种shell。不同的地方在于它没有命令行提示符(这也是平常用的最多的一种脚本执行方式,例如crontab)
但是当你在系统上运行脚本时,也许希望能够运行一些特定启动的命令。

为了处理这种情况, bash shell提供了BASH_ENV环境变量。当shell启动一个非交互式shell进
程时,它会检查这个环境变量来查看要执行的启动文件。如果有指定的文件, shell会执行该文件
里的命令,这通常包括shell脚本变量设置。

那如果BASH_ENV变量没有设置, shell脚本到哪里去获得它们的环境变量呢?别忘了有些
shell脚本是通过启动一个子shell来执行的
子shell可以继承父shell导出过的变量。
举例来说,如果父shell是登录shell,在/etc/profile、 /etc/profile.d/*.sh和$HOME/.bashrc文件中
设置并导出了变量,用于执行脚本的子shell就能够继承这些变量
记住由父shell设置但并未导出的变量都是局部变量。子shell无法继承局部变量。
也就是说如果在远程执行一个嵌套了脚本的脚本中定义了一个变量,该变量为局部变量,因此无法在被嵌套的shell中执行.
实例说明:

对于那些不启动子shell的脚本,变量已经存在于当前shell中了。
所以就算没有设置BASH_ENV,也可以使用当前shell的局部变量和全局变量。

环境变量持久化

全局环境变量来说( Linux系统中所有用户都需要使用的变量),可能更倾向于将新的或修
改过的变量设置放在/etc/profile文件中,但这可不是什么好主意。如果你升级了所用的发行版,
这个文件也会跟着更新,那你所有定制过的变量设置可就都没有了。

最好是在/etc/profile.d目录中创建一个以.sh结尾的文件。把所有新的或修改过的全局环境变
量设置放在这个文件中。
在大多数发行版中,存储个人用户永久性bash shell变量的地方是$HOME/.bashrc文件。

什么是外部命令?什么是内建命令?

1、外部命令,有时候也被称为文件系统命令,是存在于bash shell之外的程序。它们并不是shell
程序的一部分。外部命令程序通常位于/bin、 /usr/bin、 /sbin或/usr/sbin中。这部分就是后来安装在系统上的软件一样.例如 mysql、nginx、keepalived…
ps就是一个外部命令。你可以使用which和type命令找到它
在这里插入图片描述

2、内建命令和外部命令的区别在于前者不需要使用子进程来执行。它们已经和shell编译成了一
体,作为shell工具的组成部分存在。不需要借助外部程序文件来运行
在这里插入图片描述
which命令只显示出了外部命令文件

更加进阶的请参考: https://blog.csdn.net/whitehack/article/details/51705889

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MyySophia

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值