Shell脚本攻略02-玩转变量与环境变量
概述
变量是任何一种编程语言都必不可少的组成部分,用于存放各类数据。
脚本语言通常不需要在使用变量之前声明其类型。只需要直接赋值就可以了。
在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]
pgrep程序检查在系统的中活动进程,报告进程属性匹配命令行上指定条件的进程的ID。
pgrep 查找的是程序名,而不包其参数
pgrep相当于
ps -eo pid,cmd |awk '{print $1,$2}'|grep keyword
- 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-玩转变量与环境变量相关推荐
- LINUX SHELL脚本攻略笔记[速查]
LINUX SHELL脚本攻略笔记[速查] Linux Shell脚本攻略笔记[速查] 资源 shell script run shell script echo printf 环境变量和变量 pgr ...
- Linux Shell脚本攻略 读书笔记
内容目录: 嗨,Echo一下 给终端来点颜色 shell的控制结构 算术比较 目录操作 网站下载 tar 归档工具 rsync 备份系统快照 ftp自动传输 磁盘管理 故障排查 使用syslog记录日 ...
- Shell脚本攻略01-简介/终端打印
概述 终端打印 玩转变量与环境变量 使用函数填加环境变量 通过shell进行数学运算 玩转文件描述符与重定向 数组和关联数组 使用别名 获取终端信息 获取.设置日期 ...
- 《Linux Shell脚本攻略》学习笔记-第一章
1.1 简介 计算机可以从文本文件(称为shell脚本)中读取并执行命令. sehll脚本不仅节省了时间,而且清楚明白地表明了所执行的操作. bash shell变成了UNIX和Linux中既成事实的 ...
- 【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 ...
- 【Shell脚本进阶】从此彻底搞懂 Linux 环境变量及 Shell 启动文件 /etc/profile 、 ~/.bash_profile 和 ~/.bashrc(建议收藏)
文章目录 1. 环境变量详解 1.1 全局环境变量 1.2 本地环境变量 1.3 自定义环境变量 1.3.1 自定义本地环境变量 1.3.2 自定义全局环境变量 1.4 删除环境变量 2. 启动文件详 ...
- Linux Shell脚本攻略学习总结:一
终端打印 终端打印的常用命令有两个:echo和print 首先,我先介绍echo 1.echo echo这个命令接受三种形式的参数,实例如下: echo "Hello World" ...
- Shell脚本攻略03-使用shell进行数学运算
概述 无论哪种编程语言都少不了算术操作,在这则攻略中,我们将会研究在shell中进行算术运算的各种方法. 理论知识 在Bash shell环境中,可以利用let. (( ))和[]执行基本的算术操作. ...
- Linux Shell脚本攻略-调试脚本+函数和参数
调试脚本 可以利用Bash内建的调试工具或按照易于调试的方式编写脚本 # 1. 使用选项-x,启用shell脚本的跟踪调试功能 $ bash -x script.sh # 打印出所执行的每一行命令以及 ...
最新文章
- NIPS 2018 迁移学习相关论文
- Effective C++ Item 30 inline里里外外
- 管理表空间和数据文件——使用OMF方式管理表空间
- python安装之后怎么打开-安装python后如何通过Python打开网页
- Netty系列(三):说说NioEventLoop
- oracle 斜线出现次数,oracle一些操作小知识
- mybatis中LIKE模糊查询的几种写法以及注意点(亲测第三种CONCAT()函数的)
- Training的第二十二天
- 如何成为云计算大数据Spark高手
- 查看linux cpu和内存利用率__linux top命令
- mysql5.7.12无法启动_MySql5.7.12免安装版配置以及服务无法启动问题解决方法
- SketchUp草图大师制作分析图的详细流程介绍
- 【python爬虫 系列】1.理解网络爬虫
- Android软件安装工具-APK安装器
- 厉害!95后2万月薪程序员,背着电脑送外卖,途中还要改bug!
- 【彩艳】ArcGIS影像裁剪说明
- MT6(8)735平台Android5.1 codege.dws 文件
- 工地反光衣识别检测系统 YOLOv7
- 常用元器件使用方法1:DCDC降压芯片SY8303的使用方法
- 数据分析盒马生鲜迭代选址策略!
热门文章
- sql substr切割字符串
- 安卓桌面软件哪个好_安卓模拟器哪个比较好?
- 12. Leetcode 350. 两个数组的交集 II (数组-分离双指针)
- Leetcode - 347. Top K Frequent Elements(堆排序)
- NTU 课程笔记 :NLP - language model
- MATLAB实战系列(六)-基于蚁群算法的三维路径规划算法思路浅析
- Linux 运维故障排查思路,有这篇文章就够了
- hdfs复制文件夹_一文理解HDFS
- 利用百度的词法分析区分数据
- QT中写一个求QVector容器中数据均值的函数