linuxt笔记2

linuxt笔记2
2011年06月13日
  每一行任务配置记录,都包括6个数据字段,如表6-1,分别表示不同含义
  分 时 日 月 周
  除了可以使用*,- ,/
  减号:如,1-4
  逗号:“,”可以表示一个间隔不连续范围,如“3,4,6,8”
  斜杠符号“/”可以用来指定间隔频率,如在日期字段中的“*/3”表示每隔3天
  下面将通过几个实例展示crontab计划任务的配置、查看和删除等管理操作。
  例如:由root用户设置一份crontab计划任务列表,完成如下任务
  每天早7:50 自动开启sshd服务,22点50时关闭ssd服务。
  每隔五天清空一次ftp服务器公共目录“/var/ftp/pub”中的数据
  每周六的7:30时重新启动系统中的httpd服务
  每周一、周三、迥五的下午17:30时,使用tar命令自动备份“/etc/httpd”
  #crontab -e
  50 7 * * * /sbin/service sshd start
  50 22 * * * /sbin/service sshd stop
  0 * */5 * * /bin/rm- rf /var/ftp/pub/*
  30 7 * * 6 /sbin/service httpd restart
  30 17 * * 1,3,5 /bin/tar jcvf httpdconf.tar.bz2 /etc/httpd
  例:为jerry 用户设置计划任务,在每周日晚上的23:55时将“/etc/passwd”文件的内容复制到宿主目录中,保存存为“pwd.txt”
  #crontab -e -u jerry
  55 23 * * 7 /bin/cp /etc/passwd /home/jerry/pwd.txt
  因各计划任务在执行时并不需要用户登录,所以在任务配置记录中的命令使用绝对路径,以避免因缺少执行路径而无法执行
  命令的情况。另外,在设置非每每分钏都执行的任务时,“分钟字段也应该填写一个具体的时间数值,而不要保留为默认的
  *,否则将会在每分钟执行一次计划任务。
  查看,用户的计划任务列表
  #crontab -l
  50 7 * * * /sbin/service sshd start
  50 22 * * * /sbin/service sshd stop
  0 * */5 * * /bin/rm -rf /var/ftp/pub/*
  30 7 * * 6 /sbin/service httpd restart
  30 17 * * 1,3,5 /bin/tar jcvf httpdconf.tar.bz2 /etc/httpd
  确认jerry用户的计划任务列表内容
  #crontab -l -u jerry
  55 23 * * 7 /bin/cp /etc/passwd /home/jerry/pwd.txt
  #ls -l /var/spool/cron/jerry
  -rw------ 1 root root 56 05-18 16:39 /var/spool/cron/jerry
  3)删除用户的计划任务列表
  例,使用jerry用户登录后,查看并删除自己的计划任务列表
  [jerry@localhost ~]$crontab -l
  55 23 * * 7 /bin/cp /etc/passwd /home/jerry/pwd.txt
  [jerry@localhost ~]$crontab -r
  [jerry@localhost ~]$crontab -l
  no crontab for jerry
  在设置用户的crontab计划任务的过程中,由于每一条记录只能运行一行命令,难以完成更复杂的系统管理任务操作
  ,因此在实际工作中,当需要按照同一周期运行多项任务时,通常会将相关命令操作编写成脚本文件,然后在计划
  任务配置中加载该脚本并执行。从下一章开始将会学习shell管理脚本的编写。
  第七章SHELL命令
  学完本章内容,学员将能够解决以下问题
  1,公司某员工辞职后,在linux服务器中留下了此员工创建的大量无用 文件,如何快速准确地删除这些文件
  2,由于服务器空间有限,公司规定文件服务器上完全共享文件夹每周五下班前定期删除清空。如何编写shell脚本来
  解决问题?
  3,如何编写shell脚本实现定期归档压缩指定文件夹。
  英语:
  1,script:脚本,手稿
  2,express:表这式。
  3,export:输出,导出
  4,read:读取,阅读
  5,echo:回声,回显
  6,alias:别名,绰号
  7,cut:切割,切分
  8,bash:猛击,这里指一种shell
  9,bourne:小溪,目的地。
  10,history:历史
  11,utility:有效,功用
  12,awk:笨拙的,棘手的
  13,source:源,来源。
  本章重点:重定向和管道的应用。
  shell变量的应用
  shell脚本的编写和执行
  本章难点:shell变量作用范围
  有bsh,csh,ksh,zsh,bash
  查看当前linux系统中能够使用shell程序的列表
  # cat /etc/shells
  /bin/sh
  /bin/bash
  /sbin/nologin
  /bin/tcsh
  /bin/csh
  /bin/ksh
  确认shell程序中存须的部分链接文件
  ;
  #ls -l /bin/*sh
  临时切换至新的shell环境
  直接输入其他shell程序的名称,即可切换到新的shell环境,新运行的shell程序作为当前shell程序的子进程
  返回,exit, or ctrl+D
  例: #ksh
  #help cd
  例如:使用teacher用户登录系统,并将自己的登录shell更改为tcsh.
  [teacher@localhost ~]$grep "teacher" /etc/passwd
  teacher:x:500:500:teacher:/home/teacher:/bin/bash
  [teacher@localhost ~]$chsh
  changing shell for teacher
  password
  new shell [/bin/bash]: /bin/tcsh
  shell changed
  [teacher@localhost ~]$grep teacher /etc/passwd
  teacher:x:500:500:teacher:/home/teacher:/bin/tcsh
  使用chsh命令设置了新的登录shell后,新的登录shell,将在该用户下一次登录系统时生效。
  3,由管理员(root)更改其他用户的登录shell
  root用户可以通过直接修改“/etc/passwd”文件的方式来改变用户的登录shell,也可以使用usermod命令进行更改
  例:由root用户使用usermod命令将teacher用户的登录shell重新修改为“/bin/bash”
  #usermod -s /bin/bash teacher
  #grep "teacher" /etc/passwd
  bash常用功能
  历史记录命令
  #which fdisk
  /sbin/fdisk
  #pwd
  /root
  #!wh
  which fdisk
  /sbin/fdisk
  查看历史命令列表
  #history |tail -3
  #!3
  将所有用户记录历史命令的条数设置为200
  #vi /etc/profile
  HISTSIZE=200
  若只需要调整特定用户历史命令条数,则可以修改用户宿主目录中的“.bash_profile”文件,添加类似于“export HISTSIZE=200”
  例:将用户jerry的历史命令记录的条数设置为5,重新选择后确认效果
  [jerry@localhost ~]$vi ~/.bash_profile //jerry用户修改自己的配置文件
  export HISTSIZE=5
  [jerry@localhost ~]$history | wc -l //需要jerry用户重新登录后执行此命令
  5
  4)清除历史命令
  例,使用teacher用户登录,执行“history -c”命令以清空自已历史记录
  [teacher@localhost ~]$history | tail -2
  14 cd /usr/src/
  15 ls -l
  [teacher@localhost ~]$history -c
  [teacher@localhost ~]$history
  1 history
  2,命令别名
  bash中的命令别名功能可以将频繁使用的复杂命令定义为简短的别名,当用户需要执行该条复杂命令时
  只需要使用别名即可完成对应的操作,降低了操作复杂性,提高输入效率,别名功能主要通过alias 、unalias这两个命令
  设置和取消
  1)查看已设置的别名
  直接执行alias命令可以查看当前用户环境中已设置的所有命令别名,若只需查看特定的命令别名,可以使用别名名称作为参数
  例:查看已设置的所有命令别名
  #alias
  alias cp='cp -i'
  alias l.='ls -d .* --color=tty'
  alias ll='ls -l --color=tty'
  alias ls='ls --color=tty'
  alias mv='mv -i'
  alias rm='rm -i'
  alias which='alias | /usr/bin/which --tty-only --read-alias --show-dot --show-tilde'
  自己设置命令别名
  例:设置一个命令别名dir,以便执行,“ls -ld --color=tty ”的命令,并进行确认
  #alias dir='/bin/ls -ld --color=tty'
  #alias dir
  alias dir='/bin/ls -ld --color=tty'
  #dir install.log
  -rw-r--r-- 1 root root 36875 05-10 21:45 install.log
  取消已设置的命令别名
  #unalias dir
  #alias dir
  -bash: alias: dir: not found
  例:取消用户当前环境中已设置的命令别名
  #unalias -a
  #alias //查询不到任何别名信息。 这很危险,不推荐做
  将执行后的输出结果发送到标准
  因此要长久保存的话可以放在,宿主目录中的“.bashrc”文件中
  标准输入输出和重定向
  标准输入(STDIN):默认的设备是键盘,文件编号为0,命令从标准输入文件中读取在执行过程中需要的输入数据
  标准输出(STDOUT):默认的设备是显示器,文件编号为1,命令将执行后的输出结果发送到标准输出文件
  标准错误(STDERR):默认设备是显示器,文件编号 为2,命令将执行时的错误信息发送到标准错误文件
  1)标准输出重定向,使用 “>” ">>"操作符号,分别用于覆盖、追加文件。
  “>” 重定向符后面指定的文件如果不存在,则会新建立该文件,并将命令执行结果保存到该文件中,若该文件已经存在
  ,则将清空文件内容并保存命令的执行结果到文件中。
  例:查看teacher用户的身份信息,并将输出结果保存到文件“intch.txt”
  #id teacher > idtch.txt
  #cat idtch.txt
  uid=517(teacher) gid=517(teacher) groups=517(teacher)
  ">>" 重定向符可以将命令执行的结果追加到指定文件的未尾进行可在,而并不覆盖,文件中原有的内容。若
  用户想将多个命令的输出结果保存到同一个文件中,可以使用此操作符
  #id jerry >> idtch.txt
  #cat idtch.txt
  2)标准输入重定向
  例如:管理员使用passwd命令为用户设置密码时,每次都必须根据提示重复输入两次密码字串,非常繁,若结合“--stdin”
  选项和“
  尝试通过help命令查看ls命令的帮助信息时,由于ls并非内部命令,系统将会报错,通过“2>”操作符可以将报错信息重写向到指定
  到文件中
  例:
  #help ls 2>err.log
  #cat err.log
  -bash:help:no help topics match 'ls'. Try 'help help' or 'man -k ls ' or 'info ls'
  2> 2>> 代表错误覆盖与错误追加
  &> 操作可以将两种输出内容重定向到同一个文件中
  使用ls命令查看“/etc/password”文件(并不存在)和“/etc/passwd”文件的属性时,输出结果将同时包含标准
  输出和错误输入,测试进行分别重定向、合并重定向的结果。
  #ls -l /etc/password /etc/passwd > std.txt 2> err.log
  #cat std.txt
  -rw-r--r-- 1 root root 2348 05-20 06:10 /etc/passwd
  #cat err.log
  ls: /etc/password:没有那个文件或目录
  #ls -l /etc/password /etc/passwd &> out.log
  #cat out.log
  ls: /etc/password:没有那个文件或目录
  -rw-r--r-- 1 root root 2348 05-20 06:10 /etc/passwd
  管道操作
  过滤出“/etc/inittab”文件中不以“#”号开头的行,并再次过江出非空行,将结果重定向保存为“inittab.txt”
  #grep -v "^#" /etc/inittab | grep -v "^$" > inittab.txt
  例:找出系统中使用bash作为登录shell、名称为"ha" 开头的用户账号,并只显示出用户名,登录shell 两个字段的内容
  #grep "bash" /etc/passwd | grep "^ha" | cut -d ":" -f 1,7
  handy:/bin/bash
  hackli: /bin/bash
  在上例中,cut命令用于分割管道输入的每一行内容,结合"-d"选项使用分号“:”字符作为分隔符,结合“-f”选项
  指定只显示分割出第1,7两个字段区域。
  例:查看当前系统中的总内存空间、剩余可用内存空间(MB),去除其他无关的信息。
  #free -m | head -2
  total used free shared buffers cached
  mem 503 339 163 0 87 199
  #free -m | grep "Mem" | awk '{print $2,$4}'
  503 163
  在上例中,free命令的“-m” 选项用于以mb为单位显示信息,awk命令用于以空格或制表位作为分隔,输出指定区域的字段数据
  例如:'{print $2,$4}'表示只输出第2、4两个字段的数据内容
  shell 变量应用
  1,用户自定义变量
  只在用户自己的shell环境中有效,因此又称为本地变量,在编写shell脚本程序时,通常会需要设置一些特定的自定义变量,
  以适应程序执行过程中的各种变化,满足不同的需要。
  1、例:新建立一个名为“DAY”的变量,初始内容设置为“sunday”
  #DAY=Sunday
  2,查看变量DAY内容,比较使用$符号与不使用$符号的区别
  #echo DAY
  DAY
  #echo &DAY
  Sunday
  当变量名称容易和紧跟其后的其他字符相混淆时,需要添加大括号{}将其包围起来,否则将无法确定正确的变量名称,当未
  指定变量或该变量未设置时,echo命令将显示空行。
  例: 在变量DAY的内容后紧跟“MorningBus”字符串并一起显示
  #echo $DAYMorningBus //错误引用
  #echo ${DAY}MorningBus //正确引用DAY变量的内容。
  SundayMorningBus
  3,为变量赋值的常用方法。
  1)双引号(")
  使用双引号时,允许在双引号的范围内使用“$”符号来引用其他变量的值(变量引用)。在简单的赋值操作中,双引号有时候
  可以省略
  例:确认变量DAY的内容,并使用双引号为TODAY变量赋值“TODAY IS $DAY”
  #echo $DAY
  Sunday
  #TODAY="Today is $DAY"
  #echo $TODAY
  Today is Sunday
  2)单引号 ‘
  使用单引号时,将不允许在单引号的范围内引用其他变量的值,“$”符号或者其他任何符号将作为普通字符看待。
  例:确认变量DAY的内容,并使用单引号为TODAY变量值“Today is $DAY”
  #echo $DAY
  Sunday
  #TODAY='Today is $DAY'
  #echo $TODAY
  Today is $DAY
  3)反撇号(')
  使用反撇号时,允许将执行特定命令的输出结果赋给变量(命令替换),反撇号内包含的字串必须是能够执行的命令
  执行后会用输出结果替换该命令字串。
  例:统计当前登录到本地终端(tty1 ~tty6)中的用户数量,并将结果保存到变量(usernum)
  #usermum ='w|grep "tty"'| wc -l '
  #echo $usernum
  3
  例,用一条命令找出安装了fdisk 程序的软件包名称(需要先确定fdisk程序的文件位置)
  #rpm -qf 'which fdisk '
  util-linux-2.13-0.44.e15
  例:通过find命令找出系统中hackli用户留下的文件或目录,并使用rm命令将其删除
  #rm -rf 'find / -user hackli'
  在需要嵌套使用命令替换操作时,反撇号将力所不能及,这时可以将反撇号用“$0”来代替
  例: 还是使用一行命令,将上一个例子的输出结果保存到变量 FdiskPKG中
  #FdiskPKG=&(rpm -qf $(which fdisk ))
  #echo $FdiskPKG
  util-linux-2.13-0.44.e15
  4)read命令
  除了上述同仁操作以外,还可以使用bash的内置命令read来给变量赋值。read命令
  可以从终端(键盘)读取输入,实现简单的交互过程,read将从标准输入读入一行内容
  并以空格为分隔符,将读入的各字段分别赋值给指定列表中的变量(多余的内容赋值给最后
  一个变量)若指定的变量只有一个,则将整行内容赋给该变量
  例:从键盘输入一整行数据,赋值给变量HELO,并确认HELO变量的内容。
  #read helo
  good morning techer!
  #echo $helo
  good morning teacher.
  例 从键盘输入 一整行数据,依次赋值给变量G1 G2,并确认G1 G2变量的内容
  #read G1 G2
  good morning,teacher
  #echo $G1
  good
  #echo $G2
  morning,teacher
  为了使交互操作的界面更加友好,提高易用性,read命令可以结合“-p”选项来设置提示信息,用于告知用户应该输入的内容
  等相关事项。
  例:从键盘读入一个数值变量,并给出相应的提示信息。
  #read -p "please input a number:" yournum
  please input a number:254
  #echo $yournum
  254
  4,设置变量的作用范围
  对于用户自行定义的变量,默认情况下只能在当前的shell环境中使用,因此称为局部变量。局部变量在新开启子shell环境
  中是无效的(无法引用定义的变量)。
  例:在当前shell环境中定义一个变量filesvr开启一个新的子shell进程(bash或zsh)等处于子shell环境中时无法使用变量
  filesvr的内容。
  #filesvr=filesvr.benet.com
  #zsh //切换到新的shell环境
  ~#echo $filesvr //无法使用该变量的内容
  #exit //返回原来的shell环境
  #echo $filesvr //可以使用该 变量的内容
  filesvr.benet.com
  为了使用户自定义的变量在所有的子shell环境中能够继续使用,减少重复设置工作,可以使用export命令将指定的变量设置
  为“全局变量”。export命令可以同时使用多个变量名作为参数(不需要使用$符号),变量名之间以空格分隔
  例:确认变量filesvr的内容,并将其设置为全局变量,在子shell、当前shell环境中进行验证。
  #echo $filesvr
  filesvr.benet.com
  #export filesvr
  #zsh
  ~#echo $filesvr //在子shell环境中也可以使用该变量
  filesvr.benet.com
  #exit
  #echo $filesvr //返回原shell环境中仍然能使用该变量
  filesvr.benet.com
  export命令还可以输出变量的同时对指定名称的变量进行赋值(创建),这样在使用export命令之前就不需要单独为变量进行
  赋值了。
  例: 定义两个变量MONTH YEAR ,并将其设置为全局变量
  #export MONTH=may YEAR=2009
  #echo $MONTH $YEAR
  May 2009
  5,清除自定义变量
  当用户不再需要使用自定义变量时,可以使用unset命令对已定义的用户变量进行清除,指定一个或多个变量名称作为参数
  即可(以空格分隔)
  例:清除已设置变量DAY MONTH YEAR
  #unset DAY MONTH YEAR
  #echo $DAY $MONTH $YEAR //查看时将无对应内容。
  6,数值变量的运算
  bash程序并不适合进行强大的数学运算(如小数、指数等),一般只适合进行简单的整数去处,对shell变量进行数值运算时
  更多的时候是用于脚本程序的过程控制(如循环次数等,下一章中将会讲解)。对整数数值变量进行算术运算时,可以使用
  expr表达式命令,格式如下
  + - \* / % 加减乘除 求余
  设置变量X Y 的值分别为 34 12,依次计算变量值 X Y 的加减乘除及取余运算结果。
  #X=34
  #Y=12
  #expr $X+$Y
  46
  #expr $x \* $y
  例 计算变量x的值与数值 “123”的和 ,并将计算结果重新赋值给变量。x
  #echo $x
  #x=`expr $x +123`
  #echo $x
  环境变量
  这里所说的环境变量是指用户登录后linux系统预告设定好的一类shell变量,其功能是设置用户的设立shell工作环境
  ,包括用户的宿主目录、命令查找路径,用户当前目录、登录终端等。在实际使用过程中,环境变量并没有严格的区分定义,用户自己
  设置的变量也可以作为环境变量。
  环境变量的名称比较固定,通常使用大写字母、数字和春他字符组成,而不使用小写字线,环境变量的值一般由linux系统自行
  维护,会随着用户状态的改变而改变,用户可以通过读取环境来了解自己的当前状态。
  1、查看环境变量
  通过不带任何选项或参数的set命令,可以查看系统中的所有shell变量(包括环境变量、用户自定义变量等),由于输出内容
  较多,使用less,命令进行分页查看。
  #set | less
  bash=/bin/bash
  bash_argc=()
  bash_argv=()
  例:以分号分离,显示当前用户的用户名、宿主目录、登录shell
  #echo "$user:$home:$shell"
  root:/root:/bin/bash
  $PATH变量表示当前用户的命令搜索路径,即当用户未指定完整路径名来执行命令时,shell程序将在哪些目录
  以及按照何种顺序查找该命令对应的可执行文件。用户需要将其他路径添加到该搜索范围时,可以对path变量的值进行修改。
  例,确认当前的命令搜索路径,并将“/opt/bin”目录添加一现有的搜索路径中去。
  #echo $PATH
  /usr/kerberos/sbin :/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin
  #PATH="/opt/bin:$PATH"
  /opt/bin:/usr/kerberos …………………………………………………………
  2,环境变量配置文件
  在linux系统中,用户环境变量的设置工作习惯在“/etc/profile”文件及用户宿主目录中的“.bash_profile”文件中进行,前者称
  为全局配置文件(对所有用户起作用)后者称为用户配置文件(允许覆盖全局配置)
  用户需要长期变更所使用的某个环境变量时,可以在“.bash_profile”配置文件中进行修改,否则可以在当前shell
  环境直接变量赋值。
  在当前用户环境中,将用于限制历史命令条数的环境变量 HISTSIZE的值改为24
  #history | wc -l
  864
  #export HISTSIZE=24
  #echo $HISTSIZE
  24
  #history | wc -l
  24
  编辑“~/.bash_profile”文件,修改PATH的设置,以便用户在下次登录后能够使用“/opt/bin”目录作为默认搜索路径
  #vi ~/.bash_profile
  PATH=$PATH:$HOME/bin:/opt/bin
  exprot PATH
  位置变量
  $1 $2 $3 $4 $5 $6 $7 $8 $9
  例如 service network restart
  $1 $2 $3
  $0代表所执行的命令或脚本程序的名称。
  预定义的变量
  预定义的变量是由BASH程序预先定义好的一些特殊变量,用户只能使用预定义变量,而不能创建新的预定义数量,
  或直接为预定义变量赋值,所有的预定义变量都是由$ 符号和另一个符号组成的,较常用的shell预定义变量包括以下这些。
  $# :表示命令行中位置参数的数量
  $* :表示所有位置参数的内容
  $? :表示命令执行后返回的状态,用于检查上一个命令的执行是否正确,在linux中,命令退出状态为0表示命令执行正确
  任何非0值表示命执行错误
  $$ 表示当前进程的进程号
  $! 表示后台运行的最后一个进程的进程号
  $0 表示当前执行的进程进程名
  预定义变量通常使用在shell脚本程序中,在命令行界面中的应用并不多见。(尽管也可以使用)
  例:验证预定义变量$0 $$ $?
  #bash
  #echo $0 $$ //显示当前的进程名称、PID号
  bash 5887
  #exxit //执行错误的一个命令
  bash: exxit: command not found
  # echo $? //返回值非0,表示上一个命令执行失败
  127
  #exit
  exit
  #echo $? //返回值为0,表示上一条命令执行成功
  0
  7.3编写并执行shell脚本
  在linux系统中存有大量的shell脚本文件,很多脚本程序 是linux系统中不可缺少的组成部分,功能非常重要。
  例如:在“/etc/init.d”目录中存在着数量相当多的系统服务启动程序,这些程序全都是shell脚本文件,可以使用file
  命令查看这些文件的类型。
  例:确认系统服务脚本文件的数量和文件类型
  #ls -l /etc/rc.d/init.d/* | wc -1
  87
  #file /etc/rc.d/init.d/* | tail -2
  /etc/rc.d/init.d/ypbind: bourne-again shell script text executable
  /etc/rc.d/init.d/yum-updatesd bourne-again shell scrip text executable
  linux中的系统脚本文件的属主都是管理员用户root,所有的脚本文件都具有可执行的(x)的文件属性,因此可以由
  shell解释执行。shell脚本文件以文本文件的形式保存,可以使用cat命令查看文件内容,也可以使用vi编辑器修改文件的内容。
  例:
  查看系统中的网络服务脚本 network文件的开头五行内容。
  #cat /etc/rc.d/init.d/network | head -5
  #! /bin/bash
  #
  #
  #network bring up/down networking
  #
  #chkconfig: 2345 10 90
  linux中的系统脚本文件只有管理员root才具有修改的权限,修改系统服务脚本存在着相当大的风险,错误的改动
  有可能导致系统程序的瘫痪,因此不初学者修改。
  例: 使用vi编辑器编写一个简单的shell脚本文件repboot.sh 用于报告当前系统中的 “/boot” 目录所占有用的空间大小
  ,并列出其中内核文件的属性信息。
  1,#vi repboot.sh //编写的内容如下
  #!/bin/bash
  #to show usage of /boot directory and mode of kernel file
  echo "usage of /boot: "
  du -sh /boot
  echo "the mode of kernel file:"
  ls -ln /boot/vmlinuz-*
  在上述脚本文件中,依次设置了四条可执行命令,两条echo语句用于显示相应的提示信息,
  而du ls 命令分别用于完成查看目录空间、显示文件属性的任务
  2,为脚本文件添加可执行权限
  编写并保存好脚本文件以后,需要执行该程序才能看到操作结果。但是刚刚建立的脚本文件通常不具有可
  执行属性,因此还得使用chmod命令为文件添加"x"权限
  例 为上一步编写的脚本文件 repboot.sh添加可执行权限
  #ls -l repboot.sh
  -rw-r--r-- 1 root root 166 05-20 15:37 repboot.sh
  #chmod a +x repboot.sh
  #ls -l repboot.sh
  -rwxr-xr-x 1 root root 166 05-20 15:37 repboot
  执行shell脚本
  例 执行当前目录下的repboot.sh脚本程序文件
  #./repboot.sh
  useage of /boot
  5.2M /boot
  the mode of kernel file:
  -rw-r--r-- 1 root root 1.7M 2007-01-27 /boot/vmlinuz-2.6.18-8.e15
  例#bash repboot.sh
  3,使用 ??命令执行脚本
  # ?? repboot.sh
  shell脚本应用实例
  1,shell脚本案例1
  由于公司的文件服务器空间有限,需要完成一项定期任务,即在每周五下班前(17:30)检查公共共享目录“/var/ftp/pub”
  中的内容,并将其中所有子目录及文件的详细列表和当时时间信息追加保存“/var/log/pubdir.log”日志文件中,然后清空
  该目录中的内容。
  编写脚本文件 ftpclean.sh 并添加执行权限
  #vi /opt/ftpclean.sh
  #!/bin/bash
  date >> /var/log/pubdir.log
  ls -lhR /var/ftp/pub >> /var/log/pubdir.log
  rm -rf /var/ftp/pub/*
  #chmod a+x /opt/ftpclean.sh
  (2)设置计划任务并确认crond服务已经启动
  #crontab -e
  30 17 * * 5 /opt/ftpclean.sh
  #service crond status
  crond (pid 2700)正在运行……
  #chkconfig --level 35 crond on
  2,shell脚本案例2
  公司内网开发服务器中的数据库位于“/var/lib/mysql”,根据数据安全管理要求,至少每隔三天要做一次完整备份,备份
  前需要统计该目录占有用的总空间大小,并将备份日期、目录空间大小等信息保存到临时文件 “/tmp/dbinfo.txt”中,
  然后使用tar命令将dbinfo.txt文件随数据库目录一起备份到“/opt/dbbak/”目录中,备份包文件名中要求体现当天的日期
  根据上述需求描述,推荐操作步骤如下。
  1) 创建保存备份文件目录
  #mkdir /opt/dbak
  2)#vi /opt/dbbak.sh
  #!/bin/bash
  DAY=`date +%Y%m%d`
  SIZE=`du -sh /var/lib/mysql`
  echo "Date:$DAY" >> /tmp/dbinfo.txt
  echo “Data size: $Size”>> /tmp/dbinfo.txt
  tar zcvf /opt/dbbak/mysqlbak-${DAY} .tar.gz /var/lib/mysql /tmp/dbinfo.txt
  rm -f /tmp/dbinfo.txt
  #chmod a+x /opt/dbbak.sh
  3)设置计划任务并确认crond服务已经启动
  #crontab -e
  55 23 */3 * * /opt/dbbak.sh
  #service crond status
  crond (pid 2700)正在进行……
  #chkconfig --level 35 crond on
  第八章编写shell管理脚本(二)
  本章将以if,for,while,语句的应用为主,学习shell脚本程序的结构控制。另外,对case语句,shell函数应用
  test 条件表达式
  [ 条件表达式 ]
  -d 测试是否为目录(directory)
  -e 测试目录或文件是否存在(exist)
  -f 测试是否为文件(file)
  -r 测试当前用户是否有权限读取(read)
  -w 测试当前用户是否有权限写入(write)
  -x 测试当前用户是否可执行(excute)该文件
  -L 测试是否为符号连接(link)文件
  例:先后测试 “/etc/vsftpd” "/etc/hosts" 是否是目录,并通过“$?”变量查看返回状态值,据此判断测试结果。
  #[ -d /etc/vsftpd ]
  #echo $?
  0 //返回值为0,表示上一步测试的条件成立
  #[ -d /etc/hosts ]
  1
  例:测试“/media/cdrom/Server” 及其父母是否存在,如果存在则显示“YES” ,否则不输出任何信息
  #[ -e /media/cdrom/Server ]&& echo "YES"
  //无输出表示该目录不存在
  #[ -e /media/cdrom ] && echo "YES"
  YES //显示YES表示该目录存在
  例:使用普通用户teacher登录,并测试是否对“/etc/passwd”文件有读、写权限,如果则显示‘yes’
  [teacher@localhost ~]$[ -w /etc/passwd ]&& echo "yes" //无写入权限
  [teacher@localhost ~]$[ -r /etc/passwd ]&& echo "yes"
  yes //有读取权限
  2,
  整数值比较
  -eq 等于 equal
  -ne 不等于 not equal
  -gt 大于 greater than
  -lt 小于 lesser than
  -le 小于等于 lesser equal
  -ge 大于等于 greater equal
  数值比较的测试操作在shell脚本编写中的应用较多,例如,用于判断磁盘使用率、登录用户数量是否超标以及用于
  控制脚本语句的循环次数等。
  例:测试当前登录到系统中的用户数量是否小于或等于10,是则输出“YES”
  #who | wc -l
  5
  #[ `who|wc -l` -le 10]&&echo "yes" //通过命令替换获取用户数
  yes
  例:提取出“/boot”分区的磁盘使用率,并判断是否超过95%(为了便于理解,操作步骤已适当进行分解)
  #df -hT | grep "/boot" |awk '{print $6}'
  12%
  #bootusage=`df -hT | grep "/boot" | awk '{print $6}' | cut -d ":" -f 1`
  #echo $bootusage
  12
  #[ $bootusage -gt 95 ]&& echo "yes" //无输出表示未超标
  3,字符串比较
  字符串比较可以用于检查用户输入,例如,在提供交互操作时,判断用户输入的选择项是否与指定的变量内容相匹配
  “=” “!=” 操作选项分别表示匹配、不匹配,“-z”操作选项用于检查字符串是否为空 。其中“!”符 号用于取反,
  表示相反的意思
  例:
  #read -p "location : " filepath
  location: /etc/inittab //从键盘输入 “/etc/inittab”
  #[ $filepath ="/etc/inittab" ]&& echo "yes"
  yes
  例:若当前环境变量lang的内容不是“en.us”,则输出lang变量的值,否则无输出
  #[ $lang != "en.us" ]&& echo $lang
  zh_CN.UTF -8
  例:使用touch zero.file
  #[ -z `cat zero.file` ]&& echo "yes"
  yes //表示该文件为空文件
  # echo "something " > zero.file //向文件写入内容
  #[ -z `cat zero.file `]&& echo "yes" //无输出表示文件不为空
  逻辑测试
  &&逻辑与 || 逻辑或
  例:测试当前的用户是否是teacher,若不是则提示“not teacher”
  #echo $USER
  root
  #[ $USER ="teacher" ] || echo "not teacher"
  not teacher
  若当前的用户是root且使用的shell程序是“/bin/bash”,则显示“yes”,否则无任何输出
  #echo $USER $SHELL
  root /bin/bash
  #[ $USER ="root" ] &&[ $SHELL =`/bin/bash` ]&& echo "yes"
  yes
  if语句结构
  1,单分支
  if 条件测试命令
  then
  命令序列
  fi
  2,双分支的if语句
  if 条件测试命令
  then
  命令序列1
  else
  命令序列2
  fi
  3,多分支的if语句
  if 条件测试命令1
  then 命令序列1
  elif 条件测试命令2
  then
  命令序列2
  else
  命令序列3
  fi
  if 语句应用的示例
  例: 检查 “/var/log/messages” 文件是否存在,若存在则统文件内容的行数并输出,否则不做任何操作(合理使用变量
  ,可以提高效率)
  #vi chklog.sh
  #!/bin/bash
  logfile="var/log/messages"
  if [ -f $logfile ]; then
  wc -l $logfile
  fi
  #sh chklog.sh //执行该脚本进行测试(sh是bash的符号链接)
  2102 /var/log/messages
  例:提示用户指定备份目录的路径,若目录已存在则显示提示信息后跳过,否则显示相应提示信息后创建该目录
  #vi mkbak.sh
  #!/bin/bash
  read -p "what is your backup directory :" bakdir
  if [ -d $bakdir] ;then
  echo "$bakdir already exist. "
  else
  echo "$bakdir is not exist,will make it."
  mkdir $bakdir
  fi
  #sh mkbak.sh
  what is your backup directory: /opt/bakroot //从键盘输入 “/opt/bakroot”
  /opt/bakroot is not exist,will make it.
  #ls -ld /opt/bakroot //验证程序是否创建该目录
  drwxr-xr-x 2 root root 4096 05-21 21:12 /opt/bakroot
  例:统计当前登录到系统中的用户数量,并判断是否超过三个,若是则显示实际数量并给出警告信息,否则列出
  登录用户贴名称及所在的终端。
  #vi chkuser.sh
  #!/bin/bash
  usernum=`who | wc -1 `
  if [ $usersnum -gt 3 ]; then
  echo "alert ,too many login users (total: $usersnum). "
  else
  echo "login users : "
  who | awk '{print $1,$2}'
  fi
  #sh chkuser.sh
  alert,too many login users (total :5 )
  例:检查portmap进程是否已经存在,若已经存在则输出“portmap service is running”,否则检查是否存在 “/etc/rc.d/
  init.d/portmap”可执行脚本,存在则启动portmap服务,否则提示“no portmap script file.”
  #vi chkportmap.sh
  #!/bin/bash
  pgrep portmap &> /dev/null //不在屏幕中显示pgrep命令的输出结果
  if [ $? -eq 0 ]; then
  echo "portmap service is running"
  elif [ -x "/etc/rc.d/init.d/portmap" ]; then
  service portmap start
  else
  echo "no portmap script file ."
  fi
  #sh chkportmap.sh
  例: 每隔五分钟监测一次mysqld服务进程的运行状态,若发现mysqld进程已终止,则在“/var/log/messages”文件中追加
  写入日志信息(包括当时时间),并重启mysqld服务,否则不进行任何操作。
  #vi chkdbsvr.sh
  #!/bin/bash
  service mysqld status &> /dev/null //通过service工具检查系统服务状态
  if [ $? -ne 0 ]; then
  echo "at time :`date`: mysql server is down " >> /var/log/messages
  service mysqld restart
  fi
  #chmod u+x chkdbsvr.sh
  # ./chkdbsvr.sh
  停止 mysql [失败]
  启动 mysql [确定]
  #tail -l /var/log/messages //查看日志记录
  at time :2009年 05月21日 星期四 22:07:58 CST :MYSQL SERVER IS DOWN
  #crontab -e //需确认 crond服务已运行
  */5 * * * * /root/chkdbsvr.sh
  使用for循环语句
  for 变量名 in 取值列表
  do
  命令序列
  done
  在上述语句中,使用in关键字为用户自定义变量设置了一个取值列表(以空格分隔多个值,)for语句第一次执行
  时首先将列表中的第一个取值赋给该变量,然后执行 do后边的命令序列;然后再将列表中的第2个取值赋给该变量
  ,然后执行do 后边的命令序列……如此循环,直到取值列表的所有值都已经用完,最后将跳至done语句,表示结束循环
  for语句应用示例
  for 语句可以用于对一些特定列表值的处理(如过滤搜索到的文件等),本小节将通过脚本实例的方式来展示for循环语句
  结构的具体用法。
  例:依次输入三条文字信息,包括一天中的“morning” "noon" "evening" 字串
  #vi showday.sh
  #!/bin/bash
  for tm in "morning" "noon" "evening"
  do
  echo "the $tm of the day"
  done
  #sh showday.sh
  the morning of the day
  the noon of the day
  the evening of the day
  例: 对于使用 "/bin/bash" 作为登录 shell的系统用户,检查他们在“/opt”目录中拥有的子目录或文件数量,如果
  超过100个,则列出具体数值及对对应的用户帐号。
  #vi chkfileown.sh
  #!/bin/bash
  DIR="/opt"
  lmt=100
  validusers=`grep "/bin/bash" /etc/passwd | cut -d ":" -f 1 `
  //找出使用bash的系统用户列表
  for username in $validusers
  do
  num=`find $DIR -user $username | wc -l` //统计每个用户拥有的文件数
  if [ $num -gt $lmt ] ; then
  echo "$username have $num files. "
  fi
  done
  #sh chkfileown.sh
  root have 6737 files
  teacher have 344 files
  计算“/etc/”目录中所有的 "*.conf" 形式的配置文件所占有用的总空间大小
  #vi confsize.sh
  #!/bin/bash
  sizenums=$(ls -l $(find /etc -type f -a -name *.conf )|awk '{print $5}')
  total =0
  for i in $sizenums
  do
  total=`expr $total +$i`
  done
  echo "total size of conf files: $total bytes."
  #sh confsize.sh
  total size of conf files :688362 bytes
  使用while循环语句
  while 语句的结构
  while 条件测试命令
  do
  命令序列
  done
  在上述语句中,首先通过while判断条件测试命令的返回状态是否为0(条件成立),如果是,则执行do后边的命令序列,然
  后返回到while再次进行条件测试并判断返回状态的值,如果条件仍然成立,则继续执行do,后边的命令序列,然后返回古巴while
  重复条件测试……如此循环,直到所测试的条件不成立时,跳转到done语句,表示结束循环。
  例:由用户从键盘输入一个大于1的整数(如50),并计算从1到该数之间各整数的和
  #vi sumint.sh
  #!/bin/bash
  read -p "input a number (>1) :" up //读取用户指定的数值保存到up的变量
  i=1
  sum=0
  while [ $i -le $up ] //加数小于用户指定的上限时执行循环
  do
  sum=`expr $sum +$i`
  i=`expr $i +1` //将整数i的值累加给sum变量
  done
  echo "the sum of 1-$up is : $sum" //输出求和结果
  #sh sumint.sh
  input a number(>1) : 50
  the sum of 1-50 is :1275
  例: 批量添加20个系统用户帐号,用户名称依次为“stu1”"stu2" "stu3"……stu20
  各用户的初始密码均设置为“123456”
  #vi add20users.sh
  #!/bin/bash
  i=1
  while [ $i -le 20 ]
  do
  useradd stu$i
  echo "123456" | passwd --stdin stu$i &> /dev/null //为用户账号设置初始密码
  i=`expr $i +1 `
  done
  #sh add20user.sh
  tail -2 /etc/passwd
  例:编写一个指删除用户的脚本程序,将上例中添加的20个用户删除
  #vi del20users.sh
  #!/bin/bash
  i=1
  while [ $i -le 20]
  do
  userdel -r stu$i
  i=`expr $i+1`
  done
  #sh del20user.sh
  #grep "stu" /etc/passwd //无输出则表示上述用户已删除
  其他控制语句 case
  结构: case 变量值 in
  模式 1)
  命令序列1
  ;;
  模式 2)
  命令序列 2
  ;;
  ……
  *)
  默认执行的命令序列
  esac
  case语句的结构特点:
  case行尾必须为单词“in” ,每一模式必须以右括号 “)” 结束
  双人号“;;” 表示命令序列的结束
  匹配模式中可以使用方括号表示一个连续的范围,例如“[0-9]”;使用坚杠符号“|”表示或,如a|b (a或者b)
  例:由用户从键盘输入一个字符,并判断该字符是否为字母、数字或者其他字符,并输出相应的提示信息
  #vi hitkey.sh
  #!/bin/bash
  read -p "press some key, then press return: " KEY
  case "$KEY" in
  [ a-z ]| [ A-Z])
  echo "it's a letter."
  ;;
  [ 0-9 ])
  echo "it's a digit"
  ;;
  *)
  echo "it's function keys、spacebar or other keys"
  esac
  #sh hitkey.sh
  press some key,then press return: K
  it's a letter
  在linux系统中的很多脚本文件都使用了case分支语句,其中“/etc/rc.d/init.d”目录下的各种系统服务脚本最为典型
  例如在crond服务脚本的case语句的结构中,用于匹配的变量为“$1”,也就是用户输入的第1个参数,当用户执行
  "/etc/rc.d/init.d/crond start"命令时,“$1”的值就是“start” ,因此程序会执行 start) 模式后边的命令序列
  用于启动crond服务(start 执行语句为该脚本中定义的函数)
  例: crond服务脚本中的case语句
  case "$1" in
  start)
  start
  ;;
  stop)
  stop
  ;;
  restart)
  restart
  ;;
  reload)
  reload
  ;;
  status)
  rhstatus
  ;;
  condrestart
  [ -f /var/lock/subsys/crond ]&& restart ||
  ;;
  *)
  echo $"usage: $0 {start|stop|status|reload|restart|condrestart}"
  exit 1
  esac
  until 循环
  until循环语句与while循环语句的机构非常类似,同样是根据特定的条件决定是否执行循环体中的命令序列
  只不过while循环语句是当测试条件成立时执行,而until循环是当测试条件成立时结束循环,until循环语句格式如下
  until 条件测试命令
  do
  命令序列
  done
  例,同while一样的,批量删除用户一样
  #!/bin/bash
  i=1
  until [ $i -gt 20 ] //此行原来为while [ $i -le 20 ]
  do
  userdel -r stu$i
  i=`expr $i + 1`
  done
  shift语句
  shift实际上是bash中一个特殊的内部命令,但是在命令行较少使用,而更多的是用在shell脚本程序中,执行
  shift命令后,位置变量($1~$9)中的命令行参数会依次向左传递。例如:
  $1=file1 $2=file2 $3=file3 $4=fie4
  执行一次shift命令操作后(丢弃最左边的一个值),各位置变量的值将变为如下所示
  $1=file2 $2=file3 $3=file4
  再执行shift命令操作后,各位置变量的值将变为如下所示
  $1=file3 $2=file4
  各理利用shift语句,可以在位置参数的数量不固定的情况下灵活实现程序的功能
  例: 编写一个shell程序,计算多个整数值的和,需要计算的各个数值由用户在执行脚本时作为命令行参数给出
  #vi sumer.sh
  #!/bin/bash
  result=0
  while [ $# -gt 0 ]
  do
  result=`expr $result +$1 `
  shift
  done
  echo "the sum is : $result"
  #chmod a+x sumer.sh
  #./sumer.sh 12 34 //计算(12+34)的和
  the sum is : 46
  #./sumer.sh 12 34 56 //计算(12+34+56)的和
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值