概述

变量是任何一种编程语言都必不可少的组成部分,用于存放各类数据。

脚本语言通常不需要在使用变量之前声明其类型。只需要直接赋值就可以了。

在Bash中,每一个变量的值都是字符串。

无论你给变量赋值时有没有使用引号,值都会以字符串的形式存储。

有一些特殊的变量会被shell环境和操作系统环境用来存储一些特别的值,这类变量就被称为环境变量。


理论知识

变量采用常见的命名方式进行命名。当应用程序执行时,它接收一组环境变量。

可以使用env命令查看所有与终端相关的环境变量。

[root@entel1 ~]# env
HOSTNAME=entel1
TERM=xterm
SHELL=/bin/bash
HISTSIZE=1000
.......省略

对于进程来说,其运行时的环境变量可以使用下面的命令来查看:

cat /proc/$PID/environ

其中,将PID设置成相关进程的进程ID(PID总是一个整数)。

如何获取$PID呢?

假设有一个叫做gedit的应用程序正在运行。我们可以使用pgrep命令获得gedit的进程ID:

$ pgrep gedit
12501

那么,你就可以通过以下命令获得与该进程相关的环境变量:

$ cat /proc/12501/environ
GDM_KEYBOARD_LAYOUT=usGNOME_KEYRING_PID=1560USER=slynuxHOME=/home/slynux
.........

环境变量远不止这些,只是由于对页面篇幅的限制,在这里删除了其他很多环境变量。


pgrep 用法

[root@entel2 ~]# pgrep --help
pgrep: invalid option -- '-'
Usage: pgrep [-flvx] [-d DELIM] [-n|-o] [-P PPIDLIST] [-g PGRPLIST] [-s SIDLIST][-u EUIDLIST] [-U UIDLIST] [-G GIDLIST] [-t TERMLIST] [PATTERN]
  1. pgrep程序检查在系统的中活动进程,报告进程属性匹配命令行上指定条件的进程的ID。

  2. pgrep 查找的是程序名,而不包其参数

  3. pgrep相当于 ps -eo pid,cmd |awk '{print $1,$2}'|grep keyword

  1. pgrep 通常和pkill在一起用,在指定条件下kill进程

如果pgrep不是很熟悉,可以用ps -ef

[root@entel2 ~]# ps -ef|less
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 Oct25 ?        00:00:15 /sbin/init
root         2     0  0 Oct25 ?        00:00:00 [kthreadd]

取 第二列 PID


举例:

[root@entel2 ~]# pgrep java
4309
[root@entel2 ~]# cat /proc/4309/environ
APP_XMX_SIZE_zmcDaemon=128MHOSTNAME=tbpr_app1SHELL=/bin/bashTERM=vt100HISTSIZE=1000SSH_CLIENT=172.25.246.66 42562 22OLDPWD=/home/settWeb/zmc_agent/daemonSSH_TTY=/dev/pts/9USER=settWebJRE_HOME=/usr/lib/jvm/jdk1.7.0_80/jreLS_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=01;05;37;41: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:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.......省略

上面的命令返回一个包含环境变量以及对应变量值的列表。每一个变量以name=value的形式来描述,彼此之间由null字符(\0)分隔。

看起来是不是很懵逼,一团乱糟糟的很难以查看。

如果你将\0替换成\n,那么就可以将输出重新格式化,使得每一行显示一组“变量=值”。替换可以使用tr命令来实现:

[root@entel2 ~]# cat /proc/4309/environ |tr '\0' '\n'
APP_XMX_SIZE_zmcDaemon=128M
HOSTNAME=tbpr_app1
SHELL=/bin/bash
TERM=vt100
HISTSIZE=1000
SSH_CLIENT=172.25.246.66 42562 22
OLDPWD=/home/settWeb/zmc_agent/daemon
SSH_TTY=/dev/pts/9
USER=settWeb
JRE_HOME=/usr/lib/jvm/jdk1.7.0_80/jre
LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;....省略

对变量和环境变量进行赋值

变量赋值

变量可以通过以下方式进行赋值:

