Linux学习笔记(六)-Shell高级程序设计基础

来源:互联网 发布:qemu ubuntu 编辑:程序博客网 时间:2024/05/29 12:30

Shell高级程序设计基础

一. 关于Shell

  1. shell是一个命令解释器,是介于操作系统kernel与用户之间的一个绝缘层。它也是一种强力的计算机语言,一个shell程序,被称为一个脚本,可以通过将系统调用、公共程序、工具、和编译过的二进制程序粘合在一起来建立应用。
  2. Shell脚本对于管理系统任务和其它的重复工作的例程来说,表现的非常好

二. Vi编辑器的使用
1. Vi编辑器的三种模式
- Command mode 命令模式
- Edit mode 编辑模式
- ex mode 复杂命令模式
这里写图片描述

2 . Vi编辑器常用命令
1、在文件中移动光标 
h:向左移动一个字符  
l:向右移动一个字符  
k:向上移动一行
j:向下移动一行  
^(即Shift+6):移动到当前行的开头处  
$(即Shift+4):移动到当前行的结尾处  
H(大写):使光标移动到屏幕的顶部  
M(大写):使光标移动到屏幕的中间  
L(大写):使光标移动到屏幕的底部  
Ctrl+b:上滚一屏。  
Ctrl+f:下滚一屏。  
Ctrl+d:下滚半屏。  
Ctrl+u: 上滚半屏。  
2、插入文本  
(1)添加:  
●输入a后,在光标的右边插入文本  
●输入A,在一行的结尾处添加文本  
(2)插入:  
●通过在命令模式下输入i,在光标的左边插入文本  
●通过在命令模式下输入I,在行首插入文本  
(3)插入新行:  
●输入o,在当前光标位置下面打开一行  
●输入O,在当前光标位置上面打开一行  
3、撤消更改  
(1)撤消前一个命令:在最后一个命令之后立即输入u来撤消该命令 
(2)重复某个命令:“.”  
(3)撤消对一行的更改:输入U来撤消你对一行所做的所有更改,这个命令只有在你没将光标移动到该行以外时才生效。 
4、删除文本 
(1)删除一个字符: 
●为删除一个字符,需将光标放置在要删除的字符上并输入x 
●为删除光标之前(其左边)的一个字符,需输入X 
(2)删除一个词或词的部分内容: 
●为删除一个词,需将光标放置到该词的开头并输入dw 
●为删除词的部分内容,需将光标放置到该词要保存部分的右边。输入dw来删除该词余下的部分 
(3)删除一行:将光标放置到该行的任意处并输入dd 
(4)删除多行:ndd 
(5)删除行的部分内容:将光标放置到该行要保存部分的右边,并输入D。为删除光标左边的所有内容,须将光标放置到该行要删除部分的右边,并输入d0(d-零)。  
(6)删除到文件的结尾:为删除从当前行到文件结尾的所有内容,需输入dG 
5、复制和移动文本 
●复制一行命令:yy 
●粘贴命令:p 
●移动文本:先将要移动的部分用删除命令删除,然后再粘贴就可以了
●复制指定文件的内容  : r filename 
6、查找一个字符串 
●输入/,并在/后面输入要查找的串,然后按下回车 
●输入“n”跳转到该串的下一个出现处 
●输入“N”跳转到该串的上一个出现处 
7、替换一个字符串 
●在一行内替换头一个字符串old为新的字符串new   :s/old/new   
●在一行内替换所有的字符串old为新的字符串new   :s/old/new/g  
●在两行内替换所有的字符串old为新的字符串new   :#,#s/old/new/g  
●在文件内替换所有的字符串old为新的字符串new   :%s/old/new/g  
●进行全文替换时询问用户确认每个替换需添加c选项   :%s/old/new/gc  
8、设置vi  
●显示行号   :set number  
●取消行号显示   :set nonumber  
●设置显示用户模式   :set showmode  
●设置文件只读   :set readonly
9、退出Vi
这里写图片描述
10、快捷键一览
这里写图片描述

3 . 激活脚本的三种方法

方法一:
- 脚本不必标示为可执行,但必须可读
- Bash在一个子shell中激活脚本

$ cat script1date$ bash script1

这里写图片描述

方法二:
- 用chmod来使脚本可执行,然后像运行命令一样运行脚本
- 脚本将在子shell中运行

$ chmod 755 ./script1$ ./script1

这里写图片描述

