前言:随着Linux系统在企业中的应用越来越多,服务器的自动化管理也越来越变得重要,在一些复杂的Linux维护工作中,大量的重复性的输出和交互式操作不但费时费力,而且容易出错,所以Shell脚本,可以批量处理,自动化完成一系列维护工作,大大减轻管理员的负担。

一,Shell脚本基础知识 1,编写第一个shell脚本 1),vim first.sh [root@localhost ~]# mkdir /shell //创建一个shell目录 [root@localhost ~]# vim first.sh //新建first。sh文件 #!/bin/bash cd /boot/ pwd ls -lh vml* 2),设置执行权限并执行 [root@localhost /]# chmod +x first.sh //添加可执行权限 [root@localhost /]# ./first.sh //直接运行脚本文件 /boot -rwxr-xr-x. 1 root root 4.0M 11?.22 2013 vmlinuz-2.6.32-431.el6.x86_64 [root@localhost /]# 2.为脚本添加注释,友好输出,更容易读懂 1) [root@localhost ~]# vim first.sh ~
#!/bin/bash #this is my first shell-scipt cd /boot echo "当前的目录位于:" pwd echo "其中以vml开头的文件包括:" ls -lh vml* 2),执行./first.sh后如下 [root@localhost ~]# ./first.sh 当前的目录位于: /boot 其中以vml开头的文件包括: -rwxr-xr-x. 1 root root 4.0M 11?.22 2013 vmlinuz-2.6.32-431.el6.x86_64 [root@localhost ~]# 3,重定向操作 在Linux维护中,可以改变输入、输出内容的方向,而不是使用默认的标准输出、输出设备(键盘和显示器),这种操作成为“重定向”。 1),>表示重定向输出,>>表示重定向追加 [root@localhost ~]# uname -p > kernel.txt //将当前主机的CPU类型信息保存到kernel.txt文件中 [root@localhost ~]# cat kernel.txt x86_64 [root@localhost ~]# uname -r >> kernel.txt //将内核版本追加到kernel.txt文件中 [root@localhost ~]# cat kernel.txt x86_64 2.6.32-431.el6.x86_64 [root@localhost ~]# 2),重定向输入,<表示重定向输入 [root@localhost ~]# vim pass.txt //添加初始密码串内容“123456” [root@localhost ~]# useradd chenpeng //添加用户“chenepng” [root@localhost ~]# passwd --stdin chenpeng < pass.txt //从pass.txt文件中取密码 Changing password for user chenpeng. passwd: all authentication tokens updated successfully. 3),错误重定向,可用来收集程序执行的错误信息,为排错提供依据,例如:执行以下操作可以将使用tar命令备份时出现的错误信息保存到error.log文件中 [root@localhost ~]# tar kcf /noendir/etc/.tgz /etc/ 2> error.log [root@localhost ~]# cat error.log tar: /noendir/etc/.tgz:无法. open:没有那个文件或目录 tar: Error is not recoverable: exiting now 4)&>操作符可以将两类输出信息保存到同一个文件,例如,在编译源码包的自动化脚本中,若要忽略make,make install的操作的过程信息,可以将其定向到空文件/dev/null 首先下载httpd软件到本机,然后执行Vim httpd_install.sh,并输入如下内容: [root@localhost ~]# vim httpd_install.sh #!/bin/bash
cd /usr/src/httpd-2.2.17/ ./configure --prefix=/usr/local/httpd --enable-so &> /dev/null make &> /dev/null make install &> /dev/null 设置权限chmod +x httpd_install.sh 最后执行./httpd_install.sh(注意/前的点) 4、管道操作 例子:使用grep命令查询使用/bin/bash作为shell的用户名称时,会输出符合条件的整行内容,在此基础上可以结合管道操作与Awk命令做进一步过滤,只输出用户名和登录shell列。 1)提取之前的正常效果 [root@localhost /]# grep "/bin/bash$" /etc/passwd root:x:0:0:root:/root:/bin/bash jerry:x:500:500::/home/jerry:/bin/bash chenpeng:x:501:501::/home/chenpeng:/bin/bash 2)提取之后的效果,只显示用户名和shell列 [root@localhost /]# grep "/bin/bash$" /etc/passwd | awk -F: '{print $1,$7}' root /bin/bash jerry /bin/bash chenpeng /bin/bash 3)再例如:显示磁盘已用的百分比,可以执行以下操作,其中用到了df, grep,awk命令和管道操作 [root@localhost /]# df -hT | grep "/$" | awk '{print $6}' 11% 二、使用shell变量 1、自定义变量:只在自己的shell环境中有效 1)定义新的变量和引用变量 Bash中的变量操作相对比较简单,不像其他高级编程语言(如C/C++,Java等)那么复杂。在定义一个新的变量时,一般不予要提前进行声明,而是直接指定变量名称并赋予初始值(内容)即可, 定义变量的基本格式为“变量值=变量值”,等号两边没有空格。变量的名称需以字母或者下划线开头,名称中不要包含特殊字符(如+、—、、/、.%、 &、 #、) 例如,若要定义一个名为“Product”的变量(值为Benet)和一个名为“Version”的变量(值为5.0),和查看引用变量的值,可执行一下操作: [root@localhost /]# product=benet [root@localhost /]# version=5.0 [root@localhost /]# echo $product benet [root@localhost /]# echo $product $version benet 5.0 2、变量赋值的特殊操作 1)双引号的作用:赋值的内容包含空格时,例如: [root@localhost /]# benet=benet 5.0 //错误的赋值 -bash: 5.0: command not found
[root@localhost /]# benet="benet 5.0" //正确的赋值 [root@localhost /]# echo $benet benet 5.0 在双引号范围内,使用"$"符号可以引用其他的变量值 [root@localhost /]# ACCP="ACCP $Version" //以变量的值进行赋值 [root@localhost /]# Version=4.0 [root@localhost /]# echo $ACCP ACCP 4.0 3)反撇号()的作用:用于将某个命令的输出结果赋值给变量,例如: [root@localhost /]# ls -lhwhich useradd-rwxr-x---. 1 root root 101K 12?. 8 2011 /usr/sbin/useradd 4)$()的作用:可以代替反撇号,解决嵌套问题,因为反撇号不能实现嵌套,例如:查询提供useradd命令程序的软件包所安装的配置文件位置. [root@localhost /]# rpm -qc $(rpm -qf $(which useradd)) /etc/default/useradd /etc/login.defs 5)read命令的作用:用来提示用户输入信息,例如: [root@localhost /]# read todir1 /opt/backup/ [root@localhost /]# echo $todir1 /opt/backup/ [root@localhost /]# read -p "请指定备份存放目录:" todir2 请指定备份存放目录:/opt/backup [root@localhost /]# echo $todir2 /opt/backup 3、设置变量的作用范围 新定义的变量只在当前shell有效,如果想进入新的shell环境同样有效,就需要使用export命令将变量导出为“全局变量” [root@localhost /]# echo "$product $version" benet 4.0 [root@localhost /]# export product version [root@localhost /]# bash [root@localhost /]# echo "$product $version" benet 4.0 也可以在export导出全局变量的同时,也可以为变量赋值,例如: [root@localhost /]# export web="www.google.com" [root@localhost /]# echo $web www.google.com 4,数值变量的运算 常用的几种运算符: +:加法计算 —:减法计算 \*:乘法计算,注意不能仅用“*”符号,否则将被当成文件通配符。 /:除法计算 %:求模运算,又称为取余运算,用来计算数值相处后的余数 示例如下: [root@localhost /]# x=35 [root@localhost /]# y=16 [root@localhost /]# expr $x + $y 51 [root@localhost /]# expr $x - $y 19 [root@localhost /]# expr $x \* $y 560 [root@localhost /]# expr $x / $y 2 [root@localhost /]# expr $x % $y 3 若要将运算的结果赋值给其他变量,可以结合命令替换操作(使用反撇号),例如,计算Y的3次方,并将结果赋值给ycube [root@localhost /]# ycube=expr $y * $y * $y[root@localhost /]# echo $ycube 4096 三、特殊的shell变量 1、环境变量 环境变量系统安装好了就存在,不用创建,可以直接使用,我们先查看一下: [root@localhost /]# env HOSTNAME=localhost.localdomain version=4.0 SELINUX_ROLE_REQUESTED= TERM=xterm SHELL=/bin/bash .................. 我们可以把脚本直接添加到$PATH搜索路径中去,这样执行脚本的时候就不用加./了 [root@localhost ~]# cd /shell [root@localhost shell]# ls first.sh [root@localhost shell]# first.sh //直接执行时找不到命令 -bash: first.sh: command not found [root@localhost shell]# PATH="$PATH:/shell" //将//root添加到搜索路径 [root@localhost shell]# echo $PATH //查看修改后的搜索路径 /usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/shell [root@localhost shell]# first.sh //直接以文件名运行脚本 当前目录位于: /boot 其中以vml开头的文件包括 -rwxr-xr-x. 1 root root 4.0M 11?.22 2013 vmlinuz-2.6.32-431.el6.x86_64 环境变量的全局配置文件为/etc/profile,作用于所有用户,例如:将历史记录命令条数改为200条,只针对root用户 [root@localhost ~]# vim /root/.bash_profile ............//省略部分内容 export HISTSIZE=200 //需要添加的 只需要添加上面的最后一行,然后执行source /root/.bash_profile使之生效。 [root@localhost ~]# source /root/.bash_profile //读取并执行文件中的设置 [root@localhost ~]# history | wc -l //修改后的历史命令跳数 110 2、位置变量,例如求两个数的和 [root@localhost ~]# vim adder2num.sh #!/bin/bash sum=expr $1 + $2echo "$1 + $2 = $sum" [root@localhost /]# ./adder2num.sh 1 1 1 + 1 = 2 3、预定义变量,系统安装好之后就有,不能创建,只能使用,例如:$#表示命令行中位置参数的个数,$*表示所有位置参数的内容,$?表示前一条命令执行后的返回状态,返回0表示正确。$0表示当前执行的脚本或程序的名称。 例如:制作备份数据脚本 [root@localhost /]# vim mybak.sh #!/bin/bash tarfile=beifen-date +$s`.tgz tar zcf $tarfile $
&> /dev/null echo "已执行 $0 脚本" echo "共完成 $# 个对象的备份" echo "具体内容包括: $" 执行脚本./mybak.sh,备份两个文件 [root@localhost /]# ./mybak.sh /etc/passwd /etc/shadow 已执行 ./mybak,.sh 脚本, 共完成 2 个对象的备份 具体包括:/etc/passwd /etc/shadow 查看备份结果 [root@localhost /]# ls -lh beifen- -rw-r--r-- 1 root root 3.4k Aug 17 23:29 beifen-1401972022.tgz -rw-r--r-- 1 root root 3.4k Aug 17 23:29 beifen-1401972038.tgz