var=value

var是变量名, value是赋给变量的值。

如果value不包含任何空白字符(例如空格),那么它就不需要使用引号进行引用,否则必须使用单引号或双引号。

注意, var = value不同于var=value。把var=value写成var = value是一个常见的错误,但前者是赋值操作,后者则是相等操作。

在变量名之前加上$前缀就可以打印出变量的内容:

var="value" #给变量var赋值
echo $var

或者

echo ${var}

输出value

栗子:

[root@entel1 ~]# cat -b var.sh 1  #!/bin/bash2  var="xiaogongjiang bash"3  var2=xiaogongjaing4  var3 = wrong_use5  echo $var6  echo ${var2}7  echo $var3
[root@entel1 ~]# ./var.sh
./var.sh: line 4: var3: command not found
xiaogongjiang bash
xiaogongjaing[root@entel1 ~]# 

可以在printf或echo命令的双引号中引用变量值。

[root@entel1 Templates]# cat variables.sh
#!/bin/bash
lesson=shell
count=100
echo "we have ${count}  $lesson  ,output by echo"
#换行 \n
printf "we have $count $lesson output by printf \n"
[root@entel1 Templates]# ./variables.sh
we have 100  shell  ,output by echo
we have 100 shell output by printf
[root@entel1 Templates]# 

注意:

使用单引号时,变量不会被扩展(expand),将依照原样显示。这意味着:

$ echo '$var' will print $var

但如果变量var已经定义过,那么$ echo "$var"会打印出该变量的值;
如果没有定义过,则什么都不打印。

[root@entel1 Templates]# cat test.sh
#!/bin/bash
var=xiaogongjiang
echo '$var' will print $var
echo '$var2' will print $var2
[root@entel1 Templates]# ./test.sh --观察var2的输出为空,因为未定义
$var will print xiaogongjiang
$var2 will print
[root@entel1 Templates]# 

环境变量赋值

环境变量是未在当前进程中定义,而从父进程中继承而来的变量。

例如环境变量,HTTP_PROXY,它定义了互联网连接应该使用哪个代理服务器。

该环境变量通常被设置成:

HTTP_PROXY=192.168.1.23:3128
export HTTP_PROXY

export命令用来设置环境变量。至此之后,从当前shell脚本执行的任何应用程序都会继承这个变量。

我们可以按照自己的需要,在执行的应用程序或者shell脚本中导出特定的变量。

在默认情况下,有很多标准环境变量可供shell使用。
PATH就是其中之一。

[root@entel1 Templates]# echo $PATH
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

在给出所要执行的命令后, shell会自动在PATH环境变量所包含的目录列表中(各目录路径之间以冒号分隔)查找对应的可执行文件。

PATH通常定义在/etc/environment或/etc/profile或~/.bashrc中。

PATH中添加一条新路径

如果需要在PATH中添加一条新路径,可以使用:

$ export PATH="$PATH:/home/user/bin"

也可以使用

$ PATH="$PATH:/home/user/bin"
$ export PATH

这样,我们就将/home/user/bin添加到了PATH中。

还有一些众所周知的环境变量: HOME、 PWD、 USER、 UID、 SHELL等


Addition

下面我们再多看些有关标准变量和环境变量的技巧。

