Bash编程013——环境变量

Bash编程013——环境变量

环境变量可以帮助提升你的Shell体验。很多程序和脚本都通过环境变量来获取系统信息,存储临时数据和配置信息。

13.1 什么是环境变量

bash使用环境变量( environment variables)来存储有关shell会话和工作环境的信息。这项功能允许你在内存中存储数据,以便程序或shell脚本能够轻松访问。这是存储持久数据的一种简便方法。bash的环境变量分为两类:全局变量和局部变量。

补充:bash使用一致的专有环境变量,但是不同发行版的linux可能会添加自己的环境变量,本博客使用的发行版为Ubuntu 16.04.5 Gnome。

13.1.1 全局环境变量

全局变量对于shell会话和所有生成的子shell都是可见的。全局环境变量有助于子shell获取父shell信息。

在Linux中有四个命令可以帮助我们查看所有的环境变量,printenv、env、set、declare。

# 因为一般环境变量比较多,无法再一个屏幕页中显示,可以使用env | less来查看。
env # 注:printenv可以获取相同的结果
printenv
# 输出结果如下:
XDG_VTNR=2
SSH_AGENT_PID=1833
XDG_SESSION_ID=1
CLUTTER_IM_MODULE=xim
TERM=xterm-256color
SHELL=/bin/bash
XDG_MENU_PREFIX=gnome-
VTE_VERSION=4205
QT_LINUX_ACCESSIBILITY_ALWAYS_ON=1
WINDOWID=46137350
GTK_MODULES=gail:atk-bridge
USER=ruo
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:
QT_ACCESSIBILITY=1
DESKTOP_AUTOSTART_ID=10b22a799e35ca853154656900878515100000017700001
SSH_AUTH_SOCK=/run/user/1000/keyring/ssh
SESSION_MANAGER=local/ruo-pc:@/tmp/.ICE-unix/1770,unix/ruo-pc:/tmp/.ICE-unix/1770
USERNAME=ruo
DEFAULTS_PATH=/usr/share/gconf/gnome.default.path
XDG_CONFIG_DIRS=/etc/xdg/xdg-gnome:/etc/xdg
PATH=/home/ruo/bin:/home/ruo/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
DESKTOP_SESSION=gnome
QT_IM_MODULE=fcitx
XDG_SESSION_TYPE=x11
PWD=/home/ruo
XMODIFIERS=@im=fcitx
LANG=zh_CN.UTF-8
MANDATORY_PATH=/usr/share/gconf/gnome.mandatory.path
GDMSESSION=gnome
XDG_SEAT=seat0
HOME=/home/ruo
SHLVL=1
LANGUAGE=zh_CN:zh
GNOME_DESKTOP_SESSION_ID=this-is-deprecated
XDG_SESSION_DESKTOP=gnome
LOGNAME=ruo
QT4_IM_MODULE=fcitx
XDG_DATA_DIRS=/usr/share/gnome:/usr/local/share:/usr/share:/var/lib/snapd/desktop
DBUS_SESSION_BUS_ADDRESS=unix:abstract=/tmp/dbus-KiSjECqdfu,guid=cefed3c1dd4c76fc3c0c7e8d5c2ec52f
LESSOPEN=| /usr/bin/lesspipe %s
WINDOWPATH=2
XDG_RUNTIME_DIR=/run/user/1000
DISPLAY=:1
XDG_CURRENT_DESKTOP=GNOME
GTK_IM_MODULE=fcitx
LESSCLOSE=/usr/bin/lesspipe %s %s
XAUTHORITY=/run/user/1000/gdm/Xauthority
_=/usr/bin/env

使用set命令时会一起显示之前定义的函数,仅显示变量可以使用如下命令:

set -o posix; set

13.1.2 局部环境变量。

局部变量只能在定义它们的进程中可见,Linux也有默认定义的标准局部环境变量。你也可以自己定义局部环境变量,称为用户定义局部变量。

set命令会显示某个特定进程的所有环境变量,包括局部变量、全局变量以及用户定义变量。

补充:set、env、printenv之间的区别很细微。set命令会显示出所有变量,并且按照字母顺序排序。env和printenv输出相同,但是仅含有全局变量,并且未对变量排序。

13.2 设置用户定义变量

设置局部用户定义变量,就是之前002一节提到的变量。

注意:一般bash的环境变量都是使用的大写字母,建议自己的变量名为小写,避免产生冲突。

# 类似这种格式
my_var=10086

设置全局环境变量

先创建一个局部环境变量,然后使用export命令将其导出到全局变量。

# 示例

# 定义一个局部变量
myvar=10086

# 启动子shell
bash

echo $myvar # 输出为空白的一行

# 退出子shell
exit

# 导出为全局变量
export myvar # 注意这里不加$

# 再次启动一个子shell
bash

echo $myvar # 输出为:10086

13.3 删除环境变量

使用unset命令,格式unset varname

注意:在子shell中删除全局环境变量不会影响到父shell的全局环境变量。

13.4默认的一些环境变量