方法三:
- 使用.(dot) 或者source命令在当前shell环境中执行脚本
- 例如,为了不重起而让环境变量修改立即生效——可以使用source或者dot命令 (例如 #source /etc/profile)

$ .script1$ source script1

这里写图片描述

注意:在脚本的第一行加入如下语句

#!/bin/bash
  • 脚本将总是在bash中运行,即使用户的默认shell是其它的shell
  • 此时,使用dot在当前的shell中激活shell脚本不再可行了

    4 . Shell脚本参数

    • 1,2,$3 指向每个参数
    • $#表示参数的个数
    • $*表示所有参数的整体
      例如:
      这里写图片描述

    如果有很多参数(例如,文件名),则可以用shift切换参数,例如:
    这里写图片描述

    三. Shell基本编程技术

    1. 条件循环判断语句
      条件语句:
      这里写图片描述
      While do命令
      这里写图片描述
      For循环
      这里写图片描述

    例子:如何写个程序输出/home下所有的不够安全的文件?

for file in  `find /home -perm 777`doecho Dangerous File Permissions on $filedone

2 . 特殊字符$

$# 是传给脚本的参数个数$0 是脚本本身的名字$1 是传递给该shell脚本的第一个参数$2 是传递给该shell脚本的第二个参数$@ 是传给脚本的所有参数的列表$* 是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9$$ 是脚本运行的当前进程ID$? 是显示最后命令的退出状态,0表示没有错误,其他表示有错误

例子:

//看下面脚本执行以后各个变量的意义# touch variable;  vi variable#!/bin/bashecho “number:$#echo "scname:$0"echo "first :$1"echo "second:$2"echo "argume:$@”echo "show parm list:$*"echo "show process id:$$”echo "show precomm stat: $?" //保存退出//赋予脚本执行权限# chmod +x variable//执行脚本# ./variable aa bbnumber:2scname:./variablefirst:aasecond:bbargume:aa bbshow parm list:aa bbshow process id:24544show precomm stat:0

3 . 输入重定向
文件描述符:
这里写图片描述
重定向的例子:
这里写图片描述
这里写图片描述

4 . 标准Shell变量

$:当前shell的PIDPATH:用于搜索可执行程序的路径PS1:主shell提示符PS2:第二shell提示符PWD: 当前工作目录HOME:用户的主目录LANG:用户的语言环境

5 . 命令替换
命令替换是指将命令的标准输出作为值赋给某个变量,bash Shell定义了两种形式进行命令的替换,两种形式的语法格式如下:
方式一: `Linux命令`
方式二: $(Linux命令)
例子:
这里写图片描述
注意:尽管()形式的命令替换是可以嵌套的。
bash Shell中,反引号与$()在处理双反斜线符号时存在区别。

 [root@CentOS6 tmp]#echo \\ [root@CentOS6 tmp]#\            #输出转义符 [root@CentOS6 tmp]#echo `echo \\` [root@CentOS6 tmp]#              #输出空白行 [root@CentOS6 tmp]#echo $(echo \\) [root@CentOS6 tmp]#\            #输出单斜线

6 . 生成审计报告的例子

用法:./Auditfilter ./audit0118.log#!/bin/bash# auditfilterif [ $# != 1 ]  #如果参数个数不为1,则显示当前命令的语法信息提示,并 then  echo “`basename $0` <audit_log>”  #$0显示当前脚本的路径,而basename $0则显示当前脚本的名字  exit 1  #非正常退出fi if [ ! -f $1 ]  #如果参数所指定的文件不存在,则也退出  then   echo "file does not exist"   exit 1 fihost=$(hostname)  #打印出当前的主机名称# extract the date part of the filename for the reportreport=$(basename $1)  #basename $1$1相同echo $report #显示报告的文件名称# filename ie: audit0118.logdate_rep=$(echo $report | sed –e ‘s/audit//g’ -e ‘s/.log//g’)  #  -e多重编辑, 将管道输出中”audit”删除,将”.log”删除。本例中,将留下“0118echo "date is..."echo $date_rep  #结果应为0118mth=$(echo $date_rep | cut -c 1,2) #取出月份,即01echo "month is..."echo $mthday=$(echo $date_rep | cut -c 3,4) #取出日,即18echo "day is..."echo $dayDatex=$day$mth  #重新规划日期的格式# email list herelist="root"mailit2(){sendmail -t <<maydayTo:$listSubject:audit report on $hostContent-Type: text/htmlContent-Transfer-Encoding: 7bit<body><body bgcolor="#C0C0C0">Generated: `date`<br>Date of Audit : $datex<hr><br><pre>$(cat $1)</pre></body>mayday}echo '$1 is...'echo $1# do header and join lines# do header and join lines# filter out# filter outawk '!($1 ==“USER_SU” && $2 ==$10) &&    #为了排除用户su到自己!($1==“USER_SU” && $2==“root” && $9==“su” && $10==“poppy”) &&   #为了不包含root用户(他通过su将用户id变成了poppy)!($1==“PASSWORD_Change” && $2 == $10) &&   #为了忽略用户修改自己密码的事件!($1==“USER_SU” && $10==“operator”) &&  #如果不关心用户su到某个特定用户!($1=="USER_SU" && $10=="genrep1") &&!/xntpd/    #要忽略包含字符串“xntpd”的所有记录 network time protocol daemonEND {print "\t\t\t\t--- end of report ---"}' $1 >$1.rep# cat $1.repmailit2 $1.rep
0 0