一. shell脚本基础
Bash脚本类似批处理,简单来讲就是把许多的指令集合在一起,并提供循环、
条件、判断等重要功能,语法简单实用,用以编写程序,大大简化管理员的操
作,并可以完成图形工具所无法实现的功能。

1. 创建包含bash命令的文本文件。文件的第一行应为:
#!/bin/bash
#!/usr/bin/env tcsh 【这样写不用寻找指定bash目录,在env中自动搜索执行】

2. 使文件可执行(使用chmod +x scripts;sh ~.sh)

3. 将文件放置在用户的$PATH的目录中
~/bin – 用于用户的私有程序
/usr/local/bin – 本地开发、系统上的其他人使用的脚本
/usr/local/sbin - 本地开发、由root使用的脚本
直接运行脚本和使用source命令运行脚本是不同的!
脚本调试模式:
#!/bin/bash -x
# bash -x scripts

二. 基础命令
1. 引用(强度有高到底)
' '
" "
2.转义
\
3.执行命令
` `
4.变量
name=HXL
echo $name

5.命令替换
Time=`dade`
Weather=is sun
echo $Time$Weather

6.算术运算符(与c语言差不多)
<变量>++
<变量>--
-
+
**
*
/
%
+=
-+

7.计算命令
echo $[1+2]
echo `expr 1 + 2`   (加号与数必须空一个,要不然就看成一个整体了)
let A=1+2 echo $A
用(())表示数学运算。bash内建功能,效率高。(脚本中使用)



test -{b|c|e|f|d|r|w|x|s|L} file/directory

[ -b /dev/sda ];echo $?         【判断文件是否为一个block device】
1              
[ -c /dev/sda ];echo $?         【判断文件是否存在且是一个character device】
0
[ -e /dev/sda ];echo $?         【判断文件是否存在,常用】
0
[ -f /dev/sda ];echo $?         【判断文件是否存在且为文件(file),常用】
0  
[ -d /dev/sda ];echo $?         【判断文件是否存在且为目录(directory),常用】
1
[ -L /dev/sda ];echo $?         【判断文件是否存在且为一个链接文件】
1

test -{zn} string

test -z string             
【判断字符串是否为0?若string为空字符串,则为true】
test -n string              【判断判断字符串是否非为0?若string为空字符串,则为false】

二. 进制文件运算符:-ef,-nt,-ot

[ /bin/mount -ef /usr/bin/mount ];echo $?   【判断两个文件是否为同一个文件,可用在判断hard link的判定上。主要意义是判定两个文件是否指向同一个inode】
0
[ /bin/mount -nt /usr/bin/mount ];echo $?   【判断/bin/mount 是否比 /usr/bin/mount 新】
1
[ /bin/mount -ot /usr/bin/mount ];echo $?   【判断/bin/mount 是否比 /usr/bin/mount 旧】
1

逻辑运算符:-o,-a,!,&&,||

[ 2 -gt 1 -a 1 -gt 2 ];echo $?      (2>1and 1>2,错误)
1
[ 2 -gt 1 -o 1 -gt 2 ];echo $?         (2>1 or1>2,正确)
0
[ !2 -gt 1];echo $?         (非2>1,错误)
1

三. 【语句】
for语句
for HOST in HXL{1..3};do echo $HOST;done
HXL1
HXL2
HXL3

vim /etc/2.sh
#!/usr/bin/env tcsh
for ((i=1;i<=10;i++))
do
((j+=i))
#j=`expr $j + $i`   [这三种方法都可以]
#let j+=i
#j=$[j+=i]
#declare -i j+=i
done
echo $j

【数据库备份小脚本】

vim MsqDump.sh

#!/bin/bash

for x in $(mysql -uroot -phxl -e "show databases;"      -NE | grep -E "^\*|schema$"-v)
do
        mysqldump -uroot -phxl $x >/mnt/$x.dump