HOME:当前用户的主目录

IFS:shell用来将文本字符串分割成字段的一系列字符

PATH:shell用来查找命令的目录列表。当你输入一个命令时,shell会按照这个目录遍历寻找。

13.5 系统环境变量

在登录系统启动一个bash shell时,默认情况下bash会在几个文件中查找命令。这些文件叫做启动文件或者环境文件。bash检查的启动文件取决于启动bash的方式:

  • 登录时作为默认登录shell
  • 作为非登录shell的交互式shell
  • 作为脚本运行的非交互式shell

13.5.1 登录shell

登录Linux系统是,bash作为登录shell启动。登录shell会一次从以下几个启动文件中读取命令。

  • /etc/profile
  • $HOME/.bash_profile
  • $HOME/.bashrc
  • $HOME/.bash_login
  • $HOME/.profile

/etc/profile文件是系统上默认的bash shell的主启动文件。系统上的每个用户登录时都是执行这个文件。

注意: 某些Linux发行版使用了可拆卸式认证模块(PAM)。这时,PAM文件会在bash启动前处理,这些文件可能会包含环境变量。PAM文件包括/etc/environment和$HOME/.pam_environment文件。

我们这里来查看一下/etc/profile文件的内容,学了之前的内容的话,这个文件很容易理解。

# /etc/profile: system-wide .profile file for the Bourne shell (sh(1))
# and Bourne compatible shells (bash(1), ksh(1), ash(1), ...).

if [ "$PS1" ]; then
  if [ "$BASH" ] && [ "$BASH" != "/bin/sh" ]; then
    # The file bash.bashrc already sets the default PS1.
    # PS1='\h:\w\$ '
    if [ -f /etc/bash.bashrc ]; then
      . /etc/bash.bashrc
    fi
  else
    if [ "`id -u`" -eq 0 ]; then
      PS1='# '
    else
      PS1='$ '
    fi
  fi
fi

if [ -d /etc/profile.d ]; then
  for i in /etc/profile.d/*.sh; do
    if [ -r $i ]; then
      . $i
    fi
  done
  unset i
fi

$HOME目录下的启动文件

剩下的启动文件都启着同一个作用:提供一个用户专属的启动文件来定义该用户所用到的环境变量。一般Linux发行版只有到下面这四个启动文件中的一两个。

  • $HOME/.bash_profile
  • $HOME/.bashrc
  • $HOME/.bash_login
  • $HOME/.profile

这里列出Ubuntu的启动文件:

ls -a ~
.
..
.bash_history
.bash_logout
.bashrc
.cabal
.cache
.cgdb
Codes
.config
.dbus
Desktop
Documents
Downloads
fault.c
.gconf
.gnupg
.ICEauthority
.lesshst
.local
.mozilla
Music
.nano
Pictures
.presage
.profile
Public
snap
.sogouinput
.ssh
.sudo_as_admin_successful
.swp
Templates
test.c
.tgdb
Videos
.vim
.viminfo
.vimrc
.wget-hsts
.xinputrc
.xsel.log

可以看到这里只有.bashrc和.profile两个文件。

shell会按照以下顺序执行启动文件,找到第一个其他的就会被忽略。

  • $HOME/.bash_profile
  • $HOME/.bash_login
  • $HOME/.profile

注意:这里没有$HOME/.bbashrc,因为该文件是通过上面三个文件中的一个运行的。

我们来查看一下.profile文件,.bashrc文件请自行查看。

注意:这里会检查当前运行的shell是否是bash,如是的话,检查是否存在$HOME/.bashrc,若存在则加载该文件。

cat ~/.profile
# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.

# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022

# if running bash
if [ -n "$BASH_VERSION" ]; then
    # include .bashrc if it exists
    if [ -f "$HOME/.bashrc" ]; then
    . "$HOME/.bashrc"
    fi
fi

# set PATH so it includes user's private bin directories
PATH="$HOME/bin:$HOME/.local/bin:$PATH"
13.5.2 交互式shell

交互式shell不是登录系统时启动的,它可能是你打开终端启动的。交互式shell不会访问/etc/profile文件,而是只会检查用户HOME目录中的.bashrc文件。

13.5.3 非交互式shell

执行shell脚本是的非交互式shell。脚本能以不同的方式执行,可以启动子shell执行,也可以在当前shell中执行。

bash提供了一个BASH_ENV的环境变量,当shell启动一个非交互式shell进程时,它会检查这个环境边浪来查看要执行的启动文件。若有指定的文件,则shell会执行该文件。Ubuntu未设置该变量。

若BASH_ENV未设置,那么非交互式shell如何获得环境变量呢?对于以子shell进程执行的情况,子shell会继承父shell导出的变量(export)。对于在当前shell中执行的情况,变量即为当前shell的变量。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,417评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,921评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,850评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,945评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,069评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,188评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,239评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,994评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,409评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,735评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,898评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,578评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,205评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,916评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,156评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,722评论 2 363
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,781评论 2 351

推荐阅读更多精彩内容