反思

由于自已从事java后端开发这块的工作,有时候会登录到远程Linux服务器查看日志,分析错误,统计数据等场景,会键入大量的命令。突发奇想,可以通过编写脚本(Shell)来实现工作简化。提到Linux Shell,自已曾经也系统化学习过,买过关于Shell编程的书籍。但是当自已要开始编写脚本的时候,才发现一些基础的知识都可能遗忘掉,比如声明变量、基础语法(if-elsefor)、方法定义 (function)、自带Linux命令等一些基础的东西。只能通过百度一点点组装,完成最后脚本的编写,花费了大量的时间以及精力,不断地去重复搜索与记忆。也许自已不是一个运维工程师,不需要去尝试写这些东西。但是编写脚本,简化工作,节约时间,最后受益的人是自已,不是别人。

  1. **只有畏惧不敢尝试才是真正的失败!**

本篇仅是对自已搜索知识的记录,方便下次查找!!!

Shell接收用户输入

read命令读取用户输入
Shell脚本交互之:自动输入密码

通过read命令

    示例:
    read test
    echo $test

Shell中声明函数

Shell函数:Shell函数返回值、删除函数、在终端调用函数

通过funcation name(){}方式声明函数,{}中放入需要执行的命令。通过name即可调用函数

    声明函数
    function printEcho()
    {
        echo "hello world!!!"
    }
    调用函数
    printEcho

if判断

Linux shell if判断语句
对用户输入的判断的shell实现代码

几种方式:

  • if
    stdout=` ps -ef|grep hexo |grep -v grep|awk '{print $2}' `
    if [ -n "$stdout" ]
    then
      echo -n "有货"
    fi
  • if-else
    stdout=` ps -ef|grep hexo |grep -v grep|awk '{print $2}' `
    if [ -n "$stdout" ]
    then
      echo -n "有货"
    else
      echo -n "没货"
    fi
  • if-elif-else
    if [ -z $num ];then
      exit 0
    elif  [ $num = 1 ];then
     startServer
    elif [ $num = 2 ];then
     stopServer
    elif [ $num = 3 ];then
     getPID
    elif [ $num = 4 ];then
     autoUpdate
     startServer
    elif [ $num = 5 ];then
     autoDeploy
    elif [ $num = 6 ];then
     updateSou
    else
     echo "Input error !!!!!!"
    fi
  • 判断表达式
    关于文件属性的判断式
    -a 如果文件存在
    -b 如果文件存在,且该文件是区域设备文件
    -c 当file存在并且是字符设备文件时返回真
    -d 当pathname存在并且是一个目录时返回真
    -e 当pathname指定的文件或目录存在时返回真
    -f 当file存在并且是普通文件时返回真
    -g 当由pathname指定的文件或目录存在并且设置了SGID位时返回为真
    -h 当file存在并且是符号链接文件时返回真,该选项在一些老系统上无效
    -k 当由pathname指定的文件或目录存在并且设置了“sticky”位时返回真
    -r 当由pathname指定的文件或目录存在并且可读时返回为真
    -s 当file存在文件大小大于0时返回真
    -t 文件描述符 如果文件描述符是开启的,且链接了某一个终端
    -u 当由pathname指定的文件或目录存在并且设置了SUID位时返回真
    -w 当由pathname指定的文件或目录存在并且可执行时返回真。一个目录为了它的内容被访问必然是可执行的。
    -x 如果文件存在,且该文件有可执行的属性
    -O 当由pathname指定的文件或目录存在并且被子当前进程的有效用户ID所指定的用户拥有时返回真。
    -G 如果文件存在,且该文件为有效的群组 id 所拥有
    -L 如果该文件存在,且该文件是符号链接文件
    -S 如果该文件存在,且该文件是Socket文件
    -N 如果该文件存在,且该文件自上次读取后曾修改过
    文件1 –nt 文件2 如果文件1比文件2新,或者文件1存在,文件2不存在
    文件1 –ot 文件2 如果文件1比文件2旧,或者文件1不存在,文件2存在
    文件1 –ef 文件2 如果文件1和文件2 引用到相同的设备和 inode 编号
    关于字符串的条件判断式

linux if 命令判断条件总结

-z 空串 (如果字符串长度为0)
-n 非空串 (如果字符串长度不为0)
字符串 如果字符串长度不为0
!= 如果两个字符串不相等
= 如果两个字符串相等
== 如果两个字符串相等
字符串 1 < 字符串 2 如果字符串1小于字符串2
字符串 1 > 字符串 2 如果字符串1大于字符串2
关于算式的条件判断
-eq 等于
-ne 不等于
-gt 大于
-lt 小于
-le 小于等于
-ge 大于等于
关于 Bash 选项的条件判断
-o set的选项名称 如果选项是开启的状态

循环

Shell for&while 循环详细总结

几种方式:

  • for in循环
    for i in {1..10}
    do
       echo $i
    done
  • for(?,?,?)循环
    for((i=1;i<100;i++))
    do
        if((i%3==0))
        then
            echo $i
            continue
        fi
    done
  • while循环
    min=1
    max=100
    while [ $min -le $max ]
    do
        echo $min
        min=`expr $min + 1`
    done

判断命令是否有输出

    第一种方式:
    $ stdout=`ls /asdfkasd`
    $ if [ -n "$stdout" ]
    > then
    > echo "有货"
    > else
    > echo "没货"
    > fi
    没货

    第二种方式:
    $ stdout=`ls /tmp`
    $ if [ -n "$stdout" ]; then echo "有货"; else echo "没货"; fi
    有货

Linux Crontab内环境变量与Shell环境变量的关系

