wofaLinux Shell编程自编讲义
一、Shell脚本基础
Shell是用户与Linux操作系统沟通的桥梁。用户既可以输入命令执行,又可以利用 Shell脚本编程,完成更加复杂的操作。Shell脚本是一种解释型语言,在执行脚本时,解释器逐行的扫描代码并执行,与编译型语言不同。
Linux的Shell种类众多,常见的有:Bourne Shell(/usr/bin/sh或/bin/sh)、Bourne Again Shell(/bin/bash)、C Shell(/usr/bin/csh)、Korn Shell(/usr/bin/ksh)、Shell for Root(/sbin/sh),等等。由于易用和免费,且作为大多数Linux系统默认的Shell,Bourne Again Shell的使用是最广泛的。Bourne Shell和Bourne Again Shell的语法非常相似,一般情况下可以通用。
编写Shell脚本的格式是固定的,如下:
第一行:#!/bin/sh 或 #!/bin/bash
注:(第一行可以省略,省略后为系统的默认配置,Ubuntu和RedHat9下初始为/bin/bash,可以在首选项中修改)
第二行及以后 Your commands go here
首行中的符号“#!”告诉系统其后路径所指定的程序即是解释此脚本文件的Shell程序。在程序编写完成之后,用“chmod +x 文件名”命令将文件属性设置为“可执行”,如果首行没有这句话,在执行脚本文件的时候,将因不到解释器而发生错误。
编辑完毕,将脚本存盘为filename.sh,文件名后缀sh表明这是一个shell脚本文件。执行脚本的时候,要先将脚本文件的属性改为可执行的:
chmod +x filename.sh
后续的部分就是主程序,Shell脚本像高级语言一样,也有变量赋值,也有控制语句。除第一行外,“#”字符之后的语句为Shell的注释。在解释器扫描注释时,会跳过“#”之后的所有内容,直到一行的结尾,与C++的“//”是一个道理。强烈建议在程序中使用注释,如果您使用了注释,那么即使相当长的时间内没有使用该脚本,您也能在很短的时间内明白该脚本的
作用及工作原理。
二、变量与函数
Shell的变量分为两种:本地数据区变量(也称本地变量)、用户环境区变量(也称环境变量) (函数也相应分为两种,后面章节讲述)。在Shell工作机制中,存在一个子shell的概念,子shell是登录shell(父shell)为了运行程序而建立的一个全新的shell,这个全新的shell将会使用自己的本地变量,以及继承自父shell的环境变量,父shell的本地变量对子shell隐藏,而且,子shell 和父shell的变量在命名上不会有任何冲突。当子shell需要继承父shell的变量时,可以使用export命令将变量作为环境变量复制给子shell(类似于C++的值传递),子shell可以修改和存取它,但是这种修改父shell看不到,也就是说,子shell无法修改父shell的变量。环境变量的上述特性对于由子shell产生的后继子shell也是如此。export可以在变量赋值之后用,也可以在变量赋值之前用。若需要修改根shell的变量,唯一的办法是在/etc/rc.local(RedHat为/etc/init.d/)中写入脚本语句,并重启Linux,(/etc/rc.local相当于autoexec.bat,为Linux系统启动时自动执行的脚本)。
env命令用于显示所有环境变量及其取值(env为外部命令);set及declare命令用于显示
所有本地变量、环境变量及取值,以及所有局部函数和环境函数及其函数体;declare –x “变量名/函数名”命令用于将本地数据区中的变量复制到用户环境区,亦即:将本地变量转化为环境变量,功能与export “变量名/函数名”相同。在某些Linux下,将环境变量转化为局部变可以用declare +x “变量名/函数名”命令。declare –f命令显示所有局部函数、环境函数的名称和函数体,declare –r “变量名”或readonly “变量名”将变量配置为只读(只读变量不能够修改,不能够unset),变量无法解除只读。export命令用于显示所有变量(不包括函数)的属性,前缀显示“declare - -”的是本地变量,“declare -x”的是环境变量。在POSIX标准下(使用set –o posix设置),export命令用于显示所有环境变量(不包括函数)的属性,与declare –x命令相同,前缀显示“export”的是环境变量。
注:shell脚本是一种弱类型解释型语言,使用变量的时候无需声明其类型,任何变量的类型本质上都为字符串,在不同的地方有不同的解释。新的变量会在本地数据区分配内存进行存储(属于本地变量),这个变量归当前的shell所有,任何其他进程都不能访问本地变量,包括子shell。
变量的引用就是将变量简单地替换为字符串,引用方式有三种:
$变量名 或 {$变量名} 或 ”$变量名”
注:$’变量名’ 或 $”变量名” 不能引用变量
变量的声明和赋值的方式有三种:
第一种: 变量名=”字符串” #等号左右都不能有空格,字符串中如果出现了某个变量的引用,则以该变量值(所代表的字符串)替换,用法与C类似。
第二种:变量名=’字符串’ #等号左右都不能有空格,单引号内字符串忠实于其字面值。
第三种: 变量名=字符串 #等号左右都不能有空格,字符串中不能有空格,如果字符串中出现空格,则变量赋值为第一个空格前面的部分,第一个空格之后第二个空格之前的字符串被shell执行,第二个空格之后的字符串全部被忽略掉。
注:“\”为转义字符
例:echo "I am saying: \"Good morning!\""
输出:I am saying: " Good morning!"
例:echo ’I am saying: \"Good morning!\"’#单引号内字符串忠实于其字面
输出:I am saying: \" Good morning!\"
删除变量的方法为:
unset 变量名 #必须是变量名,不能是变量名的引用
引用带默认值的变量方式:
${变量名:-字符串} 如果变量已经赋值,则使用该变量值。如果变量为空,则使用字符串作为值。
例:
unset a
echo ${a:-1234} #输出1234
echo $a #输出为空
a=4321
echo ${a:-1234} #输出4321
echo $a #输出4321
${变量名:=字符串} 如果变量已经赋值,则使用该变量值。如果变量为空,则将字符串赋值到变量中,并使用字符串作为值。
unset a
echo ${a:=1234} #输出1234
echo $a #输出1234
a=4321
echo ${a:=1234} #输出4321
echo $a #输出4321
如果需要检验变量是否为空,如果为空的话则显示错误信息,则使用下面的表达式:DOIT博客3[/~ Y_l_w9v;^f4K:|_Q
${变量名:?}DOIT博客_m)U+P:N_r*P_d
如果需要显示自己定义的信息,则如下:DOIT博客_M p3\+z1C_v
${变量名:?字符串}
将变量作为数学表达式使用,有三种方法,第一种是用双括号,第二种是用单中括号,第三种是使用expr,expr指令在实际中用的很少,多用第一种方式替代。数学运算符号有:+、-、*、/、%、~等等。
例:
a=1024
echo $((1024+1)) #输出1025
echo $[1024+1] #输出1025
echo $(($a+1)) #输出1025
echo $[$a+1] #输出1025
b=$(($a+1)) #将1025赋到b中
echo $b #输出1025
expr 1024 + 1 #输出1025
expr $a + 1 #输出1025,加号前后必须有空格
一个外部命令执行后的输出可以替换这个命令本身,甚至可以将输出值赋到一个变量中,其语法如下:
`命令` 或者 $(命令)
注:$(命令)在sh下不支持,只能在bash或ksh中使用
例:echo $(date)
输出:Sat Feb 20 22:06:20 CST 2010
echo `date`
输出:Sat Feb 20 22:06:20 CST 2010
将变量当作数字使用的方法:
declare –i 变量名
例:
unset a
declare –i a
echo $a #输出为空
a=123
echo $a #输出123
a=123abcdef231
echo $a #输出123
a=abcdef
echo $a #输出0
unset a
a=abcdef
echo $a #输出abcdef
附:Shell的默认变量有:
$#:保存程序命令行参数的数目
$1、$2、$3... $n: 保存所有输入的命令行的第n个参数
$?:保存前一个命令的返回码
$1、$2、$3... $n: 保存所有输入的命令行的第n个参数
$?:保存前一个命令的返回码
linux循环执行命令脚本$0:保存程序名
$*:以("$")的形式保存所有输入的命令行参数
$@:以("$1""$2"...)的形式保存所有输入的命令行参数
$$:本shell的PID
$_:前一个执行的命令
$*:以("$")的形式保存所有输入的命令行参数
$@:以("$1""$2"...)的形式保存所有输入的命令行参数
$$:本shell的PID
$_:前一个执行的命令
$PS1: Shell 提示符
Shell的函数分为两种:局部函数、环境函数。
定义函数的方法为:
函数名() #或 “function 函数名()”,仅bash适用,sh不适用
{
语句1
语句2
……
最后一个语句
return 返回值 #无须返回值时可以写“return”或什么都不写
}
每个语句之后都可以加上分号,以接近C语言风格。
默认情况下,所有函数内部声明的变量都是本地全局变量,可以用typeset去声明一个本地局部变量,当函数结束时该本地局部变量消亡。
删除函数的方法为:
unset 函数名
三、条件测试
单目条件测试有两种等价的表示方法:
第一种:test 参数 待测条件
第二种:[ 参数 待测条件 ] #中括号和参数、条件之间一定要有空格
双目条件测试有两种等价的表示方法:
test 待测条件
[ 待测条件 ]
条件测试能够测试字符串(存在与否、是否相等)、数值(大小比较)和文件状态,条件满足则返回0(真),不满足则返回1(假)。
1、 字符串测试参数
单目参数:
无参数:测试字符串是否是非空串
-z:测试字符串是否是空串
-n:测试字符串是否是非空串
注:-n选项在引用变量时必须加上双引号
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论