Chinaunix首页 | 论坛 | 博客
  • 博客访问: 44102
  • 博文数量: 20
  • 博客积分: 1419
  • 博客等级: 上尉
  • 技术积分: 220
  • 用 户 组: 普通用户
  • 注册时间: 2010-03-23 13:02
文章分类
文章存档

2010年(20)

我的朋友

分类:

2010-04-03 17:47:05

什么是shell script
 将OS命令堆积到可执行的文件里,由上至下的顺序执行文本里的OS命令 就是脚本了.
 再加上些智能(条件/流控)控制,就变成了智能化脚本了.
变量
    变量声明
 bash中的变量无须声明,拿来就用.类型会根据赋予的值来决定
 a=abc
 b=123
 c=(123)
 d=$(uname -r)
 unset a
 declare -p var_name 可以查看
    引用变量
 在变量名前加上 $ 符号
 echo $a
    作用范围
 全局
    export var=abc
    . 或 source
     局部
    子进程中
     函数中
操作符
 算术操作
    + - * / %
 关系操作
    < > <= >= == != && ||
 测试操作
 测试命令  test [ ] [[ ]]  (( ))
 1、测试文件状态
    -d  目录
    -s  文件长度 > 0、非空
    -f  正规文件
    -w  可写
    -L  符号连接
    -u  文件有 suid 位设置
    -r  可读
    -x  可执行
    $ [ -w tmp.txt ]
    $ echo $?
    0
 2、字符串测试
    =   两个字符串相等
    !=  两个字符串不相等
    -z  空串
    -n  非空串
  
    $ VAR1='abc'
    $ VAR2='123'
    $ [ '$VAR1' = '$VAR2' ]
     $ echo $?
     1
 3、测试数值
    -eq 等于
    -ne 不等于
    -gt 大于
    -lt 小于
    -ge 大于等于
    -le 小于等于
 
 4. 拓展测试符号 [[ ]] (())
   数字测试符号
    # [ 10 < 2 ]   # 语法错误
    -bash: 2: 没有那个文件或目录
    #
   
           # [[ 2 > 10 ]]  # 结果错误
           # echo $?
    0
    # [[ 20 > 10 ]] # 正确
    # echo $?
    0
           # ((  10 < 20 ))
           # echo $?
    0
   字符测试
    # [ "aa" = "aa" ]
    # echo $?
    0
    # [[ "aa" = "aa" ]]
    # echo $?
    0
    # (( "aa" = "aa" )) #结果错误
           # echo $?
    1
   混合测试
    # [ a = a -a 10 < 20 ]
    -bash: 20: 没有那个文件或目录
   
   结论:
  比较数字,使用(( ))
  其他测试使用 [[ ]]
  包含数字比较的混合测试,使用标准语法
流控结构
 if 分支结构
 # cat my.sh
 #!/bin/bash
 var=/etc/init.d
 if [[ -d $var ]]
 then
     echo "$var is directory."
 elif [[ -b $var ]]
 then
     echo "$var is block device."
 elif [[ -f $var ]]
 then
     echo "$var is a regular file."
 else
     echo "unknow."
 fi
 # 除了 -L -h 等于的文件测试遇到软连接都会用原文件测试
 if 测试中还可以执行命令 根据命令的返回值做判断
 # if cd / ;then echo Y ;fi
 # if grep -q root /etc/passwd  ;then echo Y ;fi
 向脚本传递参数
 # vim 2.sh
 #!/bin/bash
 echo '$0' $0
 echo '$1' $1
 echo '$2' $2
 echo '$3' $3
 echo '${10}' ${10}
 echo '${11}' ${11}
 echo '${12}' ${12}
 echo '$$' $$
 echo '$*' $*
 echo