done
(-NE 是为了让数据库表信息呈现横向数据排序,而不是表格形式)
if语句
语法:if command;then command1;command2;elsecommand3;fi

例子
 #!/usr/bin/env tcsh
 if [ "$USER" !="root" ];then      【这里只能用 !=,不能用 -nq】,=,!=,...表示字符型,而-eq,-nq..表示整型
        echo "I'm notroot"
 else
        echo "I'm root"
 fi

case语句:它能够把变量的内容与多个模板进行匹配,再根据成功匹配的模板去决定应该执行那部分代码

#!/bin/bash
case "$1" in
        banana)
                echo apple     
                ;;
        apple)
                echo banana
                ;;
        *)
                echo shab
                ;;
esac

【*expect】实现自动应答脚本

vim /SHELL/talk

#!/bin/bash
echo "who are you?"
read who
echo "hello,$who"
echo "Are you happy?"
read answer
echo "why?"
read answer

vim /SHELL/auto.exp

#!/usr/bin/expect
#set timeout 3              【设置后面所有的expect命令的等待响应的超时时间,单位为妙】
spawn /SHELL/talk.sh            【spawn是expect的内部命令,作用是给后面的shell指令加个接入源,传递交互指令】
expect "who are you"            【判断接入源中是否有该匹配的字段,如果有则立即返回,否则等待超时时间后返回】
send "Hxl\n"                【执行交互动作,相当于手工输入“HXL”】
expect "Are you happy"
send "Yes,I am happy.\n"
expect "why?"
send "You ah me!\n"
expect eof              【作用是在输入中搜索文件结束符,如果没有这一行,脚本会立即退出,得不到正确结果】
exit


interact                【执行完成后保持交互状态,把控制权交给控制台,这时候就可以手工操作,否则退出登陆】

四. $argv 参数数组
expect脚本可以接受从bash传递过来的参数.可以使用[lindex $argv n]获得,n从0开始,分别表示第
一个,第二个,第三个....参数。

例子,一次执行 ssh root@172.25.254.[1..10] redhathostname 

vim /SHELL/HNmame.sh

NUM=160
ping -c1 -w1 172.25.254.$NUM &> /dev/null && /BASH/ssh.exp172.25.254.$NUM redhat hostname


vim /SHELL/ssh.exp

#!/usr/bin/expect
set IP [ lindex $argv 0 ]
set PASS [ lindex $argv 1 ]
set COMM [ lindex $argv 2 ]
spawn ssh root@$IP $COMM
expect {
        "yes/no"
        {send"yes\r";exp_continue}   [这是一个选择回答的格式,如果检索到“yes/no”,则回答 yes,没检索到则继续下面的检索]
        "password"
        {send "$PASS\r"}
        }
interact
       

5.环境变量
    在当前bash中再开启一个新bash,一般来说需要对已经定义的变量重新赋值。若不想重新赋值,则需要把原来的变量加入到环境变量中,因为:子程序仅会继承夫进程的环境变量,而不会继承夫进程的自定义变量

    例如
      name=HXL
      export name      [将name加入到环境变量]
      bash         [开启新bash]
      echo $name      
      HXL
加入到环境变量中的方法:1.export 变量名;2.declare -x 变量名

declare [-aixr] 变量名

declare -a 变量名   【将变量定义成为数组(array)类型】
declare -i 变量名   【将变量定义成为×××(interger)类型】
    declare -i num=1+2+3        [不加declare-i,echo $num 还是 1+2+3]
    echo $num
declare -x 变量名
declare -r 变量名   【将变量设置为readonly类型,该变量不可被更改内容,也不能重设】
declare -p 变量名   【查看变量被设置为以上那种属性】
    declare -p num
    declare -i num="6" 

6.设置别名 alias和unalias
   
    例子(有空格必须加'')
        alias  c='clear'    【将c指定为clear 命令】
  【注意】若命令相同,别名优先;若不想每次都更改,可以写道用户私有目录下的.bashrc 文件中