《Shell脚本学习指南》学习笔记之变量、判断和流程控制
变量
- 定义变量
可以使用export和readonly来设置变量,export用于修改或打印环境变量,readonly则使得变量不得修改。语法:export name[=word] ...
readonly name[=word] ...可以export/readonly时就给变量赋值,或给变量赋值后再export/readonly变量,如:
export website=oseye.net
age=22
export age比较常用的exoprt,它是把变量放进环境中,新的进程可以从其父进程继承环境,但继承后就是各自的,操作互不影响;而readonly不能被子进程继承。
如打开终端,输入:a=b
echo $a
gnome-terminal这样会在打开的子进程的终端,你在新的终端试试:
echo $a
可以看到输出是“b”。
- 删除变量
使用unset从当前的shell删除变量或函数,语法如下:unset [ -v ] variable ...
unset -f function ....-v是默认选项,表示删除/接触指定的变量;
-f解除或删除指定的函数; - 使用变量
除了在变量名之前加符号“$”使用变量外,还有更特殊的使用情况,这些变量名括在花括号里如${var},而且会增加额外的语法表达更丰富的含义。
替换运算符运算符 替换 ${varname:-word} 如果varname存在且不是null,则返回其值;否则返回word。
用途:如果变量未定义,则返回默认值。
范例:如果count未定义,则${count:-0}的值为0。
${varname:=word} 如果varname存在且不是null,则返回其值;否则,设置它的值设为word,并返回其值。
用途:如果变量未定义,则设置变量为默认值。
范例:如果count未定义,则${count:=0}设置count为0,并返回0。
${varname:?message} 如果varname存在且不是null,则返回它的值;否则显示varname:message,并退出当前的命令或脚本。省略message会出现默认信息parameter null or not set(参数为空或未设置).
用途:为了捕捉由于变量未定义所导致的错误。
范例:${count:?"undefined!"}如果count未定义将显示“undefined!”且退出。
${varname:+word} 如果varname存在且不是null,则返回word;否则返回null。
用途:为测试变量是否存在。
范例:如果count已定义,则${count:+1}返回1(也就是“真”)。
模式匹配运算符
下表中使用的模式(pattern)以及shell里其他的地方,例如case语句里所使用的模式都是shell的“通配符”模式,而不是正则表达式。
表中假设path的值为/home/tolstoy/mem/long.file.name运算符 替换 ${varname#pattern} 从前面匹配,匹配成功则删除匹配的最短部分,并返回剩下的部分。
例子:${path#/*/}
结果:tolstoy/mem/long.file.name
${varname##pattern} 从前面匹配,匹配成功则删除匹配的最长部分,并返回剩下的部分。
例子:${path##/*/}
结果:long.file.name
${varname%pattern} 从后面匹配,匹配成功则删除匹配的最短部分,并返回剩下的部分。
例子:${path#.*}
结果:tolstoy/mem/long.file
${varname%%pattern} 从后面匹配,匹配成功则删除匹配的最长部分,并返回剩下的部分。
例子:${path##.*}
结果:tolstoy/mem/long
- 位置参数
所谓位置参数指的是Shell脚本的命令行参数,也表示在Shell函数内的函数参数,它的名称是以单个整数来命名,处于历史原因,当这个整数大于9时,需要用花括号({})括起来。
除了使用整数来引用位置参数,还有一些特殊的变量:- $# 位置参数的总数;
- $*,$@ 一次表示所有命令行参数,可以直接传递给函数或脚本;
- "$*" 将所有的位置参数视为单个字符串,等同于"$1 $2 ...";
- "$@" 将所有命令行参数视为单独个体,也就是单独字符串,等同于"$1" "$2" ...;
POSIX还有一些内置的变量:
- # 目前进程的参数个数。
- @ 传递给当前进程的参数。置于双引号内,会展开为个别参数。
- * 传递给当前进程的命令行参数,置于双括号内,展开时为一单独参数。
- - 在引用时给的Shell 的选项。
- ? 前一命令的退出状态。
- $ shell的PID。
- 0 shell程序的名字。
- ! 最近一个后台命令的PID。可以此方式存储进程编号,然后通过wait命令同步。
- HOME 主目录。
- IFS 内部的字段分隔符,一般为制表符、空格、以及换行符。
- LANG 当前locale的默认名称
- LC_ALL 当前locale的名称。会覆盖LANG与其他LC_*变量。
- LC_CTYPE 在模式匹配期间,用来确定字符类别的当前locale名称。
- LC_MESSAGE 输出信息的当前语言名称。
- LINENO 刚执行过的行在脚本或函数内的行编号。
- NLSPATH 在$LC_MESSAGES(XSI)所给定的信息语言里,信息目录的位置。
- PATH 命令查找的路径。
- PPID 父进程的进程编号。
- PS1 主要的命令提示字符串,默认为“$”。
- PS2 行继续提示字符串默认">"。
- PS4 以set -x设置的执行跟踪的提示字符串,默认为“+”。
- PWD 当前工作目录。
- 算数运算符
Shell的算术运算符与C语言里差不多,优先级顺序也相同。虽然有些是(包含)特殊字符,不过它们不需要以反斜杠转义,因为它们都置于$((...))语法中,这一语法如同双引号功能,除了内嵌双引号无须转义。运算符 意义 顺序 ++ -- 增加及减少,可前置也可放在结尾 由左至右 + - ! ~ 一元的正号与负号;逻辑与位的取反 由左至右 + - * / % 加、减、乘、除、余 由左至右 << >> 左移位、右移位 由左至右 < <= > >= == != 比较 由左至右 & | ^ 位的与、或、异或 由左至右 && || 逻辑的与、或 由左至右 ? : 条件表达式 由右至左 = += -= *= /= %= &= ^=
<<= >>= |=
赋值运算符 由左至右 用圆括号把字表达式语句括起来产生数字的结果1表示真,0表示假。对于逻辑的AND与OR运算符而言,任何的非0值函数都为真。
退出状态
每一条命令,不管是内置的、Shell函数,还是外部的,当它退出时,都会返回一个小的整数值给引用它的程序,这就是大家所熟知的程序退出状态。POSIX标准定义了退出状态及其含义:
状态值 | 含义 |
0 | 表示运行成功,程序执行未遇到任何问题 |
1-125 | 表示运行失败,脚本命令、系统命令错误或参数传递错误 |
126 | 找到了命令但无法执行 |
127 | 未找到要运行的命令 |
>128 | 命令被系统强行结束 |
test命令
test命令接受不同的参数用于测试各种条件是否成立,它还有一种等效形式:[ ... ],因此test的语法:
test [ expression ]
[ [ expression ] ]
test命令的参数被描述为表达式,如下表:
运算符 | 如果....则为真 |
#一元表达式,运算符后边只有一个参数 | |
-b file | file为块设备 |
-c file | file为字符设备 |
-d file | file为目录 |
-e file | file存在 |
-f file | file为一般文件 |
-g file | file属性位set- group-id置1 |
-h file | file为符号链接(与-L 同) |
-k file | file设置了粘滞位(sticky bit) |
-L file | file为符号链接(与-h同) |
-O file | file用户拥有该文件 |
-p file | file为命名管道 |
-r file | file(对用户)可读 |
-s file | file不是空的(长度大于0字节) |
-S file | file存在且为套接字(socket) |
-t fd | file描述符与终端相关联 |
-u file | file属性位set-user-id置1 |
-w file | file(对用户)可写 |
-x file | file(对用户)可执行 |
-n string | 字符串是非null (长度大于0字节) |
-z string | 字符串为空(长度为0字节) |
#二元表达式,运算符前后各有一个参数 | |
expr1 -a expr2 | 两个表达式皆为真(逻辑与) |
expr1 -o expr2 | 两个表达式至少有一个为真(逻辑或) |
---------------------------------------------------------- | |
file1 -nt file2 | 第一个文件比第二个文件新(利用修改时间戳比较) |
file1 -ot file2 | 第一个文件比第二个文件旧(利用修改时间 戳比较) |
file1 -ef file2 | 两个文件由链接关联在一起(硬链接或符号链接) |
---------------------------------------------------------- | |
var1 = var2 | 第一个字符串与第二个字符串相同 |
var1 != var2 | 第一个字符串与第二个字符串不相同 |
---------------------------------------------------------- | |
var1 -eq var2 | 第一个整数与第二个整数相等 |
var1 -ne var2 | 第一个整数不等于第二个整数 |
var1 -lt var2 | 第一个整数小于第二个整数 |
var1 -le var2 | 第一个整数小于或等于第二个整数量 |
var1 -gt var2 | 第一个整数大于第二个整数 |
var1 -ge var2 | 第一个整数大于或等于第二个整数 |
- 所有shell变量都应该以引号括起来,这样即使shell变量展开后为null值,也不会出现问题!
- -a和-o是test表达式之间,而&&和||是test之间的,要区分下。
- 比较字符串是非常微妙的,因为字符串可能为空或减号开头,test命令会被混淆,所以通常在字符串前置字母X比如test "X$a" = "Xhe",当然了前置字母可以是任意的;
- 只能做整数测试,而不能做任何浮点数测试;
流程控制
- if语句
if 条件
then
Command
else
Command
fi - case语句
case $变量名 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
*)
默认执行的命令序列
;;
esaccase语句结构特点如下:
- case行尾必须为单词“in”,每一个模式必须以右括号“)”结束。
- 双分号“;;”表示命令序列结束。
- 匹配模式中可是使用方括号表示一个连续的范围,如[0-9];使用竖杠符号“|”表示或。
- 最后的“*)”表示默认模式,当使用前面的各种模式均无法匹配该变量时,将执行“*)”后的命令序列。
- for语句
for循环对一个变量的可能的值都执行一个命令序列。赋给变量的几个数值既可以在程序内以数值列表的形式提供,也可以在程序以外以位置参数的形式提供。for循环的一般格式为:for $变量名 [in 数值列表]
do
命令序列
done变量名可以是用户选择的任何字符串,如果变量名是var,则在in之后给出的数值将顺序替换循环命令列表中的$var。如果省略了in,则变量var的取值将是位置参数。对变量的每一个可能的赋值都将执行do和done之间的命令列表。
- while和until
while 和 until命令都是用命令的返回状态值来控制循环的.While 循环的一般格式为:
while
若干个命令行1
do
若干个命令行2
done只要while的“若干个命令行1”中最后一个命令的返回状态为真,while循环就继续执行do...done之间的“若干个命令行2”。
until命令是另一种循环结构,它和while命令相似,其格式如下:
until
若干个命令行1
do
若干个命令行2
doneuntil循环和while循环的区别在于:while循环在条件为真时继续执行循环,而until则是在条件为假时继续执行循环。
- break和continue
break和continue命令分别用来退出循环或跳到循环体的其他地方,他们还可以接受参数,用来指出要退出或继续多少个被包含的循环,如while 条件(如:true)
do ...
while 条件
do ...
break 2
done
done
《Shell脚本学习指南》学习笔记之变量、判断和流程控制的更多相关文章
- Linux Shell脚本攻略 读书笔记
Linux Shell脚本攻略 读书笔记 这是一本小书,总共253页,但内容却很丰富,书中的示例小巧而实用,对我这样总是在shell门前徘徊的人来说真是如获至宝:最有价值的当属文本处理,对这块我单独整 ...
- C#基础课程之二变量常量及流程控制
课堂练习:.一个四位整数 输出它的千位,百位,十位,个位 数字. ; ; % ; % ; ; Console.WriteLine("千位数" + b+" 百位数" ...
- shell学习指南-阅读笔记
shell学习指南真不是刚开始学习shell应该看得书,虽然其中讲了简单的linux命令,shell语法等,但是每章也有些深入和生僻地方,我想如果我刚学shell看到这样的地方一定会头疼的要死.或许也 ...
- shell脚本学习指南-学习(1)
1.先看下面这个命令: $who | wc -l 计算当前登陆的用户个数: $who 当前登陆的有哪些用户: pipeling( | )可以在两个程序之间建立管道,左侧的结果成为右侧的 ...
- linux shell 脚本攻略学习20--awk命令入门详解
awk生于1977年,创始人有三个,分别为 Alfred Aho,Peter Weinberger, 和 Brian Kernighan,名称源于三个创始人的姓的首字母. 作用:处理文本文件. awk ...
- Linux Shell脚本攻略学习总结:一
终端打印 终端打印的常用命令有两个:echo和print 首先,我先介绍echo 1.echo echo这个命令接受三种形式的参数,实例如下: echo "Hello World" ...
- linux shell脚本、命令学习
1,echo "test" > test.txt 输出重定向到text.txt,文件不存在就创建 echo "test" >> test ...
- Linux Shell脚本攻略学习总结:二
比较与测试 程序中的流程控制是由比较和测试语句来处理的. 我们可以用if,if else 以及逻辑运算符来执行测试,而用一些比较运算符来比较数据项.另外,有一个test 命令也可以用来进行测试.让我们 ...
- 可以在shell脚本中使用哪些类型的变量?
在shell脚本,我们可以使用两种类型的变量: 系统定义变量 用户定义变量 系统变量是由系统系统自己创建的.这些变量通常由大写字母组成,可以通过“set”命令查看. 用户变量由系统用户来生成和定义,变 ...
随机推荐
- endnote X7 加入文献
endnote可以管理文献,并且在word中方便的添加参考文献. 1.加入文献: 2.导入以后可以创建自己的group,然后把导入的参考文献拖到group里,这样方便在插入参考文献的时候用group名 ...
- HDU-1256-画8
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1256 这题做的我好苦,开始题目理解错了,一直都不对,仔细看题,别急,慢慢来,别紧张, 难度到不大,但题 ...
- 用c3m自动生成的化学机理文件导入mfix里需要注意的一些问题
1. 首先是类似这种写法: Species_g(1) = "CH4" Species_Alias_g(1) = "CH4" 可能会报错,写在一行可能就好了,如: ...
- TTP 错误 404.3 - Not Found 由于扩展配置问题而无法提供您请求的页面。如果该页面是脚本,请添加处理程序。如果应下载文件,请添加 MIME 映射。
解决办法一: 控制面板->打开或关闭windows功能->Internet信息服务->万维网服务->应用程序开发功能. 勾选上“.net扩展性”和“ASP.NET”,保存后,重 ...
- Spring MVC DispatcherServlet绑定多种URL
需要学习的内容: http://my.oschina.net/shishuifox/blog/215617 当前的处理方式,在web.xml中配置: <servlet> <servl ...
- lufylegend库 LGraphics
lufylegend库 LGraphics <!DOCTYPE html> <html lang="en"> <head> <meta c ...
- Java 导出Excel的各种尝试
最近的一个项目比较忙,一直没时间过来跟新博客.今天过来分享一下在此项目中遇到的一个小问题:导出Excel:相信导出Excel这个功能是特别常见的,也有很多的方式.好了,不多说了,直接说说自己遇到的各种 ...
- java工程打包成jar包,并且解压lib里的jar包
在我们开发完java工程部署时,有时不需要web容器,为了方便部署有时候需要打成jar包. 这里介绍2种Eclipse打jar包的方式, 方式一.工程引用的jar包打在lib目录下 1.工程上右键,E ...
- ProjectManager Beta 2 项目管理器发布
上次载Alpha阶段有一个可用版本Alpha 8也在这个博客发布了,传送:http://www.cnblogs.com/deali/p/ProjectManager.html ProjectManag ...
- [html] 学习笔记-Canvas使用路径
想要绘制其他图形,需要使用路径,使用路径包含4个步骤,开始创建路径.创建图形的路径.路径创建完成后关闭路径.设定绘制样式,之后就可以调用绘制方法绘制路径了. 1.绘制圆形 <!DOCTYPE h ...