获得字符串长度${#}

[root@entel1 Templates]# cat test.sh
#!/bin/bash
var=xiaogongjiang
echo "var's length  ${#var}"
[root@entel1 Templates]# ./test.sh
var's length  13

识别当前所使用的shell

可以用下面的方法获知当前使用的是哪种shell:

echo $SHELL

也可以用

echo $0

检查是否为超级用户

UID是一个重要的环境变量,可以用于检查当前脚本是以超级用户还是以普通用户的身份运行的。

root用户的UID是0。

例如:

[root@entel1 Templates]# cat test.sh
#!/bin/bash
#检测用户是否是root用户
#[] 两侧记得带空格 [$UID -ne 0] 会报错
if [ $UID -ne  0 ]; then echo Non root user
else echo Root user
fi
[root@entel1 Templates]# ./test.sh
Root user

修改Bash提示字符串( username@hostname:~$)

http://blog.csdn.net/yangshangwei/article/details/52928009

当我们打开终端或是运行shell时,会看到类似于user@hostname:/home/$的提示字符串。

不同GNU/Linux发布版中的提示及颜色略有不同。我们可以利用PS1环境变量来定制提示文本。

默认的shell提示文本是在文件~/.bashrc中的某一行设置的。

 可以使用如下命令列出设置变量PS1的那一行:

$ cat ~/.bashrc | grep PS1
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '

 如果要设置一个定制的提示字符串,可以输入:

$ PS1="PROMPT>"
PROMPT> Type commands here #提示字符串已经改变

 我们可以利用类似\e[1;31的特定转义序列来设置彩色的提示字符串

还有一些特殊的字符可以扩展成系统参数。

例如: \u可以扩展为用户名, \h可以扩展为主机名,而\w可以扩展为当前工作目录。


使用函数添加环境变量

环境变量通常用于存储路径列表,这些路径用于搜索可执行文件、库文件等。

例如$PATH、$LD_LIBRARY_PATH,它们通常看起来像这样:

PATH=/usr/bin;/bin
LD_LIBRARY_PATH=/usr/lib;/lib

这意味着只要shell需要运行二进制可执行文件时,它会首先查找/usr/bin,然后是/bin。

场景举例

当你必须使用源代码编译生成程序并将其安装到某个特定路径中时,有项极其常见的任务就是将该程序的bin目录加入PATH环境变量。

假设我们要将myapp安装到/opt/myapp,它的二进制文件在bin目录中,库文件在lib目录中。

实现方法

export PATH=/opt/myapp/bin:$PATH
export LD_LIBRARY_PATH=/opt/myapp/lib;$LD_LIBRARY_PATH

PATH和LD_LIBRARY_PATH现在看起来应该像这样:

PATH=/opt/myapp/bin:/usr/bin:/bin
LD_LIBRARY_PATH=/opt/myapp/lib:/usr/lib;/lib

不过我们可以把下面的函数加入.bashrc-,让一切变得更轻松些:

prepend() { [ -d "$2" ] && eval $1=\"$2':'\$$1\" && export $1; }

像下面这样来使用该函数:

prepend PATH /opt/myapp/bin
prepend LD_LIBRARY_PATH /opt/myapp/lib

函数分析

我们定义了名为prepend()的函数,它首先检查该函数第二个参数所指定的目录是否存在。

如果存在, eval表达式将第一个参数所指定的变量值设置成第二个参数的值加上“ :”(路径分隔符),随后再跟上首个参数的原始值。


完善函数

不过,有一点需要留意。在进行添加时,如果变量为空,则会在末尾留下一个“ :”。

要解决这个问题,可以将该函数再进行一些修改

prepend() { [ -d "$2" ] && eval $1=\"$2\$\{$1:+':'\$$1\}\" && export $1 ; }

在这个函数中,我们引入了一种shell参数扩展的形式:

${parameter:+expression}

如果parameter有值且不为空,则使用expression的值。

通过这次修改,在追加环境变量时,当且仅当旧值存在,才会增加。


Shell脚本攻略02-玩转变量与环境变量相关推荐

  1. LINUX SHELL脚本攻略笔记[速查]

    LINUX SHELL脚本攻略笔记[速查] Linux Shell脚本攻略笔记[速查] 资源 shell script run shell script echo printf 环境变量和变量 pgr ...

  2. Linux Shell脚本攻略 读书笔记

    内容目录: 嗨,Echo一下 给终端来点颜色 shell的控制结构 算术比较 目录操作 网站下载 tar 归档工具 rsync 备份系统快照 ftp自动传输 磁盘管理 故障排查 使用syslog记录日 ...

  3. Shell脚本攻略01-简介/终端打印

    概述  终端打印  玩转变量与环境变量  使用函数填加环境变量  通过shell进行数学运算  玩转文件描述符与重定向  数组和关联数组  使用别名  获取终端信息  获取.设置日期 ...

  4. 《Linux Shell脚本攻略》学习笔记-第一章

    1.1 简介 计算机可以从文本文件(称为shell脚本)中读取并执行命令. sehll脚本不仅节省了时间,而且清楚明白地表明了所执行的操作. bash shell变成了UNIX和Linux中既成事实的 ...

  5. 【Linux Shell脚本攻略】第1章 小试牛刀

    第1章 小试牛刀 1.1 简介 1.2 在终端中显示输出 1.2.1 预备知识 1.2.2 实战演练 1.2.3 工作原理 1.2.4 补充内容 1.在echo中转义换行符 2.打印彩色输出 1.3 ...

  6. 【Shell脚本进阶】从此彻底搞懂 Linux 环境变量及 Shell 启动文件 /etc/profile 、 ~/.bash_profile 和 ~/.bashrc(建议收藏)

    文章目录 1. 环境变量详解 1.1 全局环境变量 1.2 本地环境变量 1.3 自定义环境变量 1.3.1 自定义本地环境变量 1.3.2 自定义全局环境变量 1.4 删除环境变量 2. 启动文件详 ...

  7. Linux Shell脚本攻略学习总结:一

    终端打印 终端打印的常用命令有两个:echo和print 首先,我先介绍echo 1.echo echo这个命令接受三种形式的参数,实例如下: echo "Hello World" ...

  8. Shell脚本攻略03-使用shell进行数学运算

    概述 无论哪种编程语言都少不了算术操作,在这则攻略中,我们将会研究在shell中进行算术运算的各种方法. 理论知识 在Bash shell环境中,可以利用let. (( ))和[]执行基本的算术操作. ...

  9. Linux Shell脚本攻略-调试脚本+函数和参数

    调试脚本 可以利用Bash内建的调试工具或按照易于调试的方式编写脚本 # 1. 使用选项-x,启用shell脚本的跟踪调试功能 $ bash -x script.sh # 打印出所执行的每一行命令以及 ...

最新文章

  1. NIPS 2018 迁移学习相关论文
  2. Effective C++ Item 30 inline里里外外
  3. 管理表空间和数据文件——使用OMF方式管理表空间
  4. python安装之后怎么打开-安装python后如何通过Python打开网页
  5. Netty系列(三):说说NioEventLoop
  6. oracle 斜线出现次数,oracle一些操作小知识
  7. mybatis中LIKE模糊查询的几种写法以及注意点(亲测第三种CONCAT()函数的)
  8. Training的第二十二天
  9. 如何成为云计算大数据Spark高手
  10. 查看linux cpu和内存利用率__linux top命令
  11. mysql5.7.12无法启动_MySql5.7.12免安装版配置以及服务无法启动问题解决方法
  12. SketchUp草图大师制作分析图的详细流程介绍
  13. 【python爬虫 系列】1.理解网络爬虫
  14. Android软件安装工具-APK安装器
  15. 厉害!95后2万月薪程序员,背着电脑送外卖,途中还要改bug!
  16. 【彩艳】ArcGIS影像裁剪说明
  17. MT6(8)735平台Android5.1 codege.dws 文件
  18. 工地反光衣识别检测系统 YOLOv7
  19. 常用元器件使用方法1:DCDC降压芯片SY8303的使用方法
  20. 数据分析盒马生鲜迭代选址策略!

热门文章

  1. sql substr切割字符串
  2. 安卓桌面软件哪个好_安卓模拟器哪个比较好?
  3. 12. Leetcode 350. 两个数组的交集 II (数组-分离双指针)
  4. Leetcode - 347. Top K Frequent Elements(堆排序)
  5. NTU 课程笔记 :NLP - language model
  6. MATLAB实战系列(六)-基于蚁群算法的三维路径规划算法思路浅析
  7. Linux 运维故障排查思路,有这篇文章就够了
  8. hdfs复制文件夹_一文理解HDFS
  9. 利用百度的词法分析区分数据
  10. QT中写一个求QVector容器中数据均值的函数