bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html


变量存在于内存中。假设变量str,设置或修改变量属性时,不带$号,只有引用变量的值时才使用$号。也就是说在内存中,标记变量的变量名称是str,而不是$str

1.4.1 环境变量

环境变量就是运行在"环境"上下文的,在这个上下文都可以引用。例如,常见的cd、ls等命令严格来说应该使用绝对路径如/bin/ls来执行,由于/bin目录加入到了PATH环境变量中,系统自己会去寻找PATH下的路径是否有该命令。

环境变量常用大写字母表示。常见的环境变量有HOSTNAME、SHELL、HISTSIZE、USER、PATH、PWD、LANG、HOME、LOGNAME。分别表示当前主机名、SHELL的路径即bash的类型、history保存多少记录、当前用户名、自动搜索路径、当前目录、使用的语系(临时修改语系时就改这个变量)、当前用户的家目录、当前登录的用户。

使用env或者export可以查看当前用户的环境变量。

[root@xuexi ~]# env

XDG_SESSION_ID=
HOSTNAME=xuexi.longshuai.com
TERM=linux
SHELL=/bin/bash
HISTSIZE=
SSH_CLIENT=172.16.10.1
QTDIR=/usr/lib64/qt-3.3
QTINC=/usr/lib64/qt-3.3/include
SSH_TTY=/dev/pts/
QT_GRAPHICSSYSTEM_CHECKED=
USER=root
LS_COLORS=rs=:di=;:ln=;:mh=:pi=;:so=;:do=;:bd=;;:cd=;;:or=;;:mi=;;;:su=;:sg=;:ca=;:tw=;:ow=;:st=;:ex=;:*.tar=;:*.tgz=;:*.arc=;:*.arj=;:*.taz=;:*.lha=;:*.lz4=;:*.lzh=;:*.lzma=;:*.tlz=;:*.txz=;:*.tzo=;:*.t7z=;:*.zip=;:*.z=;:*.Z=;:*.dz=;:*.gz=;:*.lrz=;:*.lz=;:*.lzo=;:*.xz=;:*.bz2=;:*.bz=;:*.tbz=;:*.tbz2=;:*.tz=;:*.deb=;:*.rpm=;:*.jar=;:*.war=;:*.ear=;:*.sar=;:*.rar=;:*.alz=;:*.ace=;:*.zoo=;:*.cpio=;:*.7z=;:*.rz=;:*.cab=;:*.jpg=;:*.jpeg=;:*.gif=;:*.bmp=;:*.pbm=;:*.pgm=;:*.ppm=;:*.tga=;:*.xbm=;:*.xpm=;:*.tif=;:*.tiff=;:*.png=;:*.svg=;:*.svgz=;:*.mng=;:*.pcx=;:*.mov=;:*.mpg=;:*.mpeg=;:*.m2v=;:*.mkv=;:*.webm=;:*.ogm=;:*.mp4=;:*.m4v=;:*.mp4v=;:*.vob=;:*.qt=;:*.nuv=;:*.wmv=;:*.asf=;:*.rm=;:*.rmvb=;:*.flc=;:*.avi=;:*.fli=;:*.flv=;:*.gl=;:*.dl=;:*.xcf=;:*.xwd=;:*.yuv=;:*.cgm=;:*.emf=;:*.axv=;:*.anx=;:*.ogv=;:*.ogx=;:*.aac=;:*.au=;:*.flac=;:*.mid=;:*.midi=;:*.mka=;:*.mp3=;:*.mpc=;:*.ogg=;:*.ra=;:*.wav=;:*.axa=;:*.oga=;:*.spx=;:*.xspf=;:
MAIL=/var/spool/mail/root
PATH=/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/sersync:/root/bin
PWD=/root
LANG=en_US.UTF-
HISTCONTROL=ignoredups
SHLVL=
HOME=/root
LOGNAME=root
QTLIB=/usr/lib64/qt-3.3/lib
SSH_CONNECTION=172.16.10.1 172.16.10.3
LESSOPEN=||/usr/bin/lesspipe.sh %s
XDG_RUNTIME_DIR=/run/user/
_=/usr/bin/env