Linux Crontab内环境变量与Shell环境变量的关系及解决问题的办法
对一次 crontab 执行失败的调试
cron 定时执行脚本 执行用户自定义脚本
Linux的cron和crontab

在线Crontab表达式执行时间验证工具:
crontab执行时间计算
crontab在线生成器

crontab有一个坏毛病,就是它总是不会缺省的从用户profile文件中读取环境变量参数,经常导致在手工执行某个 脚本时是成功的,但是到crontab中试图让它定期执行时就是会出错。

crontab配置文件路径:/etc/crontab

编写crontab有两种方式:
1.通过文件的方式,编辑上述路径文件
2.通过contab命令的方式

    Usage:
     crontab [options] file
     crontab [options]
     crontab -n [hostname]

    Options:
     -u <user>  define user
     -e         edit user's crontab
     -l         list user's crontab
     -r         delete user's crontab
     -i         prompt before deleting
     -n <host>  set host in cluster to run users' crontabs
     -c         get host in cluster to run users' crontabs
     -s         selinux context
     -x <mask>  enable debugging

Example of job definition:

    # .---------------- minute (0 - 59)
    # |  .------------- hour (0 - 23)
    # |  |  .---------- day of month (1 - 31)
    # |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
    # |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
    # |  |  |  |  |
    # *  *  *  *  * user-name command to be executed

解决办法:
1. PATH 后面加入缺少目录,将crontab表达式追加到最后一行
表达式格式:30 23 * * * root "sh /opt/blog/hexo-deploy.sh >> /tmp/test.txt"
2. 在Shell脚本缺省的#!/bin/sh开头换行后的第一行加上. /etc/profile

CentOS 7 下重启服务

RHEL/CentOS 7中启动/停止/重启服务

在CentOS 7之前,比如6的时候,是通过 service name [start/stop/restart/status] 的方式启动或停止服务。
CentOS7好像是在6之后的最大改版,在某些命令上会存在差异,比如服务的启动(7采用systemctl)、查看ip(ip addr)等

下列演示对crontab服务的操作:

   systemctl status crond.service  #查看服务的状态
   systemctl stop  crond.service  #停止服务
   systemctl start crond.service  #启动服务
   systemctl restart crond.service #重启服务

date 指定时间格式

linux中通过date命令获取昨天或明天时间的方法

通过 date --help命令可以查看帮助文档

date +”%F”  #输出格式 2017-06-10 yyyy-MM-dd
date +”%F %H:%M:%S” #输出格式 2017-06-10 18:55:38 yyyy-MM-dd HH:mm:ss

设置环境变量

Linux环境下如何修改环境变量

通过export命令的方式

export: usage: export [-fn] [name[=value] ...] or export -p

查看环境变量配置 : export -p

一般不通过命令的方式,因为服务器重启或者关机等异常情况,之前配置的环境变量可能会失效,一般都配置在启动文件中(/etc/profile)中,通过source命令让环境变量生效。

嵌套执行expect命令

shell中嵌套执行expect命令实例
expect spawn、linux expect 用法小记

1.先安装expect

  yum install -y expect
  1. 脚本示例
    /usr/bin/expect <<-EOF
    set time 30
    spawn ssh -p18330 root@192.168.10.22
    expect {
    "*yes/no" { send "yes\r"; exp_continue }
    "*password:" { send "$passwd\r" }
    }
    expect "*#"
    send "cd /home/trunk\r"
    expect "*#"
    send "svn up\r"
    expect "*#"
    send "exit\r"
    interact
    expect eof
    EOF

加解密

shell几种字符串加密解密的方法

第一种:〔 Python 与 Bash Shell 的结合 〕
这个命令会让你输入一个字符串,然后会再输出一串加密了的数字。

加密代码[照直输入]:
python -c ‘print reduce(lambda a,b: a*256+ord(b), raw_input(“string: “), 0)’

解密代码[数字后+P]:
dc -e 输出的数字P

第二种:〔 应该是纯 Bash Shell,含 VIM 的 xxd 〕
用 gtalk@gmail.com 作为明文,加密分两步,当然了,也是可以一步过的,呆会说~

加密代码:
1、echo “gtalk@gmail.com” |xxd -ps -u
得到:6774616C6B40676D61696C2E636F6D0A
2、echo “ibase=16; 6774616C6B40676D61696C2E636F6D0A” |bc
得到:137514765985002236391382606438443478282

一步加密代码:
echo “ibase=16; $(echo “gtalk@gmail.com” |xxd -ps -u)” |bc
得到:137514765985002236391382606438443478282

解密代码:
3、dc -e 137514765985002236391382606438443478282P
得到:gtalk@gmail.com

第三种:〔 Base64 编码,这个很好很强大,适合写加密脚本 〕
同样用 gtalk@gmail.com 作为明文,来看代码:

加密代码:
echo “gtalk@gmail.com” |base64 -i
得到:Z3RhbGtAZ21haWwuY29tCg==

解密代码:
echo “Z3RhbGtAZ21haWwuY29tCg==” |base64 -d
得到:gtalk@gmail.com

kill 杀进程

linux kill终止进程

先通过ps -ef | grep 进程名的方式获得pid。在通过kill -9 pid 的方式杀死进程,也可以通过 killall 进程名的方式。

编写异常收集

Q:warning: here-document at line 17 delimited by end-of-file (wanted EOF)
A:末尾的EOF后面带有空格,EOF前后都不应有空格或其他符号

Q:linux bash中too many arguments问题的解决方法
A: if [ -z " lsof -i:22 " ] //这种写法会报too many arguments,改成[[ -z " lsof -i:22 " ]]