Shell常用的算法总结

运维思想

  • 做事情若有多种选择,就会比较轻松,没有选择就会比较痛苦。
  • 汇报领导交代的任务就要给领导多种选择,只有一种选择,老大没得选,不叫有能力。
  • 有两种选择,老大左右为难,不叫有能力。有三种或以上的选择,才叫有能力。
  • 提交解决方案、面试提问、笔试等都是如此,甚至老男孩写书也会尽量给读者多种思路,供读者选择。

判断一个字符串是否为数字的多种思路

  • 利用expr做计算时变量或字符串必须是整数的规则,把一个变量或字符串和一个已知的整数(非0)相加,看命令返回值是否为0.若为0,则做加法的变量或字符串为整数,否则就不是整数。

    1
    expr $变量 + 1 > /dev/null 2>&1 ; [ $? -eq 0 ] && echo Number || echo NoNumber
  • 使用sed加正则表达式,删除一个字符串中的所有数字,看字符串的长度是否为0,如果不为0,则说明不是整数,否则是整数。

    1
    [ -n "`echo $变量 | sed 's/[0-9]//g'`" ] && echo NoNumber || echo Number
  • 使用变量的子串替换的方法

    1
    [ -z "`echo "${变量//[0-9]/}"`" ] && echo Number || echo NoNumber
  • 变量的子串替换加正则表达式:如果变量的长度不为0,并且把变量中的非数字部分删除,然后再看结果是不是等于变量本身,如果两者都成立,则变量就是数字。

    1
    [ -n "$变量" -a "$变量" = "${变量//[^0-9]/}" ] && echo Number || echo Nonumber
  • 利用=~符号进行判断:

    1
    [[ $变量 =~ ^[0-9]+$ ]] && echo Number || echo Nonumber
  • 利用bc判断字符串是否为整数(仅为参考方法,不推荐,因为有Bug)

    1
    echo "$变量" | bc | [ $? -eq 0 ] && echo Number || echo Nonumber

判断字符串长度是否为0的多种思路

  • 使用字符串条件表达式-z-n的语法如下:

    1
    2
    [ -z "$变量" ] && echo NoChar || echo Char
    [ -n "$变量" ] && echo Char || echo NoChar
  • 使用变量子串判断的语法如下:

    1
    [ ${#变量} -eq 0 ] && echo Char || echo NoChar
  • 使用expr length函数判断的语法如下:

    1
    [ `expr length "$变量"` -eq 0 ] && echo NoChar || echo Char
  • 使用wc-L参数统计判断的语法如下:

    1
    [ ` echo $变量 | wc -L ` -eq 0 ] && echo Nochar || echo Char
  • 使用awk length函数判断的语法如下:

    1
    [ `echo $变量 | awk '{print length}'` -eq 0 ] && echo Nochar || echo Char

grep精准过滤单词的三种方法

  • grep -w "theshu" filename
  • grep "\btheshu\b" filename
  • grep "^theshu$" filename

用while循环按行读取文件的几种常见方式

  • 方法1:采用exec读取文件,然后进入while循环处理

    1
    2
    3
    4
    5
    6
    exec < FILE
    sum=0
    while read line
    do
    cmd
    done
  • 方法2:使用cat读取文件内容,然后通过管道进入while循环处理

    1
    2
    3
    4
    cat FILE_PATH | while read line
    do
    cmd
    done
  • 方法3:在while循环结尾done处通过输入重定向指定读取的文件

    1
    2
    3
    4
    while read line
    do
    cmd
    done < FILE

Linux系统产生随机数的6种方法

  • 方法1:通过系统环境变量$RANDOM实现,示例代码如下:

    1
    2
    3
    4
    [root@theshu ~]# echo $RANDOM
    23156
    [root@theshu ~]# echo $RANDOM
    31167
    • RANDOM的随机数范围为0~32767,因此,加密性不是很好,可以通过在输出的随机数后增加加密字符串(就是和密码生成有关的一个字符串)的方式解决,最后再一起执行md5sum操作并截取结果的后n位,这样一来,就无法根据随机数范围来猜出具体结果了。
    • 示例
      1
      echo "theshu$RANDOM" | md5sum | cut -c 8-15
  • 方法2:通过openssl产生随机数,示例代码如下:

    1
    2
    3
    4
    5
    [root@theshu ~]# openssl rand -base64 8
    8BZOHW5d36Y=
    [root@theshu ~]# openssl rand -base64 80
    PEJx3xbF7Om4aZW+yovQZCY1szJ3tgNEZaEjWJj5kJCIiJT8RW6UQ+hJou5GyThd
    MgdI9ZnCnQGYBGhe52sYzKMkoB6U7JM4P7QWRmrrElo=
    • 令数字与大小写字符相结合,并且带上特殊字符,可以达到很长的位数,这样的随机数很安全。
  • 方法3:通过时间(date)获取随机数,示例代码如下:

    1
    2
    3
    4
    [root@theshu ~]# date +%s%N
    1519866764460747105
    [root@theshu ~]# date +%s%N
    1519866766036338040
  • 方法4:通过/dev/urandom配合chksum生成随机数,示例代码如下:

    1
    2
    [root@theshu ~]# head /dev/urandom | cksum
    1635584842 3081
    • /dev/random设备存储着系统当前运行环境的实时数据。它可以看作系统在某个时候的唯一值,因此可以用作随机数元数据。我们可以通过文件读取的方式,读到里面的数据。/dev/urandom这个这杯的数据与random里的一样。只是,它是非阻塞的随机数发生器,读取操作不会产生阻塞。
  • 方法5:通过UUID生成随机数,示例代码如下:

    1
    2
    3
    4
    [root@theshu ~]# cat /proc/sys/kernel/random/uuid
    412be67d-1f8f-422b-b925-ea7337120890
    [root@theshu ~]# cat /proc/sys/kernel/random/uuid
    fbdd40ed-3d5b-4f30-983a-2ccabf1c871c
    • UUID码全称是通用唯一识别码(Universally Unique Identifier,UUID),它是一个软件建构的标准,亦为自由软件基金会的组织在分布式计算机环境领域的一部分。
    • UUID的目的是让分布式系统中的所有元素都能有唯一的辨识信息,而不需要通过中央控制端来做识别信息的指定。如此一来,每个人都可以创建不与其他人发生冲突的UUID。在这样的情况下,就不需要考虑数据库创建时的名称重复问题了。它会让网络中任何一台计算机所生成的UUID码都是互联网整个服务器网络中唯一的编码。它的原信息会加入硬件、时间、机器当前运行信息等。
  • 方法6:使用expect附带的mkpasswd生产随机数

    • mkpasswd命令依赖于数据包expect,因此必须通过yum install expect -y命令先安装该数据包:

      1
      2
      3
      4
      5
      6
      [root@theshu ~]# mkpasswd -l 9 -d 2 -c 3 -C 3 -s 1
      sCc7OR2p-
      [root@theshu ~]# mkpasswd -l 9 -d 2 -c 3 -C 3 -s 1
      bM95NC\om
      [root@theshu ~]# mkpasswd -l 9 -d 2 -c 3 -C 3 -s 1
      Q5yi2JvP}
    • 相关参数说明如下:

      1
      2
      3
      4
      5
      -l # (length of password,default = 9) #<==指定密码长度
      -d # (min # of digits,default = 2) #<==指定密码中数字的数量
      -c # (min # of lowercase chars,default = 2) #<==指定密码中小写字母的数量
      -C # (min # of uppercase chars,default = 2) #<==指定密码中大写字母的数量
      -s # (min # of special chars,default = 1) #<==指定密码中特殊字符的数量
  • 上面的随机数长短不一,统一格式化呢?解答:使用md5sum命令。示例如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    [root@theshu ~]# mkpasswd -l 9 -d 2 -c 3 -C 3 -s 1 | md5sum | cut -c 2-10
    d161a4cd6
    [root@theshu ~]# cat /proc/sys/kernel/random/uuid | md5sum | cut -c 2-10
    424e67af0
    [root@theshu ~]# head /dev/urandom | cksum | md5sum | cut -c 2-10
    8db5ea345
    [root@theshu ~]# date +%s%N | md5sum | cut -c 2-10
    560f1cbf4
    [root@theshu ~]# openssl rand -base64 80 | md5sum | cut -c 2-10
    5e88fdf5c
    [root@theshu ~]# echo "theshu$RANDOM" | md5sum | cut -c 2-10
    63d0f00c3
0%