使用echo可以输出变量的值。

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

例如,在PATH环境变量中新加入一个目录/usr/local/mysql/bin。

[root@xuexi tmp]# PATH=/usr/local/mysql/bin:$PATH

这里也能看到两个PATH第一个没使用$,第二个使用了。当对变量本身进行操作,则不使用$,当对变量值进行操作,则使用$

1.4.2 普通变量

脚本语言是弱类型的语言,变量通常不需要特地声明甚至不需要初始化,在脚本运行时由解释器进行解释运算,解释器知道变量在什么时候是什么类型,所以直接赋值使用即可。bash中,变量默认都是字符串类型,不论是否使用引号赋值,都以字符串方式存储。

1.变量赋值方式: str=value 。注意等号左右没有空格。如果有空格就是进行比较运算符的比较运算了。

2.变量引用方式:$str或者${str},例如 echo "the var is ${str}" 。

[root@xuexi tmp]# str='Hello World!'

[root@xuexi tmp]# echo "We will say ${str}"
We will say Hello World!

3.释放变量: unset str ,注意变量名前不加前缀$。

[root@xuexi ~]# unset str

4.查看所有的变量:不接任何参数的set或者declare命令,输出结果中包含了普通变量和环境变量。

5.定义只读变量: readonly str 。这时将无法修改变量值也无法unset变量,只有重新登录shell才能继续使用只读变量。

6.临时将普通变量升级为环境变量: export str 或者赋值时 export str="value" ,这样$str就可以在当前shell和子shell中使用,但是退出脚本或者重新登录shell都会取消export效果。

[root@xuexi ~]# str='Hello World!';echo $str
Hello World! [root@xuexi ~]# bash # 开启子shell
[root@xuexi ~]# echo ${str} # 子shell中查看变量结果发现没有该变量。

在子shell中查看变量,结果竟然没有该变量。这是因为$str的作用域只在当前shell,要想在子shell中也能引用普通变量,则需要使用export升级为环境变量。

[root@xuexi ~]# exit   # 退出子shell

[root@xuexi ~]# export str # 回到父shell升级该变量

[root@xuexi ~]# bash

[root@xuexi ~]# echo $str
Hello World!

1.4.3 修改变量的生命周期和作用域

普通的变量在脚本结束或退出登录后就失效,并且只对当前shell有效,其他用户和当前用户的子shell都无法使用。

使用export可以升级为临时局部的环境变量,只对当前用户的当前shell和子shell有效,退出脚本和退出登录后也失效。

如果想要设置永久的且全局的变量,一种方法是将变量的设置语句放入到/etc/profile文件中,因为每个用户登录时,都会调用该文件并执行其中的语句。如果想立即加载此文件中的配置使得临时添加的设置立即生效,只需source该文件即可。

[root@xuexi ~]# source /etc/profile

/etc/profile文件是bash的全局配置文件,还有每个用户的配置文件~/.bash_profile,此文件中的变量将只对对应的用户生效。

此外,还有几个配置bash环境配置文件,具体的见bash环境配置流程

1.4.4 获取变量的长度

在使用"${}"方式引用变量时,变量名前加上#就可以查看该变量的字符长度。空格也算入长度。例如:

[root@xuexi ~]# echo ${#str}

[root@xuexi ~]# echo ${#PATH}

1.4.5 declare声明变量

declare [+/-][选项] 变量名

选项说明:

-/+:给变量设定类型属性,取消给变量设定的类型属性

-i:声明为整型

-x:声明为环境变量

-p:显示变量名和值

例如,声明一个环境变量 declare -x str ,取消该变量 declare +x str 。

1.4.6 位置变量和特殊变量

