王军老师《Linux系统命令及shell脚本实践指南》的读书笔记,shell编程基础语法
shell概述:
Shell不只是一种解释器(在用户和系统间起着桥梁的作用),还是一种编程工具,称为脚本语言。与编译型语言(比如C/C++/Java等)不同,脚本语言又被称作解释型语言,这种语言经过编写后不需要做任何编译就可以运行。
概述:
“#!/bin/bash” 一个脚本开始的标记,它是在告诉系统执行这个文件需要使用某个解释器,后面的就是指明了解释器的具体位置。
运行方式:
bash:实际上,如果使用这种方式来运行脚本,该脚本中的第一行“#!/bin/bash”就可以不需要了,因为直接bash一个文件就是指定了使用Bash Shell来解释脚本内容。 |
脚本加上可执行权限,然后使用“./”来运行,它代表运行的是当前目录下的HelloWorld.sh脚本,如果采用这种方式而脚本没有可执行权限则会报错。 |
编程插件工具
Bashdb:这是一个类似于GDB的脚本调试软件,小巧而强大,具有设置断点、单步执行、观察变量等功能。下载使用:http://sourceforge.jp/projects/sfnet_bashdb, |
Shell内建命令
就是由Bash自身提供的命令,而不是文件系统中的某个可执行文件。
alias可用于创建命令的别名,若直接输入该命令且不带任何参数,则列出当前用户使用了别名的命令。 |
unalias:删除当前Shell环境中的别名 |
declare、typeset:两个命令都是用来声明变量的,作用完全相同。 |
echo用于打印字符,典型用法是使用echo命令并跟上使用双引号括起的内容(即需要打印的内容),该命令会打印出引号中的内容,并在最后默认加上换行符。使用-n参数可以不打印换行符。 |
break:break后可以跟一个数字n,代表跳出n层循环,n必须大于1,如果n比当前循环层数还要大,则跳出所有循环。 |
continue:停止当前循环,并执行外层循环(for、while、until或者select)的下一次循环。continue后可以跟上一个数字n,代表跳至外部第n层循环。n必须大于1,如果n比当前循环层数还要大,将跳至最外层的循环。 |
exit:在当前Shell中直接运行该命令的后果是退出本次登录。在Shell脚本中使用exit代表退出当前脚本。 |
export:用户登录到系统后,系统将启动一个Shell,用户可以在该Shell中声明变量,也可以创建并运行Shell脚本,通常,如果说登录时的Shell是父Shell,则在该Shell中运行的Shell是该Shell的子Shell。当子Shell运行完毕后,将返回执行该脚本的父Shell。从这种意义上来说,用户可以有许多Shell,每个Shell都是由父Shell创建的。 在父Shell中创建变量时,这些变量并不会被其子Shell进程所知,也就是说变量默认情况下是“私有”的,或称“局部变量”。使用export命令可以将变量导出,使得该Shell的子Shell都可以使用该变量,这个过程称为变量输出。 |
read: 从标准输入读取一行到变量。read是按行读取的,用回车符区分一行,你可以输入任意文字,它们都会保存在变量REPLY中。 |
|
Linux操作系统包括3种不同类型的进程,第一种是交互进程,这是由一个Shell启动的进程,既可以在前台运行,也可以在后台运行;第二种是批处理进程,与终端没有联系,是一个进程序列;第三种是监控进程,也称系统守护进程,它们往往在系统启动时启动,并保持在后台运行。
脚本“位置参数”的概念。假设一个脚本在运行时可以接受参数,那么从左到右第一个参数被记作$1,第二个参数为$2,以此类推,第n个参数为$N。所有参数记作$@或$*,参数的总个数记作$#,而脚本本身记作$0。
基本语法
unset: 取消变量指的是将变量从内存中释放, 还可以跟上函数名以取消函数 |
位置参数”,位置参数的命名简单直接,比如,脚本本身为$0,第一个参数为$1,第二个参数为$2,第三个为$3,以此类推。当位置参数的个数大于9时,需要用${}括起来标识,比如说第10个位置参数应该记为${10}。另外,$#表示脚本参数的个数总和,$@或$*表示脚本的所有参数。 |
$?永远是上一个命令的返回值,所以要查看某个命令的返回值必须在运行该命令后立即查看$?。 |
|
数组
定义:declare:用命令定义数组Array,并将第一个元素赋值为0,第二个元素赋值为1,其下标(也就是索引)则分别是0和1(记住数组的索引是从0开始计数的) declare-a Name=('john' 'sue') |
赋值:Name=('john' 'sue') Score=([3]=3 [5]=5 [7]=7) |
取值:${数组名[索引]} echo ${Name[1]} 取全部值:echo ${Array[@]} echo ${Array[*]} |
数组长度:echo ${#Array[@]} |
数组截取:取出第二个元素从第0个字符开始连续5个字符 [root@localhost ~]# echo ${Array[2]:0:5} Hello |
数组连接:Conn=(${Array[@]} ${Name[@]}) |
替换元素:Array=(${Array[@]/HelloWorld/HelloJohn}) |
运算符
Shell中的运算符主要有比较运算符(用于整数比较)、字符串运算符(用于字符串测试)、文件操作运算符(用于文件测试)、逻辑运算符、算术运算符、位运算符、自增自减运算符等。
算数运算符:指的是加、减、乘、除、余(%)、幂(**)等常见的算术运算,以及加等、减等、乘等、除等、余等复合算术运算。要特别注意的是,Shell只支持整数计算,也就是所有可能产生小数的运算都会舍去小数部分。 |
位运算有左移运算(<<)、右移运算(>>)、按位与(&)、按位或(|)、按位非(~)、按位异或(^)等运算 |
自增自减:包括前置自增、前置自减、后置自增、后置自减等。前置自增或前置自减操作会首先修改变量的值,然后再将变量的值传递出去;后置自增或后置自减则会首先将变量的值传递出去,然后再修改变量的值。 |
$[]和$(())类似,可用于简单的算术运算 echo $[5%2] |
expr命令也可用于整数运算。和其他算术运算方式不同,expr要求操作数和操作符之间使用空格隔开(否则只会打印出字符串),所以特殊的操作符要使用转义符转义(比如*)expr 2 \* 2 |
而Linux下的bc正是这样一款专门用于高精度计算的工具。 |
特殊字符
* | *代表任意长度的字符串 |
? | 匹配任一单个字符 |
[] | 匹配其中的任意一个字符,比如[abc]代表匹配a或者b或者c |
引号 | 单引号又叫称“全引用”或“强引用”;双引号又称“部分引用”或“弱引用” |
# | 注释符 |
大括号 | 引用变量原型,又叫变量扩展${VAR}引用 |
测试方法
test expression 测试结构 |
#文件测试方法一 test file_operator FILE #文件测试方法二 [ file_operator FILE ] test expression |
字符串比较主要有等于、不等于、大于、小于、是否为空等测试 |
逻辑测试用于连接多个测试条件,并返回整个表达式的值。逻辑测试主要有逻辑非、逻辑与、逻辑或3种
|
判断
if expression; then command fi |
if expression; then command else command fi |
case VAR in var1) command1 ;; var2) command2 ;; var3) command3 ;; ... *) command ;; esac |
循环:
for VARIABLE in (list) do command done |
for VARIABLE do command done |
for ((i=1; i<=10; i++)) do echo-n "$i " done e |
while expression do command done |
until采用的是测试假值的方式,当测试结果为假时才继续执行循环体,直到测试为真时才停止循环。 until expression do command done |
select是一种菜单扩展循环方式,其语法和带列表的for循环非常类似,select有判断用户输入的功能,所以select经常和case语句合并使用 do command done |
函数:
函数是Shell脚本中自定义的一系列执行命令,一般来说函数应该设置有返回值(正确返回0,错误返回非0。对于错误返回,可以定义返回其他非0正值来细化错误,这将在下一节中详细描述)
#shell中的函数定义 #其中function为关键字,FUNCTION_NAME为函数名 function FUNCTION_NAME(){ command1 #函数体中可以有多个语句,不允许有空语句 command2 ... }
|
#省略关键字function,效果一致 FUNCTION_NAME(){ command1 command2 ... } |
函数库
cat lib01.sh_ checkFileExists(){ if [-f $1 ]; then echo "File:$1 exists" else echo "File:$1 not exist" fi } |
调用: [root@localhost ~]# . /PATH/TO/LIB #使用source命令 [root@localhost ~]# source /PATH/TO/LIB |
cat callLib01.sh #!/bin/bash source ./lib01.sh #引用当前目录下的lib01.sh函数库 _checkFileExists /etc/notExistFile #调用函数库中的函数 _checkFileExists /etc/passwd
#执行结果 [root@localhost ~]# bash callLib01.sh File:/etc/notExistFile not exist File:/etc/passwd exists |
重定向:
“重定向”,就是将原本应该从标准输入设备(键盘)输入的数据,改由其他文件或设备输入;或将原本应该输出到标准输出设备(显示器)的内容,改而输出到其他文件或设备上。
标准输入(stdin)、标准输出(stdout)、标准错误输出(stderr),分别用文件标识符0、1、2来标识。如果要为进程打开其他的输入输出,则需要从整数3开始标识。默认情况下,标准输入为键盘,标准输出和错误输出为显示器。
重定向符号: