shell编程基础

花了两天看了下shell编程的一些内容,结合以前记得笔记做个小结。linux的shell编程主要是用于维护服务器操作的自动化,从安装软件,到启动服务,都可以使用脚本来完成。

前言

  花了两天看了下shell编程的一些内容,结合以前记得笔记做个小结。linux的shell编程主要是用于维护服务器操作的自动化,从安装软件,到启动服务,都可以使用脚本来完成。

  linux下的shell有很多种,但我们主要用的是bash

  感觉下来,shell的一些优势:

  1. 不需要额外的环境,linux自带bash。
  2. 完成简单的操作需要的代码量较少。
  3. 和原生程序交互比较方便。比如处理文本的时候需要用到的awk和sed,熟练使用后比较方便。

语法基础

1. bash内置变量和常见表达式

  • 命令行参数(非指定), 对于脚本参数,和自定义函数参数而言,$0代表脚本本身的名字,$1到$9代表1到9个参数,从第10个参数开始需要用${n}来表示变量。
  • 常见的符号。$,取变量的值,${}和$()分别代表在在本身的shell中执行命令和在子shell中执行命令。{}还有分割变量与文本的左右例如$varAA就会报错,需要携程${var}AA的形式。
  • 扩展运算,$[cmd],$((cmd))进行数字运算,`expr x operator y`也可能达到相同的效果。
  • >>和<< 重定向,|管道。
  • 定义数组 var=(),生成a到z的list,var=({a..z})
  • 更多表达式参考 https://www.cnblogs.com/farwish/p/4806018.html

2. bash中的过程控制

  • 分支选择
    if分支选择语法
    1
    2
    3
    4
    5
    6
    7
    if [ cond ]; then
    cmd
    elif [ cond ];then
    cmd
    else
    cmd
    fi
    cond 可用test命令
    例如 test -e /etc/passwd 或者 []代替test [ -e /etc/passwd ]

选择分支语法

1
2
3
case word in
[ [(] pattern [| pattern]…) command-list ;;]…
esac

举例
1
2
3
4
5
6
7
8
9
echo -n "Enter the name of an animal: "
read ANIMAL
echo -n "The $ANIMAL has "
case $ANIMAL in
horse | dog | cat) echo -n "four";;
man | kangaroo ) echo -n "two";;
*) echo -n "an unknown number of";;
esac
echo " legs."

  • 循环
    for循环

    1
    2
    3
    4
    5
    6
    7
    8
    9
    for var in list;
    do
    cmds;
    done

    for((exp1;exp2;exp3));
    do
    cmds;
    done

    while循环和until循环

    语法

    1
    while \ until [ test cmd ]; do cmds;done

    while和until的唯一区别是until的退出条件是test命令返回1 也就是不成立循环,而while循环则相反

3. 处理字符串

  1. shell内置处理字符串,准确说shell中有两种处理字符串的方式。一种是${var:start:length},另外一种则是通过通配符的方式掐头去尾。
  • 例如 ${var%%$SUBSTR},最长匹配去尾
  • ${var##$SUBSTR},最长匹配去头
  • ${var\$old\$new} 将旧的字符串替换为新的字符串(第一个) \\全部替换,#匹配开头,%匹配结尾
  1. cut命令 cut -f 1,7 -d ‘分隔符’ 去第一块和第七块
  2. awk -F ‘分隔符’ ‘条件{action}’ 文本
  3. sed

4. 一些实例

  1. 随机函数
    array[@]或者array[*]取数组所有的变量,数组下标从1开始。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    get_random(){
    length=$1
    payload=({a..z})
    payload+=({0..9})
    l=${#payload[@]}
    result=''
    for((i=0;$i<$length;i++))
    do
    r=$[$RANDOM%$l]
    result=$result${payload[$r-1]}
    done
    printf "\n"
    echo $result
    }

    for i in `seq 1 20`
    do

    result=$(get_random 6)
    echo $result
    done
  2. 统计每个ip的访问量并按从大到小排序

    1
    2
    3
    4
    5
    #! /bin/bash

    path=$HOME
    now=$(date +%Y%m%d)
    echo $(ps aux | awk '{if($1 in map){map[$1]+=1}else{map[$1]=1}} END{for(x in map){printf("用户名:%-20s\t\t进程数:%d\r",x,map[x]) }}')>>$path/$now.log