$?:上一条代码执行的回传指令,回传0表示标准输出,即正确执行,否则为标准错误输出。

$$:当前shell的PID。除了执行bash命令和shell脚本时,$$不会继承父shell的值,其他类型的子shell都继承。

$BASHPID:当前shell的PID,这和"$$"是不同的,因为每个shell的$BASHPID是独立的。而"$$"有时候会继承父shell的值。

$!:最近一次执行的后台进程PID。

$#:统计参数的个数。

$@:所有单个参数,如"a""b""c""d"。

$*:所有参数的整体,如“abcd”。

$0:脚本名。

$1……$n:参数位置。

使用下面的脚本来验证位置变量和特殊变量。

root@xuexi tmp]# vim var.sh
#!/bin/bash # 测试各种变量的作用,包括预定义和自定义变量
echo '$?:'$?
echo '$$:'$$
echo '$!:'$!
echo '$#:'$#
echo '$@:'$@
echo '$*:'$*
echo '$0:'$
echo '$1:'$
echo '$2:'$
echo '$3:'$
echo '$4:'$

使用5个参数来运行该脚本。

[root@xuexi tmp]# sh ./var.sh a b c d e
$?:
$$:
$!:
$#:
$@:a b c d e
$*:a b c d e
$:./var.sh
$:a
$:b
$:c
$:d

1.4.7 shift轮替变量

使用 shift [N] 可以指定参数轮替,每执行一次 shift N 就踢掉N个参数,默认N为1。

例如在脚本中:

echo $   # # 输出第一个参数值
shift # # 踢掉前两个参数,第三个参数变成$
echo $ # # 此时$1的值为第三个参数的值
shift # # 又踢掉一个参数,第四个参数变成$
echo $ # # 输出第四个参数

1.4.8 shell其他基础

