1 Linux操作系统Shell
1.1 Shell脚本
当命令不在命令行中执行,而是从一个文件中执行时,该文件就称为 Shell 脚本。
注意:
Shell脚本通常以.sh作为后缀名,但不是必须的。
Shell 脚本是以行为单位的,在执行脚本的时候会分解成一行一行依次执行。
Shell脚本是纯文本文件
, Shell 是一种功能强大的解释型编程语言
1.2 Shell脚本成分
1.2.1 Shell变量
定义变量时,变量名不加美元符号($)
变量名和等号之间不能有空格,这和其它编程语言不一样,同时,变量名的命名须遵循的规则:
<1> 首个字符必须为字母(a-z,A-Z)
<2>中间不能有空格,可以使用下划线(_)
<3>不能使用标点符号
<4>不能使用bash里面的关键字(例如:cp)
1.2.2 输入输出
1、输入
变量赋值
例如:name=1
从标准输入读取
read
例如:echo –e “what’s your name: c”
read name
echo “my name is $name”
2、输出
echo(常用)
1.2.3 Read
read:接收标准输入(键盘)的输入
例如:
#!/bin/bash //把下面的命令交给/bin下的bash执行 #The use of the read method //注释read的用法 echo -n "Enter your name:" //-n :不换行显示 read name //从键盘输入 echo "hello $name,welcome to my family" //显示信息
以上命令可以用-p进行浓缩(简写)
read -p "Enter your name:" name // -p:显示提示信息 ,read后的变量只有name echo "hello $name,welcome to my family"
1.2.4 通配符
通配符是系统level的,通配符多用在文件名上,比如查找find,ls,cp,等等
在日常的 Linux 使用中,有很多时候可能需要一次对多个文件系统对象执行单一操作(比如 rm)。在这些情况下,在命令行中输入许多文件通常让人感到厌烦:
$ rm file1 file2 file3 file4 file5 file6 file7
file8
为了解决这个问题,可以利用 linux 内置的通配符支持。这种支持也叫做“globbing”(由于历史原因),允许通过使用通配符模式一次指定多个文件。Bash 和其它 Linux 命令将通过在磁盘上查找并找到任何与之匹配的文件来解释这种模式。因此,如果在当前工作目录中,有从 file1 到 file8 的文件,那么可以输入下面的命令来删除这些文件:
$ rm file[1-8]
或者,如果只想要删除文件名以 file 开头的所有文件,可以输入:
$ rm file*
或者,如果想要列出 /etc 中以 g 开头的所有文件系统对象,可以输入:
$ ls -d /etc/g*
现在,如果指定了没有任何文件系统对象与之匹配的模式,会怎么样呢?在下面的示例中,我们试图列出 /usr/bin 中以 asdf 开头并且以 jkl 结尾的所有文件:
$ ls -d /usr/bin/asdf*jkl
这里是对所发生情况的说明。通常,当我们指定一种模式时,该模式与底层系统上的一个或多个文件匹配,bash 以空格隔开的所有匹配对象的列表来替换该模式。但是,当模式不能找到匹配对象时,bash 将不理会参数、通配符等等,保留原样。因此,当“ls”不能找到文件 /usr/bin/asdf*jkl 时,它会报错。此处的有效的规则是:glob 模式只在与文件系统中的对象匹配时才可以进行扩展。
通配符语法:*
* 将与零个或多个字符匹配。这就是说“什么都可以”。例子:
* /etc/g* 与 /etc 中以 g 开头的所有文件匹配。
* /tmp/my*1 与 /tmp 中以 my 开头,并且以 1 结尾的所有文件匹配。
通配符语法:?
? 与任何单个字符匹配。例子:
* myfile? 与文件名为 myfile 后跟单个字符的任何文件匹配。
* /tmp/notes?txt 将与 /tmp/notes.txt 和 /tmp/notes_txt 都匹配,如果它们存在。
通配符语法:[]
该通配符与 ? 相似,但允许指定得更确切。要使用该通配符,把您想要匹配的所有字符放在
[] 内。结果的表达式将与
[] 中任一字符相匹配。您也可以用
- 来指定范围,甚至还可以组合范围。例子:
* myfile[12] 将与
myfile1 和
myfile2 匹配。只要当前目录中至少有一个这样的文件存在,该通配符就可以进行扩展。
* [Cc]hange[Ll]og 将与
Changelog、ChangeLog、changeLog
以及 changelog
匹配。您可以看到,与大写形式的变形匹配时,使用括弧通配符很有用。
* ls /etc/[0-9]* 将列出
/etc 中以数字开头的所有文件。
* ls /tmp/[A-Za-z]* 将列出
/tmp 中以大写字母或小写字母开头的所有文件。
通配符语法:[!]
除了不与括弧中的任何字符匹配外,[!]
构造与 [] 构造类似,只要不是列在 [! 和 ] 之间的字符,它将与任何字符匹配。例子:
* rm myfile[!9] 将删除除
myfile9 之外的名为
myfile 加一个字符的所有文件。
1.3 Shell脚本编码规范
1、以#!开头:通知系统用哪种解释器执行脚本
#!/bin/bash(常用)
#!/bin/ksh
注:ksh在unix上使用较多;bash在linux上使用较多
2、注释
以#开头的行就是注释,会被注释器忽略。
1.4 Shell脚本的建立与执行
1、Shell脚本的建立
使用文本编辑器编辑脚本文件
vi test.sh
为脚本文件添加可执行权限
chmod +x test.sh
2、Shell脚本的执行
在子shell中执行
bash test.sh
sh test.sh
例如:
注:PATH 环境变量的默认值不包含当前目录,若脚本文件在当前目录,应使用 ./script-file(./代表当前目录)
例如:./ test.sh
1.5 Shell脚本调试
1、sh –x 脚本名
该选项可以使用户跟踪脚本的执行,此时 shell 对脚本中每条命令的处理过程为:先执行替换,然后显示,再执行它。
shell 显示脚本中的行时,会在行首添加一个加号 “ + ”
2、sh –v 脚本名
在执行脚本之前,按输入的原样打印脚本中的各行
3、sh –n 脚本名
对脚本进行语法检查,但不执行脚本。如果存在语法错误,shell 会报错,如果没有错误,则不显示任何内容。
1.6 Shell脚本类型
1、交互式脚本
脚本可以读取用户的输入, 实时向用户反馈信息(输出某些信息)
这样的脚本更灵活, 每次执行时的参数可由用户动态设定
用户界面更友好,但不适用于自动化任务(如cron任务)
简单的来说就是:交互式模式就是shell等待你的输入,并且立即执行你提交的命令
2、非交互式脚本
不需要读取用户的输入, 也不用向用户反馈某些信息
每次执行都是可预见的, 因为它不读取用户输入, 参数是固定的
可以在后台执行
简单来说:shell不与你进行交互,而是读取存放在文件中的命令,并且执行它们。当它读到文件的结尾,shell也就终止了。
1.7 流程控制语句
1.7.1 IF
if 语句通过关系运算符判断表达式的真假来决定执行哪个分支。Shell 有三种语句:
if …fi语句
if ... else ... fi 语句;
if ... elif ... else ... fi 语句。
1、 if … fi语句
格式:
if 【条件表达式】
then
语句块
fi
如果条件表达式返回true,那么then后的语句块将被执行,如果返回false,不会执行任何语句
2、if ... else ... fi 语句
格式:【条件表达式】
then
语句块1
else
语句块2
fi
3、if ... elif ... fi 语句
1.7.2 While
while expr //执行expr
do //若expr的退出状态为0,进入循环,否则退出while
commands //循环体
done //循环结束标志,返回循环顶部
1.7.3 FOR
for 变量 in 值1 值2...
do
代码
Done
1.8 作业
- 监控内存,超过20%后,报警且保存到mem.log文件
#!/bin/bash #This is monitor the usage of mem #And if the usage rate exceeds 20%,please check it #Get the Total and used Total=`free -m | sed -n '2p' | awk '{ print $2 }'` Used=`free -m | sed -n '2p' | awk '{ print $3 }'` #Get the usage usage=`echo "$Used * 100 /$Total" | bc` #whether rate is exceeds than 20% if [ $usage -ge 20 ] then echo -n `date "+20%y-%m-%d %H:%M:%S"` >> /home/wuzhenru/mem.log echo -e " Waring: The usage of MEM is $usage%, please check it." >> /home/wuzhenru/mem.log else echo -n `date "+20%y-%m-%d %H:%M:%S"` >> /home/wuzhenru/mem.log echo -e " The usage of MEM is OK !" >> /home/wuzhenru/mem.log fi
悬镜占用内存总和统计,且当总和大于2%时,将对应的时间及内存量写在日志中。
执行结果:
Jll.log