$@
 echo '$#' $#
 echo '$?' $?
 # $@ $* 在双引号(软引用)参数中有差异,$@会将引号内的多个参数当成一个参数,这会影响到$#的数量
 修改脚本从参数中传递测试文件
 # cat 1.sh
 #!/bin/bash
 if [[ -d $1 ]]
 then
     echo "$1 is directory."
 elif [[ -b $1  ]]
 then
     echo "$1 is block device."
 elif [[ -f $1 ]]
 then
     echo "$1 is a regular file."
 else
     echo "unknow."
 fi
 
 #讲讲for i in 语法
 检查内网存活的IP
 #!/bin/bash
 for i in {1..254}
 do
         (ping -W 1 -c 1 192.168.1.$i &> /dev/null && echo 192.168.1.$i) &
 done
 
 
 让文件测试脚本支持多个参数
 # vim 1.sh
 #!/bin/bash
 
 for i in $@
 do
   if [[ -d $i ]]
   then
     echo "$i is directory."
   elif [[ -b $i  ]]
   then
     echo "$i is block device."
   elif [[ -f $i ]]
   then
     echo "$i is a regular file."
   else
     echo "unknow."
   fi
 done
 
 修改脚本使脚本最多支持3个参数,多个参数或0个参数报错,并退出脚本.
 [[ $# > 3 || $# = 0 ]] && echo "USAGE: $0 ERROR" && exit 1
 
 使用测试
 修改脚本告诉用户错误原因.
 case 结构语法 用户登录欢迎
 # cat 4.sh
 #!/bin/bash
 case $1 in
     root)
  echo "welcome $1"
  ;;
     seker)
  echo "welcome $1"
  ;;
  *)
  echo "no user $1"
 esac
 
 添加上与用户交互的功能
 read -p "username: "  uname
 
 如果等待时间内用户没输入 则采用默认值
 read -p "username: " -t 5 uname
 echo
 if [[ -z $uname  ]]
 then
         uname=default
 fi
 case $uname in
     root)
         echo "welcome $uname"
         ;;
    seker)
         echo "welcome $uname"
         ;;
         default)
         echo "welcome $uname"
         ;;
        *)
         echo "no user $uname"
 esac
 
 再修改脚本 让用户输入密码
 然后比对密码是否一致,如果不一致,则不显示欢迎信息
 #cat 4.sh
 #
 read -p "username: " -t 5 uname
 echo
 stty -echo
 read -sp "password: "  paswd
 stty echo
 echo
 if [[ -z $uname  ]]
 then
         uname=default
 fi
 case $uname$paswd in
            'root111')
         echo "welcome $uname"
         ;;
            'seker222')
         echo "welcome $uname"
         ;;
            'default333')
         echo "welcome $uname"
         ;;
      *)
            echo "no user $uname"
 esac
 # case的字符测试还可以使用 | 结构 例如: a|b)
 启动脚本
 循环结构
 while 语法
 while (条件)
 do
    动作
 done
 需要无限循环时我们会选择while :
 写个脚本 让用户输入,输入数字通过,输出错误重新输入
 #!/bin/bash
 retry=0
 while [ $retry -eq 0 ]
 do
  read -p "enter a num : " aa
  if expr $aa + 0 &> /dev/null
  then
   echo OK..
   retry=1
  else
   echo "enter error.retry.."
  fi
 done
 
 # cat 5.sh
 #!/bin/bash
 
 i=1
 while (( $i < 10 ))
 do
    echo $i
    ((i++))
 done
 #
 
 until 循环
 # cat 6.sh
 #!/bin/bash
 i=1
 until ! (( $i < 10 ))
 do
    echo $i
    ((i++))
 done
 # until是条件为假时进入循环
 # while是条件为真时进入循环
 # 对until条件取反 则等同于 while
 C语言格式的for
 for ((i=1;i<=10;i++))
 do
    echo $i
 done
 shell格式的for
 for i in {1..10}
 do
    echo $i
 done
 循环控制
 # for i in {1..10};do [ $i -eq 5 ] && continue || echo $i;done
 # for i in {1..10};do [ $i -eq 5 ] && break || echo $i;done
 
        shift命令
 # cat 8.sh
 #!/bin/bash
 while (($# != 0))
 do
   echo $1
   shift
 done
 统计/dev下每种类型文件的数量
 向脚本传递一个用户名,验证这个用户是否存在.
 添加30个用户,再将它们删除
 将$PATH中的找出所有加了SUID位的文件
 FTP自动下载脚本
自定义函数
1.函数定义
    shell允许将一组命令集或语句形成一个可用块,这些块称为shell函数
    定义函数的格式:
    function-name (){
        command1
        ........
    }
    或 function function-name(){ #函数名前面多了个function关键字
        command1
        ........
    }
2.函数调用
    以下是一个函数的脚本实例:
    #!/bin/bash
    #hello
    function hello(){       #声明函数
      echo "Hello!"     #函数的主体,输出"Hello!"
    }               #函数结束
    hello             #调用函数
3.参数传递
  向函数传递参数就像在脚本是使用变量位置$1,$2,$3...$9
  以下是一个传递参数的实例:
  #!/bin/bash
  #hellofun
  function hello(){
      echo "Hello! The first parameter is '$1'."
  }
  hello good
  #该脚本执行的结果是: Hello! The first parameter is 'good'.
4.函数文件
  保存函数的文件,用以上的例子写成一个函数文件如下:
  #!/bin/bash
  #hellofunction
  function hello(){
    echo "Hello!"
    return 1
  }
  上面的hellofunction文件就是一个函数文件,可通过另一个脚本来调用
  #!/bin/bash
  #hellof
  . hellofunction #注意点和hellofunction之间有个空格
  hello
5.载入和删除
  用set查看已载入的函数
  用unset function-name 取消载入
  举例如下:
#!/bin/bash
  #hellof
  . hellofunction
  unset hello
  hello   #因为已经取消载入。。所以会出错
6.函数返回状态
  #!/bin/bash
  #hellofun
  function hello(){
    echo "Hello! The first parameter is '$1'."
    return 1
  }
  hello
  echo $?   #输出返回的状态值(一般成功是返回0,其它值为失败)
 
回收站 删
[root@stu254 dir]# cat /bin/del
#!/bin/bash
mkdir -p ~/.trash
for i in $*
do
 $echo $i
 mv -f $i ~/.trash
done &> /dev/null
[root@stu254 dir]#
回收站 恢复
[root@stu254 dir]# cat /bin/undel
#!/bin/bash
for i in $*
do
 find ~/.trash -maxdepth 1 -name "$i" -exec mv {} . \;
done
[root@stu254 dir]#

数组
数组就是若干个变量组合在一起 每个变量的值都是数组的元素
元素都在数组中有一个下标 下标从0开始
数组赋值:
[root@stu254 dir]# ary=(root seker zorro blues pg)
取值方法:
  第一个元素
[root@stu254 dir]# echo ${ary[0]}
root
[root@stu254 dir]#
  第三个元素
[root@stu254 dir]# echo ${ary[2]}
zorro
[root@stu254 dir]#
  所有元素
[root@stu254 dir]# echo ${ary[*]} ; echo ${ary[@]}
root seker zorro blues pg
root seker zorro blues pg
[root@stu254 dir]#
[root@stu254 dir]#
 第二个到第四个元素
[root@stu254 dir]# echo ${ary[*]:1:3}
seker zorro blues
[root@stu254 dir]#
 下标大于等于2的所有元素
[root@stu254 dir]# echo ${ary[*]:2}
seker zorro blues pg
[root@stu254 dir]#
 下标小于2的所有元素
[root@stu254 dir]# echo ${ary[*]::2}
root seker
[root@stu254 dir]#
 元素个数
[root@stu254 dir]# echo ${#ary[*]}
5
最后一个元素
[root@stu254 dir]# echo ${ary[$((${#ary[*]}-1))]}
4pg
倒数第2个元素
[root@stu254 dir]# echo ${ary[$((${#ary[*]}-2))]}
3blues
[root@stu254 dir]#

for批量对数组赋值
[root@stu254 dir]# ary=($(for i in {0..99};do echo $RANDOM;done))
[root@stu254 dir]# echo ${#ary[*]}
100
打印数组中所有的奇数和偶数

用数组个数中的奇数值覆盖偶数值,例如第1个元素覆盖第2个 第3个元素覆盖第4个元素

从文件中读取每行赋予一个数组的方法
生成随机数 赋予数组 进行排序
找出/etc/下最新的文件和最旧的文件 modify time

变量测试
 ${var-value} 和 ${var:-value}
 - 号 如果变量设置为空则返回空值
 :-号 如果变量设置为空则返回临时值
 变量没声明 则临时赋值,否则使用原值
[root@stu254 ~]#
[root@stu254 ~]# unset var
[root@stu254 ~]# echo ${var-value}
value
[root@stu254 ~]# echo ${var:-value}
value
[root@stu254 ~]# var=123
[root@stu254 ~]# echo ${var-value}
123
[root@stu254 ~]# echo ${var:-value}
123
[root@stu254 ~]# var=""
[root@stu254 ~]# echo ${var-value}
[root@stu254 ~]# echo ${var:-value}
value
[root@stu254 ~]#

 + 号 如果变量
[root@stu254 ~]# unset var
[root@stu254 ~]# echo ${var+value}
[root@stu254 ~]# echo ${var:+value}
[root@stu254 ~]# var=123
[root@stu254 ~]# echo ${var+value}
value
[root@stu254 ~]# echo ${var:+value}
value
[root@stu254 ~]# var=""
[root@stu254 ~]# echo ${var+value}
value
[root@stu254 ~]# echo ${var:+value}
[root@stu254 ~]#
阅读(365) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~