1、变量中字符的长度: ${#VARNAME}

2、变量赋值等:

${parameter:-word}:如果parameter为空或未定义,则变量展开为“word”;否则展开为parameter的值;

${parameter-word}:和${parameter:-word}几乎等价,除了parameter设置了但为空时,变量的结果将是null,而非word。在/etc/init.d/httpd中有此用法。

${parameter:+word}:如果parameter为空或未定义,不做任何操作,即仍然为空;否则展开为“word”值;

${parameter:=word}:如果parameter为空或未定义,则变量赋值(注意是赋值,不是展开)为“word”,否则为parameter自身;

${parameter=word}:在man bash里没有该定义,但是经测试,等价于${para:=word}。

${parameter:offset}:取子串,从offset处的后一个字符开始取到最后一个字符;

${parameter:offset:length}:取子串,从offset处的后一个字符开始,取lenth长的子串;

其中 ${parameter:-word} 最常用,最后两个是截取字符串的,偶尔也会用到。

3、脚本配置文件

配置文件中的变量值可以在脚本中被使用

要在脚本中调用配置文件,直接使用 source config_file 或 . config_file

服务启动脚本支持配置文件:/etc/sysconfig/服务脚本同名的配置文件

4、局部变量,在函数中定义局部变量使其不影响函数外的同名变量

local VAR_NAME=

5、命令mktemp创建临时文件或目录

mktemp [-d] /tmp/file.XX   # X指定越多,随机生成的后缀就越长,其中-d表示创建临时目录。

例如:

[root@xuexi ~]# mktemp haha.XXX
haha.oOe [root@xuexi ~]# mktemp -d haha.XXX
haha.npz [root@xuexi ~]# touch haha.npz/A.txt

1.4.9 变量的切分、提取和替换

其实是对变量实现的功能,只是使用文件名的说法比较典型,且容易理解它的用途。

例如,将文件名"Linux.docx.jpg"存放到变量file_name中,然后执行从左向右或从右向左的删除或贪婪删除。

[root@xuexi tmp]# file_name="Linux.docx.jpg"
[root@xuexi tmp]# file_name_greedy=${file_name%%.*}
[root@xuexi tmp]# file_name_nongreedy=${file_name%.*}
[root@xuexi tmp]# extention_name_greedy=${file_name##*.}
[root@xuexi tmp]# extention_name_nongreedy=${file_name#*.} [root@xuexi tmp]# echo -e "${file_name_greedy}\n${file_name_nongreedy}\n${extention_name_greedy}\n${extention_name_nongreedy}"
Linux
Linux.docx
jpg
docx.jpg

${var%%.*} 和 ${var%.*} 中的 %%.* 表示从右向左匹配 .* 并删除,由于Linux.docx.jpg有两种符合条件的匹配:".jpg"和".docx.jpg",所以使用两个"%%"表示贪婪删除,即删除最长匹配".docx.jpg"。可以使用一个%表示非贪婪删除,表示删除最短的匹配即".jpg"。

${var##*.} 和 ${var#*.} 中的 ##*. 表示从左向右匹配 *. 并执行贪婪删除,即删除"Linux.docx.",同理 #*. 表示非贪婪删除,即删除"Linux."。

除了删除,还可以实现提取和替换的功能。

[root@xuexi tmp]# echo "${file_name:0:5}"   # 提取第0个字节后的5个字节,即1-5字节
Linux [root@xuexi tmp]# echo "${file_name:6:4}" # 提取第6个字节后的4个字节,即第7、、、10字节
docx [root@xuexi tmp]# echo "${file_name/jpg/pdf}" # 非贪婪替换jpg为pdf,即只替换从左向右的第一个
Linux.docx.pdf [root@xuexi tmp]# echo "${file_name//jpg/pdf}" # 贪婪替换jpg为pdf,即所有的jpg都替换为pdf
Linux.docx.pdf

不错的功能是替换。有时候想要删除PATH环境变量中的某个路径,可以使用变量替换的功能,似乎没法使用变量切分来实现。例如:

[root@toystory php]# echo $A
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/apache/bin:/usr/local/mysql:/usr/local/apache/bin

注意,由于可能多次读取了配置文件,导致PATH中出现了重复的路径。现在想删除其中一个路径。使用下面的命令就可以实现路径删除,注意其中使用了转义符号,并且变量替换的替换值留空了表示删除前面匹配的部分。

[root@toystory php]# B=${A/:\/usr\/local\/apache\/bin/}

[root@toystory php]# echo $B
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/mysql:/usr/local/apache/bin

SHELL脚本--变量(基础)的更多相关文章

  1. shell脚本语法基础汇总

    shell脚本语法基础汇总 将命令的输出读入一个变量中,可以将它放入双引号中,即可保留空格和换行符(\n) out=$(cat text.txt) 输出1 2 3 out="$(cat te ...

  2. linux的基本操作(shell 脚本的基础知识)

    shell 脚本的基础知识 日常的linux系统管理工作中必不可少的就是shell脚本,如果不会写shell脚本,那么你就不算一个合格的管理员.目前很多单位在招聘linux系统管理员时,shell脚本 ...

  3. SHELL脚本编程基础知识

    SHELL脚本编程基础知识 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Linux之父Linus有一句话很经典:"Talk is cheap, show me the ...

  4. shell脚本编程基础介绍

    Linux系统——shell脚本编程基础介绍 1.什么是shell 它是一个命令解释器,在linux/unix操作系统的最外层,负责直接与用户对话,把用户的输入解释给操作系统,并处理各种操作输出的结果 ...

  5. 学习笔记:CentOS7学习之二十:shell脚本的基础

    目录 学习笔记:CentOS7学习之二十:shell脚本的基础 20.1 shell 基本语法 20.1.1 什么是shell? 20.1.2 编程语言分类 20.1.3 什么是shell脚本 20. ...

  6. linux基础—课堂随笔_03 SHELL脚本编程基础

    shell脚本编程基础 条件选择:if语句 选择执行: 注意:if语句可嵌套 单分支 if(开头)判断条件:then条件为真的分支代码 fi(结尾) 双分支 if(开头)判断条件:then条件为真的分 ...

  7. Linux shell脚本编程基础之练习篇

    shell脚本编程基础之练习篇. 1.编写一个脚本使我们在写一个脚本时自动生成”#!/bin/bash”这一行和注释信息. #!/bin/bash ] then echo "请输入一个参数& ...

  8. shell脚本由基础变量及特殊变量($@、$*、$#等)到实战。

    一.shell脚本建立: shell脚本通常是在编辑器(如vi/vim)中编写,也可以在命令行中直接执行: 1.脚本开头:     规范的脚本第一行需要指出有哪个程序(解释器)来执行脚本中的内容,在L ...

  9. shell脚本编程基础

       最近学习了shell脚本编程,感觉自己的脚本写的不太好,所以想把shell脚本相关的知识系统的整理一下,便于以后的学习和使用. 一.shell脚本基础    shell脚本是利用shell的功能 ...

随机推荐

  1. HDU 6397 Character Encoding (组合数学 + 容斥)

    题意: 析:首先很容易可以看出来使用FFT是能够做的,但是时间上一定会TLE的,可以使用公式化简,最后能够化简到最简单的模式. 其实考虑使用组合数学,如果这个 xi 没有限制,那么就是求 x1 + x ...

  2. 软件光栅器实现(四、OBJ文件加载)

    本节介绍软件光栅器的OBJ和MTL文件加载,转载请注明出处. 在管线的应用程序阶段,我们需要设置光栅器所渲染的模型数据.这些模型数据包括模型顶点的坐标.纹理.法线和材质等等,可以由我们手动编写,也可以 ...

  3. SecureCRT使用帮助

    文件上传下载 1. 安装 yum -y install lrzsz (参数-y中"y"的意思是:当安装过程提示选择全部为"yes") 2.上传 第一种方式:rz ...

  4. 清除Linux日志文件命令

    find /opt/tomcat/logs/catalina_* -mtime +9 -exec rm -rf {} \;

  5. [转] Linux 内核中的 Device Mapper 机制

    本文结合具体代码对 Linux 内核中的 device mapper 映射机制进行了介绍.Device mapper 是 Linux 2.6 内核中提供的一种从逻辑设备到物理设备的映射框架机制,在该机 ...

  6. C#.NET开源项目、机器学习、Power BI

    [总目录]本博客博文总目录-实时更新   阅读目录 1.开源Math.NET基础数学类库使用系列 2.C#操作Excel组件Spire.XLS文章目录 3.彩票数据资料库文章 4.数据挖掘与机器学习相 ...

  7. 【分布式缓存系列】集群环境下Redis分布式锁的正确姿势

    一.前言 在上一篇文章中,已经介绍了基于Redis实现分布式锁的正确姿势,但是上篇文章存在一定的缺陷——它加锁只作用在一个Redis节点上,如果通过sentinel保证高可用,如果master节点由于 ...

  8. [转]kaldi ASR: DNN训练

    作者:zqh_zy链接:http://www.jianshu.com/p/c5fb943afaba來源:简书著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 本文通过简单kaldi ...

  9. 使用Python多渠道打包apk

    使用Python生成多渠道包 往apk包中追加到一个空文件到META-INF目录以标识渠道,Android中获取此文件即可获得App的下载渠道 首先在info文件夹新建一个qdb.txt的空文本文件 ...

  10. 对js中闭包,作用域,原型的理解

    前几天,和朋友聊天,聊到一些js的基础的时候,有一种‘好像知道,好像又不不知道怎么讲的感觉’...于是捡起书,自己理一理,欢迎拍砖. 闭包 理解闭包首先要理解,js垃圾回收机制,也就是当一个函数被执行 ...