Shell编程
【学习笔记】
认识Shell脚本
Shell 脚本(Shell Script)与Windows/DOS 下的批处理相似,也就是将各类命令预先放入其中,方便一次性执行的一个程序文件,主要用以方便管理员进行设置或者管理。但是Shell 脚本比Windows 下的批处理更强大,比用其他编程程序编辑的程序效率更高,毕竟它使用了Linux/UNIX 下的命令。
Shell脚本的基本语法
开头
可以使用任何一种编辑器来编辑
gedit、kedit、emacs、vi等等
#!/bin/bash #表示系统用bash来执行程序
……
编辑该文件后不能立即执行它,需给文件设置可执行程序权限
chmod [权限] [文件名] #添加可执行程序权限(如权限777)
然后可以使用./[filename]来运行程序
执行
有三种方法
方法一:
./test.sh
方法二:
bash test.sh
方法三:
export PATH=/home/pyma/Shell:$PATH #添加到环境变量中
./test.sh #执行
注释
在进行Shell 编程时,以#开头的句子表示注释,直到这一行的结束
变量
用户自定义变量
(1)首个字母必须位字母(az,AZ)或者下划线(_)
(2)中间不能有空格,可以使用下划线(_)
(3)不能使用其他标点符号
变量赋值
变量名=值 #DATA=2
这里要注意:变量赋值时,等号两边都没有空格。在Shell 编程中通常使用全大写变量,方便识别。
从右向左赋值
#!/bin/bash
Y=y
X=$Y
echo X=$X
变量调用
要取用一个变量的值,只需在变量名前面加一个$
#!/bin/bash
# 对变量赋值:
VAR="hello world" #等号两边均不能有空格存在
# 打印变量VAR 的值:
echo "VAR is:" $VAR
用花括号区分变量和字母
可以使用花括号来告诉Shell 我们要打印的是num 变量
num=2
echo "this is the ${num}nd"
unset 命令可删除变量的赋值
Z=hello
echo $Z
#输出会打印hello
#在命令行里边输入
unset Z
#再打印Z将会为空
位置参数及命令行参数
位置参数的值可以用$N 得到,N 是一个数字,如果为1,即$1
$0 与键入的命令行一样,包含脚本文件名
$1,$2,…,$9 分别包含第一个到第九个命令行参数
预定义变量
预定义变量是在Shell 一开始时就定义了的变量,所有预定义变量都是由$符和另一个符号组成的。
·$#:包含命令行参数的个数。
·$@:包含所有命令行参数:“$1,$2,…,$9”。
·$?:包含前一个命令的退出状态,正常退出返回0,反之为非0 值。
·$*:包含所有命令行参数:“$1,$2,…,$9”。
·$$:包含正在执行进程的ID 号。
环境变量
环境变量用于所有的用户进程。在Linux 中,登录进程称为父进程,Shell 中执行的用户程序均称为子进程。环境变量可以在命令行中设置,但用户注销时这些值将丢失,因此最好在$HOME/目录下的.profile 中定义,传统上环境变量均为大写。
常见环境变量
·HOME: /etc/passwd 文件中列出的用户主目录。
·IFS:内部字段分隔符(Internal Field Separator), 默认为空格,tab 及换行符。
·PATH :shell 搜索路径。
·PS1,PS2:默认提示符($)及换行提示符(>)。
·TERM:终端类型,常用的有vt100、ansi、vt200、xterm 等。
·HISTSIZE:保存历史命令记录的条数。
·LOGNAME:当前用户登录名。
·HOSTNAME:主机名称,若应用程序要用到主机名的话,一般是从这个环境变量中取得。
·SHELL:当前用户用的是哪种Shell。
·LANG/LANGUGE:和语言相关的环境变量,使用多种语言的用户可以修改此环境变量。
·MAIL:当前用户的邮件存放目录。
·TMOUT :用来设置脚本过期的时间,比如TMOUT=3,表示该脚本3 秒后过期。
·UID : 已登录用户的ID。
·USER :显示当前用户名字。
·SECONDS:记录脚本从开始到结束耗费的时间。
设置环境变量
·echo:显示指定环境变量。
·export:设置新的环境变量。
·env:显示所有环境变量。
·set:显示所有本地定义的Shell 变量。
·unset:清除环境变量。
export PATH=[代码所在路径]:$PATH
注意:一定要加$PATH(表示应用PATH变量以前的内容),否则,之前的环境变量会被覆盖掉
Shell程序和语句
说明性语句
说明性语句即注释行
功能性语句
1、键盘读入变量值
存放目录的变量为DIRECTORY,其读入语句为read DIRECTORY
#!/bin/bash
echo “please input name of directory”
read DIRECTORY
ls $DIRECTORY -a
2、算数运算命令
算术运算命令expr 主要用于进行简单的整数运算,包括加(+)、减(-)、乘(*)、整除(/)和求模(%)等操作。
#!/bin/bash
echo "please input tow numbers:"
read var1
read var2
add=`expr $var1 + $var2`
sub=`expr $var1 - $var2`
mul=`expr $var1 \* $var2`
div=`expr $var1 / $var2`
mod=`expr $var1 % $var2`
echo '$var1+$var2'=$add
echo '$var1-$var2'=$sub
echo '$var1*$var2'=$mul
echo '$var1/$var2'=$div
echo '$var1%$var2'=$mod
【注意】表达式z=expr $x + $y
中的符号“”为键盘左上角的“
”键,即反引号
3、test命令
(1)字符串测试
s1 = s2 测试两个字符串的内容是否完全一样
s1 != s2 测试两个字符串的内容是否有差异
-z s1 测试s1 字符串的长度是否为0
-n s1 测试s1 字符串的长度是否不为0
(2)整数测试
a -eq b 测试a 与b 是否相等
a -ne b 测试a 与b 是否不相等
a -gt b 测试a 是否大于b
a -ge b 测试a 是否大于等于b
a -lt b 测试a 是否小于b
a -le b 测试a 是否小于等于b
(3)文件测试
-d name 测试name 是否为一个目录
-f name 测试name 是否为普通文件
-L name 测试name 是否为符号链接
-r name 测试name 文件是否存在且为可读
-w name 测试name 文件是否存在且为可写
-x name 测试name 文件是否存在且为可执行
-s name 测试name 文件是否存在且其长度不为0
f1 -nt f2 测试文件f1 是否比文件f2 更新
f1 -ot f2 测试文件f1 是否比文件f2 更旧
4、tput命令
tput 命令主要用于设置终端工作模式,或读出终端控制字符。tput 命令与终端控制代码数据库terminfo 相连, 根据Shell 环境变量TERM 的值, 读出这种终端的指定功能控制代码
结构性语句
1、条件测试语句
if 表达式
then 命令表1
else 命令表2
fi
#如果表达式为真, 则执行命令表1 中的命令, 并退出if 语句;否则执行命令表2 中的语句, 再退出if 语句
2、多路分支语句
多路分支语句case 用于多重条件测试, 语法结构清晰自然
case 字符串变量 in #(case 语句只能检测字符串变量)
模式1) #(各模式中可用文件名元字符,以右括号结束)
命令表1
;; #(命令表以单独的双分号行结束,退出case 语句)
模式2)
命令表2
;;
……
模式n) #(模式n 常写为字符* 表示所有其他模式)
命令表n
;; #(最后一个双分号行可以省略)
esac
3、循环语句
循环体由语句括号do 和done 来限定
(1)for循环
for 变量名 in 单词表
do
命令表
done
(2)while循环
while 命令或表达式
do
命令表
done
4、循环控制语句
Shell 脚本中,循环控制语句有break 和continue。break n 表示跳出n 层;continue 语句表示马上转到最近一层循环语句的下一轮循环上,continue n 则转到最近n 层循环语句的下一轮循环上。
#!/bin/bash
for i in 1 2 3 4 5 6 7 8 9 10
do
if [ $i -eq 5 ]
then
continue
fi
echo "$i"
done
Shell函数
在Shell 程序中, 常常把完成固定功能、且多次使用的一组命令(语句)封装在一个函数里,每当要使用该功能时只需调用该函数即可。
函数在调用前必须先定义,即在顺序上函数说明必须放在调用程序的前面。
调。
调用程序可传递参数给函数, 函数可用return 语句把运行结果返回给调用程序。
函数只在当前Shell 中起作用, 不能输出到子Shell 中。
函数定义格式
方式一:
function_name ( )
{
command1
……
commandn
}
方式二:
function function_name ( )
{
command1
……
commandn
}
函数调用格式
方式一:
value_name=`function_name [arg1 arg2 …]` #函数的所有标准输出都传递给了主程序的变量。
方式二:
function_name [arg1 arg2 …]
echo $? # $?表示获取函数的返回的状态。
Shell脚本调用
在Shell 脚本的执行过程中,支持调用另一个Shell 脚本,调用的格式为
脚本名
注意:
(1)在Linux 编辑中命令区分大小写字符;
(2)在Shell 语句中加入必要的注释,以便以后查询和维护,注释以#开头;
(3)对Shell 变量进行数字运算,使用乘法符号“*”时,要用转义字符“\”进行转义;
(4)由于Shell 对命令中多余的空格不进行任何处理,因此程序员可以利用这一特性调整程序缩进,达到增强程序可读性效果;
(5)在对函数命名时最好能使用有含义且容易理解的名字,即使函数名能够比较准确地表达
函数所完成的任务,同时建议对于较大的程序要建立函数名和变量命名对照表。
选自华清远见《嵌入式操作系统》