• bash代码


    bash代码:
    #!/bin/bash
    MySQLSTARTUP="/data/3306/mysql"
    DbProcessCount=`ps -ef|grep mysql|grep -v grep|wc -l`
    DbPortCount=`netstat -lnt|grep 3306|wc -l`
    
    if [ $DbProcessCount -eq 2 ] && [ $DbPortCount -eq 1 ]
      then
        echo "mysql is running! " 
    else
        $MySQLSTARTUP start >/tmp/mysql.log
       sleep 20;
       if [ $DbProcessCount -ne 2 ] || [ $DbPortCount -ne 1 ]
          then 
              killall mysqld >/dev/null 2>&1
    		  sleep 5
              killall mysqld >/dev/null 2>&1
    		  sleep 5
              [ $DbPortCount -eq 0 ] && $MySQLSTARTUP start >>/tmp/mysql.log
    		  [ $? -eq 0 ] &&  echo "mysql is started"
       fi
       mail -s "mysql restarted" xx@qq.com < /tmp/mysql.log
    fi

    2) 通过连接mysql 执行命令来判断

    bash代码:
    #!/bin/bash
    MySQLSTARTUP="/data/3306/mysql"
    mysql -uroot -p'oldboy' -S /data/3306/mysql.sock -e "select version();" >/dev/null 2>&1
    if [ $? -eq 0 ]
      then
        echo "mysql is running! " 
    else
        $MySQLSTARTUP start >/tmp/mysql.log
        sleep 10;
        mysql -uroot -p'oldboy' -S /data/3306/mysql.sock -e "select version();" >/dev/null 2>&1
        if [ $? -ne 0 ]
          then 
            killall mysqld  >/dev/null 2>&1
            killall mysqld  >/dev/null 2>&1
    		sleep 10
            $MySQLSTARTUP start >>/tmp/mysql.log
        fi
       mail -s "mysql restarted" xx@qq.com < /tmp/mysql.log
    fi
    

    3) 较专业的写法:

    bash代码:
    #!/bin/bash
    MYUSER=root
    MYPASS=""
    MYSOCK=/data/3306/mysql.sock
    MySQL_STARTUP="/data/3306/mysql"
    LOG_PATH=/tmp
    LOG_FILE=${LOG_PATH}/mysqllogs_`date +%F`.log
    MYSQL_PATH=/usr/local/mysql/bin
    MYSQL_CMD="$MYSQL_PATH/mysql -u$MYUSER -p$MYPASS -S $MYSOCK"

    $MYSQL_CMD -e "select version();" >/dev/null 2>&1 if [ $? -eq 0 ] then echo "MySQL is running! " exit 0 else $MySQL_STARTUP start >$LOG_FILE sleep 5; $MYSQL_CMD -e "select version();" >/dev/null 2>&1 if [ $? -ne 0 ] then for num in `seq 5` do killall mysqld >/dev/null 2>&1 [ $? -ne 0 ] && break; sleep 1 done $MySQL_STARTUP start >>$LOG_FILE fi $MYSQL_CMD -e "select version();" >/dev/null 2>&1 && Status="restarted" || Status="unknown" mail -s "MySQL status is $Status" @qq.com < $LOG_FILE fi exit

    例3 监控apache

    1) 对端口、进程和url同时监测。

    bash代码:
    #!/bin/bash
    . /etc/init.d/functions
    LOG_FILE=/tmp/httpd.log
    apachectl="/application/apache/bin/apachectl"
    HTTPPORTNUM=`netstat -lnt|grep 80|grep -v grep|wc -l` HTTPPRONUM=`ps -ef|grep http|grep -v grep|wc -l`
    wget --quiet --spider http://10.0.0.179:8000 && RETVAL=$? [ ! -f $LOG_FILE ] && touch $LOG_FILE if [ "$RETVAL" != "0" -o "$HTTPPORTNUM" -lt "1" -o "$HTTPPRONUM" < "1" ] ;then action "httpd is not running" /bin/false echo -e "httpd is not running " >$LOG_FILE echo "Preparing start apache..." for num in `seq 10` do killall httpd >/dev/null 2>&1 [ $? -ne 0 ] && { echo "httpd is killed" >$LOG_FILE break; } sleep 2 done $apachectl start >/dev/null 2>&1 && Status="started" || Status="unknown" [ "$Status" = "started" ] && action "httpd is started" /bin/true|| action "httpd is started" /bin/false mail -s "`uname -n`'s httpd status is $Status" xx@qq.com <$LOG_FILE exit else action "httpd is running" /bin/true exit 0 fi

    2) 使用nmap检测

    bash代码:
    #!/bin/bash
    ip_add="$1" 
    port="$2"
    print_usage(){
    	   echo -e "$0 ip port"
    	   exit 1
    }
    		
    #judge para num
    if [ $# -ne 2 ]
    	then
    		print_usage
    fi
    PORT_COUNT=`nmap $ip_add  -p $port|grep open|wc -l`
    #echo -e "
    " |telnet $ip_add $port||grep Connected
    #echo -e "
    "|telnet 10.0.0.179 8000|grep Connected
    [[ $PORT_COUNT -ge 1 ]] && echo "$ip_add $port is ok." || echo "$ip_add $port is unknown."
    No.001 文件安全与权限
    
    1. umask 决定了新建文件的权限
    2. 软链接(符号链接) ln -s source_path target_path
    
     
    No.002 find和xargs
    
    1. find pathname -options [-print -exec -ok]
       其中exec参数的命令格式: 'command-' {} ; 注意必须包含【{} ;】
       -perm 按权限来查找  ex. find . -perm 755 -print
       -mtime 按修改时间来查找 ex. find / -mtime -5 -print 更改时间5天以内
                                   find / -mtime +5 -print 更改时间5天以前
    2. xargs与-exec和-ok类似,但是限制更少,也更快
       3种参数的命令:find . -name "*.c" -exec wc -l {} ;
                            find . -name "*.c" -ok wc -l {} ;   每次执行命令前有提示
                            find . -name "*.c" | xargs wc -l
    
     
    No.003 后台执行命令
    
    1. [crontab] [at] [&] [nohup]四种
    
     
    No.004 文件名置换
    
    1. 列出隐藏文件 ex. ls .*
    
     
    No.005 shell输入与输出
    
    1. echo输出时加上 -n 参数不换行, ex. echo -n "aaaa"
    2. tee 命令可以同时输出到屏幕和文件中 ex. ls | tee file.out
    3. 标准输入 0  标准输出 1  标准错误 2
    4. 将标准输出和标准错误输入到一个文件  ex. command >file.out 2>&1
    
     
    No.006 命令执行顺序
    
    1. 命令1 && 命令2    命令1执行成功后才会执行命令2
    2. 命令1 || 命令2    命令1执行失败后才会执行命令2
    
     
    No.007 正则表达式
    
    1. 正则表达式元字符及含义
        ^                     只匹配行首
        $                     只匹配行尾
        *                     匹配0次或多次
        []                    匹配[]内字符
                             转义符
        .                     匹配任意一个字符
        pattern{n}          匹配pattern出现的次数,n次
        pattern{n, }        同上,最少n次
        pattern{n, m}       同上,次数在n与m之间
    
     
    No.008 grep
    
    1. grep 主要选项及其含义
       -c    只输出匹配行的行数
       -i    不区分大小写
       -h    查询多文件时不显示文件名
       -l    查询多文件时只输出包含匹配字符的文件名
       -n    显示匹配行及行号
       -s    不显示不存在或无匹配文本的错误信息
       -v    显示不包含匹配文本的所有行
    2. 查询空行 grep '^$' filename
    3. 类名及等价的正则表达式
       [[:upper:]]    =    [A-Z]
       [[:lower:]]    =    [a-z]
       [[:digit:]]    =    [0-9]
       [[:alnum:]]    =    [0-9a-zA-Z]
       [[:space:]]    =    空格或tab键
       [[:alpha:]]    =    [a-zA-Z]
    
     
    No.009 AWK
    
    # awk的主要作用在于将文本分成各个区域,便于分别进行处理
    1. awk -F指定分隔符,-f指定awk脚本
       ex. awk -F: 'commands' input-file(s)
       ex. awk -f awk-script input-file(s)
    2. awk 分隔出的域用$1,$2...$n来表示,其中$0表示所有域
    3. awk 条件操作符 <, <=, >=, ==, !=
       ~  匹配正则表达式   !~  不匹配正则表达式
    4. awk 内置变量
       ARGC        命令行参数个数
       ARGV        命令行参数排列
       ENVIRON     支持队列中系统环境变量的使用
       FILENAME    awk浏览的文件名
       FNR         浏览文件的记录数
       FS          设置输入域分隔符,等价于命令行-F选项
       NF          记录的域个数
       NR          已读的记录数
       OFS         输出域分隔符
       ORS         输出记录分隔符
       RS          控制记录分隔符
       ex. awk '{print NF,NR,$0} END{print FILENAME}' input-file
    5. awk 字符串函数
       gsub, index, length, match, split, sprint, sub, substr, substr
    6. awk 中的printf函数可以控制格式化输出
    7. awk 的循环结构 For (element in array) print array[element]
    
     
    No.010 sed
    
    # sed的主要作用在于过滤和查找文本中的特定内容
    1. sed 命令格式: sed [options] sed-command input-file
                      sed [options] -f sed-script input-file
    
     
    No.011 合并和分隔文件
    
    1. sort, uniq, join, cut, paste, split
    
     
    No.012 tr的用法
    
    1. 去除oops.txt中的重复字符 tr -s "[a-z]" < oops.txt
    2. 去除oops.txt中的空行 tr -s "[
    ]" < oops.txt
    3. oops.txt中小写转大写 tr -s "[a-z]" "[A-Z]" < oops.txt
    
     
    No.013 登录环境
    
    1. /etc/passwd 保存所有账号的基本信息(不包括密码)
    2. /etc/profile 基本的配置信息,登录时读取此文件
    3. $HOME/*profile 各个用户的profile文件,会覆盖系统的profile文件
    4. $HOME/*logout logout(键入命令exit时)是执行的脚本
    
     
    No.014 环境和shell变量
    
    1. shell变量的设置方式
       Variable-name=value    设置实际值到variable-name
       Variable-name+value    如果设置了variable-name,则重设其值
       Variable-name:?value   如果未设置variable-name,显示未定义用户错误信息
       Variable-name?value    如果未设置variable-name,显示系统错误信息
       Variable-name:=value   如果未设置variable-name,设置其值
       Variable-name:-value   如果未设置variable-name,就用value,但是不设置variable-name
    2. 设置只读变量  readonly variable-name
    3. export variable-name 可以将变量导入到子shell中
    4. shell脚本的参数 $0表示脚本名字,$1表示第一个参数......$9表示第九个参数
    5. 特定shell变量
       $#    参数个数
       $*    用一个字符串显示所有参数
       $$    脚本运行的当前进程ID
       $!    后台运行的最后一个进程的进程ID
       $@    与$*相同,每个参数作为独立的字符串
       $-    显示shell的当前选项,与set命令相同
       $?    显示shell命令的退出状态,0表示无错误,其他表示有错
    
     
    No.015 引号
    
    1. 双引号("") 其中引用的变量会替换为变量值。比如:
        [wangyb@localhost bash]$ STR="Hello world"
        [wangyb@localhost bash]$ echo "$STR"
        Hello world
    2. 单引号('') 忽略变量和其他特殊字符,单引号内任何内容都当成字符串显示。比如:
        [wangyb@localhost bash]$ STR="Hello world"
        [wangyb@localhost bash]$ echo '$STR'     
        $STR
    3. 单引号和双引号同时使用时,谁在外面谁起作用。比如
        [wangyb@localhost bash]$ echo "'$STR'"
        'Hello world'
        [wangyb@localhost bash]$ echo '"$STR"'
        "$STR"
    4. 反引号(``) 反引号中的内容被当做命令来执行。比如
        [wangyb@localhost bash]$ VAR=`date`
        [wangyb@localhos bash]$ echo $VAR
        Thu Dec 22 22:08:07 JST 2011
    5. 转义符()
    
     
    No.016 Shell脚本介绍
    
    1. 脚本的第一行一般以  #!/bin/bash  开始
    2. 给脚本加入执行权限后就可以运行脚本了
    
     
    #No.017 条件测试
    
    1. 测试语法  test condition 或者 [ condition ] 使用方括号是注意在condition两边加上空格
    2. 文件状态测试
       -d    目录            -s    文件长度大于0
       -f    正规文件        -w    可写
       -L    符号连接        -u    文件有suid位设置
       -r    可读            -x    可执行
       例子如下:测试是否为目录,也可以用 test -d bash.sh 来代替方括号
        [root@localhost bash]# [ -d bash.sh ]
        [root@localhost bash]# echo $?
        1
        [root@localhost bash]# [ -d . ]     
        [root@localhost bash]# echo $?
        0
    3. 逻辑与 -a  逻辑或 -o  逻辑否 ! 例子如下:
        [root@localhost bash]# [ -d bash.sh -a -d . ]
        [root@localhost bash]# echo $?
        1
        [root@localhost bash]# [ -d bash.sh -o -d . ] 
        [root@localhost bash]# echo $?
        0
        [root@localhost bash]# [ ! -d bash.sh -a -d . ]   
        [root@localhost bash]# echo $?
        0
        [root@localhost bash]# [ ! -d bash.sh -a ! -d . ]
        [root@localhost bash]# echo $?
        1
    4. 字符串测试  [ string1 string_operator string2 ] 或者 [ string_operator string ]
       string_operator可为:=      两个字符串相等
                            !=     两个字符串不等
                            -z     空串
                            -n     非空串
    5. 数值测试  [ "number1" num_operator "number2" ]
       num_operator可为:  -eq     数值相等
                           -ne     数值不等
                           -gt     number1 > number2
                           -lt     number1 < number2
                           -le     number1 <= number2
                           -ge     number1 >= number2
       例子:   [root@localhost bash]# [ "100" -gt "101" ]
                [root@localhost bash]# echo $?
                1
                [root@localhost bash]# [ "100" -lt "101" ]
                [root@localhost bash]# echo $?           
                0
    6. expr语法  expr arg1 operator arg2
       例子:变量自增
                [root@localhost bash]# COUNT=1       
                [root@localhost bash]# echo $COUNT   
                1
                [root@localhost bash]# COUNT=`expr $COUNT + 1`
                [root@localhost bash]# echo $COUNT           
                2
    
     
    No.018 控制流结构
    
    1. if语句格式
       if 条件1
       then
            执行命令1
       elif 条件2
       then
            执行命令2
       else
            执行命令3
       fi
    2. case语句格式
       case 值 in
       模式1)
           命令1
           ;;
       模式2)
           命令2
           ;;
       ......
       easc
    其中的“模式”可以是 *(任意字符), ?(任意单字符), [..](范围内任意字符)
    “模式”中还可以是使用 | (比如 str1|str2 表示str1和str2都可以)
    3. for语句格式
       for 变量名 in 列表
       do
           命令1
           命令2 ......
       done
    4. until语句格式
       until 条件
             命令1
             ......
       done
    一直执行至条件为真时才结束,至少执行一次
    5. while语句格式
       while 条件
             命令1
             ......
       done
    6. 利用IFS来改变读取内容的分隔符
    7. 利用break和continue控制循环的执行
    
     
    No.019 Shell函数
    
    1. shell函数格式
       函数名 ()
       {
           命令1
           ......
       }
    或者
       function 函数名 ()
       {
           命令1
           ......
       }
    2. 引用其他脚本中函数  . /pathname/funcfile (<点><空格><斜线><文件完整路径名>或者<点><空格><文件相对路径名>)
    3. 函数中通过 $1, $2,......$9来获取参数
    
     
    No.020 向脚本传递参数
    
    1. 使用shift依次获取各个参数,比如
       while [ $# -ne 0 ]
       do
             echo $1  # 通过shift,$1将依次表示各个参数
             shift
       done
    2. getopts语法格式 getopts operation-string variable。
    
     
    No.021 屏幕输出
    
    1. tput 控制屏幕上的字符输出,比如加粗字符,隐藏光标等等
    2. 改变字符颜色的方法,比如
       echo "<CTRL-V><ESCAPE>[40;32m"   设置背景黑色(40), 字符绿色(32)
    
     
    No.022 屏幕输入
    
    1. 输入时进行validation check
       “送进的是垃圾,出来的肯定是垃圾”
    
     
    No.023 调试脚本
    
    1. shell不会对错误进行精确定位,当shell打印错误后,需要观察报错的整个代码段
    2. 在脚本中利用set命令辅助调试
       set -n    读命令但不执行
       set -v    显示读取的所有行
       set -x    显示所有命令及参数
       - 表示打开; + 表示关闭;set +x 表示关闭显示所有命令及参数
    
     
    No.024 shell 嵌入命令
    
    1. set 命令在脚本中设置脚本的运行参数
    2. times命令打印shell消耗时间和运行命令消耗时间 ???
    3. type 命令查询命令是否有效及命令类型
    4. ulimit 命令设置运行在shell上的显示限制
    5. wait 命令是父进程等待子进程完成
    
     
    No.025 深入讨论<<
    
    1. 创建文本  ex. cat >> file <<end
                     > (输入内容)
                     > end
       (输入内容)将被追加到file中
    
     
    No.026 shell工具
    
    1. 用日期做文件名,ex.  $ Myfile=`date +%Y%m%d%H%M%S`
                            $ touch $Myfile
    2. 脚本中的临时文件名中加入进程号,可以保证文件名唯一,并在脚本结束时删掉文件
       ex. TmpFile1=/tmp/tempfile1.$$
           TmpFile2=/tmp/tempfile2.$$
           rm /tmp/*.$$
    3. 常用信号
       信号    信号名        含义
       1       SIGHUP        挂起或父进程被杀死
       2       SIGINT        来自键盘的中断信号,通常是<CTRL-C>
       3       SIGQUIT       从键盘退出
       9       SIGKILL       无条件终止
       11      SIGSEGV       段(内存)冲突
       15      SIGTERM       软件终止(缺省杀进程信号)
    4. trap 捕获信号 语法 trap "do-something" signal(s)
       ex.  trap "" 2 3           忽略信号2和信号3,用户不能终止该脚本
            trap "commands" 2 3   如果捕捉到信号2和信号3,就执行相应的commands
            trap 2 3              复位信号2和3,用户可以终止该脚本
    5. eval 对变量进行2次扫描 比如:
            [wangyb@localhost bash]$ VAR1="cat a.sh"
            [wangyb@localhost bash]$ echo $VAR1
            cat a.sh
            [wangyb@localhost bash]$ eval echo $VAR1 
            cat a.sh
            [wangyb@localhost bash]$ eval $VAR1    
            #!/bin/bash
            TMP='HELLO'
            sleep 2
            times
    6. 获取命令行的最后一个参数: ex. $(eval echo $$#)
    7. logger 命令记录日志
    
     
    No.027 几个脚本例子
    
    # 作者常用的几个脚本
    No.028 运行级别脚本
    
    1. 确定当前的运行级别:who -r
    2. 运行级别含义
       运行级别0    启动和停止整个系统
       运行级别1    单用户或管理模式
       运行级别2    多用户模式;部分网络服务被启动。
       运行级别3    正常操作运行模式,启动所有的网络服务
       运行级别4    用户定义的模式,可以使用该级别来定制所需要运行的服务
       运行级别5    有些Unix操作系统变体叫起作为缺省X-windows模式
       运行级别6    重启动
    
     
    No.029 cgi脚本
    # 感觉现在应该不会有人用bash来开发web程序了吧
    No.030 常用shell命令
    1. basename : basename path
    2. cat : cat optiones file
           -v 显示控制字符
    3. compress : compress options files
           -v 显示压缩结果
    4. cp : cp options file1 file2
           -i 覆盖文件之前提示用户确认
           -p 保留权限模式和更改时间
           -r 拷贝相应的目录及其子目录
    5. diff : diff options file1 file2
           -c 按照标准个数输出
           -I 忽略大小写
    6. dircmp : dircmp options directory1 directory2
           -s 不显示相同的文件
    7. dirname : dirname pathname
    8. du : du options directory
           -a 显示每个文件的大小,不仅是整个目录所占用的空间
           -s 只显示总计
    9. file : file filename
    10. fuser : fuser options file
           -k 杀死所有访问该文件或文件系统的进程
           -u 显示访问该文件或文件系统的进程
    11. head : head -number files
    12. logname : logname (显示当前使用的登陆用户名)
    13. mkdir : mkdir options directory
            -m 在创建目录时按照该选项的值设置访问权限
    14. more : more options files
            -c 不滚屏,而是通过覆盖来换页
            -d 在分页处显示提示
            -n 每屏显示n行
    15. nl : nl options file
            -I 行号每次增加n;缺省为1
            -p 在新的一页不重新计数
    16. printf : printf format arguments
    17. pwd : pwd
    18. rm : rm options files
            -i 在删除文件之前给出提示(安全模式)
            -r 删除目录
    19. rmdir : rmdir options directory
            -p 如果相应的目录为空目录,则删除该目录
    20. script : script option file
            -a 将输出附加在文件末尾
    21. shutdown : shutdown now
    22. sleep : sleep number(秒数)
    23. strings : strings filename (查看二进制文件中的文本)
    24. touch : touch options filename
            -t MMDDhhmm 创建一个具有相应月,日,时分时间戳的文件
    25. tty : tty 显示所连接的设备或终端
    26. uname : uname options
            -a 显示所有信息
            -s 系统名
            -v 只显示操作系统版本或其发布日期
    27. uncompress : uncompress files
    28. wait : wait processID
    29. wc : wc options files
            -c 显示字符数
            -l 显示行数
            -w 显示单词数
    30. whereis : whereis command_name
    31. who : who options
            -a 显示所有的结果
            -r 显示当前的运行级别
            -s 列出用户名及时间域
    AWK学习笔记:
    ==================================================
    1、匹配第4列包含"Brown"的行
            awk '{if($4~/Brown/) print $0}' grade.dat
    2、匹配第1列包含 Brown 或 Yellow的 行
            awk '{if($1 ~ /Brown/ || $1 ~ /Yellow/) print $0}' grade.dat
    3、匹配第3列等于"48"的行
    awk '$3!="48"{print $0}' grade.dat
    4、内置变量的用法:
     3.1、NR: 已读的记录数: awk '{print $0}END{print NR}' grade.dat
     3.2、NF: 浏览记录的域个数: awk '{print NF"  "NR"  "$0}END{print FILENAME" has  counts: "NF}' grade.dat
                     NF还有一个强大的功能是将变量$pwd的值传入awk并显示其目录,如:echo "bossapp/lele/into" | awk -F/ '{print $0}'   
    5、awk操作符
        设置域变量名: awk '{name=$1;belts=$4; if(belts ~ /Yellow/) print name " is belt "belts}' grade.dat
                                    awk 'BEGIN{scolor="Yellow"}{name=$1;belts=$4; if(belts == scolor) print name " is belt "belts}' grade.dat
        修改域的值:awk '{if($4 ~ /Brown/) {$4="new Brown";$6 -= 1};print $0}' grade.dat
        创建新的域:awk 'BEGIN{newfield=0}{newfield=$6+$7; print $0 "	" newfield; OFS="----"}' grade.dat
        求某列值总和: awk '{total += $6;}END{print "Club student total points : "total}' grade.dat
        打印某个目录下所有文件名及其大小:
        ls -l | awk ' /^[^d]/ {print $8"	"$5; total += $5} END{print "all files size is : " total}'
    6、awk内置字符串函数
            gsub(s,t): awk ' gsub(/48311/, a) {print $0}' grade.dat
            index(s,t): awk '{print index($1,"M.")}' grade.dat
            length(s): awk '{print length($3)}' grade.dat
            match(str,reg): awk '{print match($1,/^J/)}' grade.dat
            split(str,arr,fx): awk '{split("a/b/c/d", arr, "/"); print arr[1]}' grade.dat
            sub(reg, str): awk '{str="poped popo kell"; sub(/op/, "OP", str); print str}' grade.dat
            substr(str, i, len): awk 'BEGIN{str="poped popo kell"}END{print substr(str, 1, 5)}' grade.dat
                                                     $str = "poped popo kell"
                                                     echo $str | awk '{print substr($0,1,7)}'
    7、awk的printf函数
            echo "11" | awk '{printf "%x
    ",$0}'
            awk '{printf "%-15s %s
    ",$1,$2}' grade.dat
            awk '{AGE = 29; if($7 < AGE) print $0}' grade.dat
            df | awk '{print $3}'
    ==================================================
    sed学习笔记:
    ==================================================
    1、匹配指定行
            sed -n '2p' quote.dat
    2、匹配指定范围的行
            sed -n '1,3p' quote.dat       
    3、匹配包含某单词的行
            sed -n '/honeysuckle/p' quote.dat
    4、匹配以ing结尾的某单词的行       
            sed -n '/.*ing/p' quote.dat       
            sed -n '/.*ing/=' -e '/.*ing/p' quote.dat
    5、替换文本
            sed 's/night/NIGHT/' quote.dat        只替换第一次出现的night
            sed 's/night/NIGHT/g' quote.dat        替换全局所有的night
            sed 's/night/NIGHT/w sed.out' quote.dat  将修改结果输出到文件sed.out
    6、插入
            sed -n 's/night/light &/p' quote.dat        在night前插入light
            sed 's/The/& addword/' quote.dat        在The后插入addword
    7、将sed结果写入文件
            sed '1,2 w sed.out' quote.dat            将quote.dat的第1、2行写入到sed.out文件中
    8、在指定行的下一行,附加另外一个文件的内容       
            sed '/night/r sed.out' quote.dat
    9、首次匹配到某单词后退出
            sed '/music/q' quote.dat       
            sed 's/^M//q' quote.dat
    9、例:去掉路径前的/ , 在最后加一个/
            echo $PWD | sed 's////' | awk -F/ '{print $0"/"}'       
    小结:sed 命令主要用于文本过滤及处理
    ==================================================
    sort、uniq学习笔记
    ==================================================
    sort:
    1、按逆序排序
            sort -r vid.dat
    2、按指定域排序
            sort -t: +1 vid.dat
    3、对于数值列排序
            sort -t: +2 vid.dat            先按第一个数字进行排列,再按第二个数字排列,依此类推。和字符排列一样
            sort -t: +2n vid.dat        按数值大小排序
    4、从某域的第n个字符开始排序
            sort -t: +2.2n vid.dat
    5、指定域从1开始计数
            sort -t: -k1 vid.dat
    6、删除重复的行
            sort -u +5 vid.dat
    uniq:
    7、只显示不重复行
            uniq -u a1.c
    8、只显示重复的一行       
            uniq -d a1.c
    9、显示复重的行数
            uniq -c a1.c
    10、只按某个域进行重复排序
            uniq -f2 ab.c
    join:
    11、连接join
            join ab.c abc.c
    12、左连接
            join -a1 ab.c abc.c
    13、右连接
            join -a2 ab.c abc.c
    14、显示指定的域
            join -o 1.1,1.2,2.1,2.2 ab.c abc.c
    15、指定匹配域连接
            join -j1 1 -j2 1 ab.c abc.c
    cut:
    16、以":"为分隔符,剪切域1
            cut -d: -f1 vid.dat
    17、以":"为分隔符,剪切域1、3
            cut -d: -f1,3 vid.dat
    18、以":"为分隔符,剪切域1至3
            cut -d: -f1-3 vid.dat
    19、以空格为分隔符,剪切域1
            cut -d" " -f1 grade.dat
    paste:
    20、粘贴两个域,以@为分隔符
            paste -d@ ab.c abc.c
    21、把列变成行来粘贴
            paste -s ab.c abc.c
    22、管道输入,"-"接受变量输入
            ls | paste a1.c -
    split:
    23、默认按1000行分割,保存为x[aa]--x[zz]
            split grade.dat
    24、指定行数进行分割
            split -2 grade.dat
    ==================================================
    tr学习笔记
    ================================================== 
    1、消除重复的字符串序列
            tr -s "[a-z]" < oo.dat    : 消除重复的小写字母
            tr -s "[0-9]" < oo.dat    : 消除重复的数字
    2、删除空行
            tr -s "[
    ]" < oo.dat
    3、从大字转换成小写
            tr "[A-Z]" "[a-z]" < oo.dat
    4、删除末行的控制字符 "^M"
            tr -s "[
    ]" "[
    ]" < data.f | cat -v
    小结:常用于删除空行,大小字替换,删除控制字符
    ==================================================Shell变量学习笔记
    ==================================================1、若变量定义,则使用默认值
            echo ${variable-name:-defaultValue}
    2、若变量定义,则输出错误信息
            echo ${variable-name:?}    输出系统错误信息
            echo ${variable-name:?"my error message"}    输出自定义错误信息               
    3、将变量设置成只读
            readonly variable-name
    4、查看所有系统变量
            env
    5、系统变量必须用export命令导出
    6、设置传入变量
         $0为脚本名
         $1 为第1个参数
         例如:
         脚本myScript
         find . -name $1 -print
         调用:myScript myparam
         其中myparam当作参数($1)传给脚本中的find命令
    7、一些特定参数变量
         $? : 显示最后一个命令退出状态,0为成功,其他值表明的错误   
         $# : 传递到脚本的参数的个数
         $$ : 显示脚本运行的当前进程ID号
         $* : 以一个字符串显示所有参数
         $@ : 在引号中返回各个参数
    ==================================================条件测试 test 学习笔记
    ==================================================1、文件测试
      有如下参数
         -r : 可读
         -w : 可写
         -x :可执行
         -d :目录
         -f :正规文件
         -u :文件有suid设置
        例:
         test -x wow
         [ -x wow ]
        可以将两个测试结果进行与或操作
        -a : 与 [ -w wow -a -w wow ]
        -o :或 [ -w wow -o -w wow ]
    2、字符串测试
        有五种格式
        test "string"
        test operator "string"
        test "string" operator "string"   
        [ operator "string" ]
        [ "string" operator "string" ]
        其中,operator可以为:
        = :两个字符串相等
        != :两个字符串不等
        -z : 空串
        -n : 非空串
    3、数值测试
        格式:
        test "number1" operator "number2"
        [ "number1" operator "number2" ]
        其中,operator可以为:
        -eq :两数相等
        -ne :两数不相等
        -gt :>
        -lt :<
        -ge :>=
        -le :<=
    4、expr的用法
        4.1 expr用于数值计算
        如:expr 1 + 2
                expr 5 * 3
                expr 5 / 3 : 结果为1,不保留小数位
        4.2 用例:用于循环计数
                loop=0
                loop=`expr $loop + 1`
        4.3 expr用于字符串
                expr "a" = "a" : 特别需要注意的是,如果成功返回1,返回其它值为错误
      4.4 expr用于模式匹配
              value="accounts.doc"
              expr $value : ".*"     统计任意字符出现的次数,也就说统计单词的个数       
              expr $value : ".c"         统计c出现的
    ==================================================控制结构(whilefor、until loop、if then else)
    ==================================================一、if then else 结构
    格式: if 条件1; then
                        语句1;
                 elif 条件2; then
                         语句2;
                 fi       
    例1:名字为空,则输出信息
    #!/bin/sh
    echo -n "Please Enter your name:";
    read NAME;
    if [ "$NAME" = "" ]; then
        echo "you havn't Enter your name!";
    fi
    例2、用户输入名字列表,脚本判断是否包含peter
    #!/bin/sh
    echo -n "Please Enter your name:";
    read NAMELIST
    if echo $NAMELIST | grep "peter" > inle/null 2>&1
    then
        echo "peter is here";
    else
        echo "peter is not here";   
    fi
    例3、文件复制输出检查。自定义错误信息
    #!/bin/sh
    if cp wow wow_copy >>inle/null 2>&1
    then
        echo "复制成功!";
        rm wow_copy;
    else
        echo "脚本`basename $0`发生错误,原因为: cp命令发生错误";
    fi   
    例4、当前目录测试
    #!/bin/sh
    DIRNOW=`pwd`
    if [ "$DIRNOW" != "/" ]
    then
        echo "your are not at the dir of / " >&2
        exit 1
    fi
    例5、测试传递到脚本的参数
    #!/bin/sh
    if [ $# != 3 ]
    then
        echo "`basename $0`的参数个数不正确!应该为3个" >&2
        exit 1
    fi
    echo "arg1: $1"
    echo "arg2: $2"
    echo "arg3: $3"
    例6、登陆测试脚本,用户名和密码必须是peter/hellen--123
    #!/bin/sh
    #设置登陆标志
    INVAIL_USER=yes
    INVAIL_PWD=yes
    #保存当前stty设置
    SAVESTTY=`stty -g`
    echo "welcome to XX System for unix, now you will login to the system"
    echo "please Enter your username:"
    read USERNAME
    #设置输入密码时不可见
    stty -echo
    echo "please Enter your password:"
    read USERPWD
    #恢复之前stty设置
    stty echo
    if [ "$USERNAME" = "peter" -o "$USERNAME" = "hellen" ]
    then
        INVAIL_USER=no
    fi
    if [ "$USERPWD" = "123" ]
    then
        INVAIL_PWD=no
    fi
    if [ "$INVAIL_USER" = "no" -a "$INVAIL_PWD" = "no" ]
    then
        echo "now you have login into System"
    else
        echo "username or password is invaild, please check them and login next time"
        exit 1
    fi
    二、case
    例7、一个简单的case例子,其中配置部份可以用"|"来作为或命令
    #!/bin/sh
    echo "please Enter your choose:"
    read ANS
    case $ANS in
    1) echo "you have selected 1"
    ;;
    2) echo "you have selected 2"
    ;;
    3) echo "you have selected 3"
    ;;
    4) echo "you have selected 4"
    ;;
    5) echo "you have selected 5"
    ;;
    *) echo "`basename $0`发生错误: the choose is not between 1 and 5" >&2
    esac
    三、for
    格式:
    for 变量 in 列表
    do
        程序体
    done
    其中,列表可以是Shell命令
    例8、一个最简单的for循环
    #!/bin/sh
    for loop in 1 2 3 4 5
    do
        echo $loop
    done
    例9、将ls的结果打印出来
    #!/bin/sh
    for loop in `ls`
    do
        echo $loop
    done
    例10、将参数打印出来
    #!/bin/sh
    for loop in $*
    do
        echo $loop
    done
    例11、在for程序体中使用find,实现多文件查找
    for loop
    do
        find . -name $loop -print
    done
    例12、统计当前目录下的文件数目
    #!/bin/sh
    count=0
    for loop in *
    do
        count=`expr $count + 1`
    done
    echo "there is $count files"
    其实用ls | wc -l 也能统计出当前目录下文件的个数
    四、until
    例13、查看root用户是否登陆,登陆则给其发个邮件
    #!/bin/sh
    IS_ROOT=`who | grep root`
    until [ "$IS_ROOT" ]
    do
        sleep 5
        echo "no login"
    done
    五、while
    例14、输出1-10
    #!/bin/sh
    i=0
    while [ $i -lt 10 ]
    do
        echo $i
        i=`expr $i + 1`
    done
    例15、从键盘读字符串,按ctrl+D结束读入
    #!/bin/sh
    echo -n "Enter: "
    while read name
    do
        echo "output: $name"
    done
    例16、用while循环读取文件的每一行
    #!/bin/sh
    while read FLINE
    do
        echo $FLINE
    done < data.f
    例17、以:为分隔符,依次读取域信息
    #!/bin/sh
    SAVEIFS=$IFS
    IFS=:
    while read NAME DEPT
    do
        echo "$NAME	 $DEPT	"
    done < name.txt
    IFS=$SAVEIFS
    例18、默认以空格为域分隔符
    #!/bin/sh
    while read f1 f2
    do
        echo "$f1-----------$f2"
    done < name.txt
    说明下:无论是以什么作为分隔符,read后面的变量个数要与域的个数相同,这样就可以用变量一一对应域了
    例19、每回读两行
    #!/bin/sh
    while read rline1
    do
        read rline2
        echo $rline1
        echo $rline2
        echo "--------------------------"
    done < name.txt
    例20、while循环和文件描述符 做文件备份,按行读取,写到另一个文件
    #!/bin/sh
    FNAME=wow
    FNAME_BAK=wow.bak
    if [ -s $FNAME ]; then
        #将wow描述为输入文件
        exec 3<$FNAME
        #将wow描述为输出文件
        exec 4>$FNAME_BAK
        while :
        do
            read LINE
            if [ "$?" != "0" ]; then
                #关闭输入和输出
                exec 3<&-
                exec 4<&-
                exit 0
            fi
            echo $LINE >&4
        done  <&3
    else
        echo "文件不存在!"
    fi
    六、breakcontinue
    break 2 可以跳出两重循环
    例21、用break(continue)跳出两重循环
    #!/bin/sh
    while :
    do
        echo "这是第一重循环"
        while :
        do
            echo "这是第二重循环"
            break 2
        done
    done
    ==================================================自定义函数
    ==================================================1、定位文件: . 文件名
    这样就可以把文件中包含的函数当成系统函数了,直接调用即可,但只能在本终端运行,离开本终端就不行了
    例22、自定义查找函数,可查找多个文件
    #!/bin/sh
    myfind() {
        if [ $# -lt 1 ]; then
            echo "至少有一个参数"
            return 1
        fi
        for loop in "$@"
        do
            find . -name $loop -print
        done
    }
    例23、检查名字是否全是英文
    #!/bin/sh
    #定义检查函数
    check_name() {
        _PARAM_NAME=$1
        _PARAM_NAME=`echo $1 | awk '{if($0 ~ /^[a-zA-Z]+$/) print "1"}'`
        if [ "$_PARAM_NAME" != "" ]; then
            return 0
        else
            return 1
        fi   
    }
    #定义错误提示函数
    name_error() {
        echo "$@ 包含非法字符,请确保全部是英文字母"
    }
    #开始调用
    while :
    do
        echo "请输入你的姓氏:"
        read FIRST_NAME
        if check_name $FIRST_NAME; then
            break
        else
            name_error $FIRST_NAME
        fi
    done
    while :
    do
        echo "请输入你的名字:"
        read SEC_NAME
        if check_name $SEC_NAME; then
            break
        else
            name_error $SEC_NAME
        fi
    done
    echo "你的名字为:$FIRST_NAME $SEC_NAME"
    
    ==================================================向脚本传递参数
    
    ==================================================一、shift的作用:指向参数的位置偏移一位,从1开始
    例24、用shift实现参数位置偏移
    #!/bin/sh
    while [ $# -ne 0 ]
    do
          echo $1
          shift
    done
     
    例25、自定义大小写转换命令
    #!/bin/sh
    #文件内容的大小写转换命令
    FNAME=""
    OPT="no"
    CASEOPT=""
    #自定义错误函数
    error_msg() {
          echo "`basename $0`: Error the conversion faild, please enter `basename $0` -help" &2
          exit 1
    }
     
    #大小写转换
    l_u_case() {
          for LOOP in $FNAME
          do
               case $CASEOPT in
               lower)cat $LOOP | tr "[a-z]" "[A-Z]" >>l_rslt.dat
               ;;
               upper)cat $LOOP | tr "[a-z]" "[A-Z]" >>u_rslt.dat
               ;;
               esac
          done
    }
     
    #若不输入参数,则报错
    if [ $# -eq 0 ]
    then
          error_msg
    fi
     
    #循环遍历参数,进行处理
    while [ $# -gt 0 ]
    do
          case $1 in
               -l)OPT="yes"
               CASEOPT="lower"
               shift
               ;;
               -u)OPT="yes"
               CASEOPT="upper"
               shift
               ;;
               -help)echo "this is help"
                     exit 0   
               ;;
               -*) error_msg
               ;;
               *) FNAME=$1
               OPT="no"
               shift
               ;;
          esac
    done
     
    #下面开始处理文件
    if [ $OPT = "no" ]
    then
          if [ -f $FNAME ]
          then
               l_u_case
               exit 0
          else     
               echo "$FNAME is not a file ,please check it"
               exit 1
          fi
    else 
          exit 0
    fi
     
    二、getopts: 获取用"-"开始的参数,如-fu, 其作用与-f -u 是一样的
    例26、
    #!/bin/sh
    while getopts :afu: OPTS
    do
          case $OPTS in
               a)echo "ALL"
               ;;
               f)echo "FULL"
               ;;
               u)echo "USER"
               ;;
               ?)echo "error" >&2
               exit 1
               ;;
          esac
    done
     
    例27、-u选项必须带值,否则报错(若要屏蔽系统错误,在前面加:即可); 带入的值用变量OPTARG接收
    #!/bin/sh
    while getopts :afu: OPTS
    do
          case $OPTS in
               a)echo "ALL"
               ;;
               f)echo "FULL"
               ;;
               u)echo "USER--$OPTARG"
               ;;
               ?)echo "error"
               exit 1
               ;;
          esac
    done
    
    
    ==================================================一些比较杂的东西
    ==================================================一、信号:系统向脚本发出的信息或命令,有如下含义:
          信号            信  号  名                     含     义
          1                     SIGHUP                             挂起或父进程被杀死
          2                     SIGINT                              来自键盘的中断信号,通常是ctrl + c
          3                     SIGQUIT                            从键盘退出
          9                     SIGKILL                       无条件中止
          11                   SIGSEGV                           段(内存冲突)
          15                   SIGTERM                           软件中止,默认的
           
    二、捕捉信号
    trap     
    例28、当按下键盘中止后,用trap捕捉到信号,进行处理
    #!/bin/sh
    trap "tp_cmd" 2
     
    tp_cmd() {
          echo "hahahaha"
          exit 1
    }
    loop=0
    while :
    do
          loop=`expr $loop + 1`
          echo $loop
          sleep 1
    done      
     
    例29、在某一段关键处理过程,可以屏蔽信号,从而保证完整性
    #!/bin/sh
    #设置屏蔽信号
    trap "echo you can't interrupt me" 1 2 3 15
    
    
    ###这一段我是不希望被打断的,否则后果很严重噢,除非你用kill -9  begin
    loop=0
    while :
    do
          loop=`expr $loop + 1`
          echo $loop
          if [ "$loop" -eq "6" ]
          then
               break
          fi
          sleep 1
    done
    ###这一段我是不希望被打断的,否则后果很严重噢,除非你用kill -9  end
     
    #自定义退出函数
    myexit() {
          echo "hahahaha"
          exit 1
    }
    ##现在可以打断了,没关系
    trap "myexit" 1 2 3 15
    while :
    do
          loop=`expr $loop + 1`
          echo $loop
          sleep 1 
    done
     
     
    三、eval
    例30、自动生成变量
    #!/bin/sh
    loop=0
    name="a"
    while :
    do
          loop=`expr $loop + 1`
          eval `echo "$name$loop=$loop"`
          echo $name$loop=$loop
          if [ "$loop" -eq "6" ]
         then
              exit 0
         fi
    done
  • 相关阅读:
    SQL Server 2005 System Views Map
    SQL语句实现移动数据库文件
    重写系统存储过程:sp_spaceused
    MSSQL2005中的架构与用户
    根据时间段计算有n年n月n天
    Linux中的环境变量 (转)
    计算工龄,格式为n年n月n天
    学习递归CTE
    分区表应用例子
    根据备份文件直接还原数据库
  • 原文地址:https://www.cnblogs.com/timssd/p/4676411.html
Copyright © 2020-2023  润新知