Shell脚本认知

认识shell

shell有哪些些

  • bash
  • zsh
  • csh
  • ash
  • ksh
  • nologin

shell的使用场景

  • 自动化批量系统初始化程序 (update,软件安装,时区设置,安全策略...)
  • 自动化批量软件部署程序 (LAMP,LNMP,Tomcat,LVS,Nginx)
  • 应用管理程序 (KVM,集群管理扩容,MySQL,DELLR720批量RAID)
  • 日志分析处理程序(PV, UV, 200, !200, top 100, grep/awk)
  • 自动化备份恢复程序(MySQL完全备份/增量 + Crond)
  • 自动化管理程序(批量远程修改密码,软件升级,配置更新)
  • 自动化信息采集及监控程序(收集系统/应 用状态信息,CPU,Mem,Disk,Net,TCP Status,Apache,MySQL)
  • 配合Zabbix信息采集(收集系统/应用状态信息,CPU,Mem,Disk,Net,TCP Status,Apache,MySQL)
  • 自动化扩容(增加云主机-->业务上线)
  • Zabbix监控CPU 80%+|-50% Python API AWS/EC2(增加/删除云主机) + Shell Script(业务上线)
  • 俄罗斯方块,打印三角形,打印圣诞树,打印五角星,运行小火车,坦克大战,排序算法实现
  • Shell可以做任何事(一切取决于业务需求)

关于shell的设置

更换别名

vim .bashrc

linux快捷键操作

2、快捷键

快捷键作用
*ctrl+a把光标移动到命令行开头。如果我们输入的命令过长,想要把光标移动到命令行开头时使用。
*ctrl+e把光标移动到命令行结尾。
*ctrl+c强制终止当前的命令。
*ctrl+l清屏,相当于clear命令。
*ctrl+u删除或剪切光标之前的命令。我输入了一行很长的命令,不用使用退格键一个一个字符的删除,使用这个快捷键会更加方便
*ctrl+k删除或剪切光标之后的内容。
ctrl+y粘贴ctrl+U或ctul+K剪切的内容。
*ctrl+r在历史命令中搜索,按下ctrl+R之后,就会出现搜索界面,只要输入搜索内容,就会从历史命令中搜索。
*ctrl+d退出当前终端。
ctrl+z暂停,并放入后台。这个快捷键牵扯工作管理的内容,我们在系统管理章节详细介绍。
ctrl+s暂停屏幕输出。
ctrl+q恢复屏幕输出。
ctrl+左右箭头单词之间快速移动光标

前后台操作
直接用命令操作会在前台运作

top

在后台运行就需要按下

ctrl+z

jobs查看后台进程

fg %n 让进程回到前台
bg %n 让进程到后台
nohup 直接让软件在后台运行

重定向和命令判断

输出重定向

>是输出
<是输入

类 型符 号作 用
标准输出重定向command >file以覆盖的方式,把 command 的正确输出结果输出到 file 文件中。
command >>file以追加的方式,把 command 的正确输出结果输出到 file 文件中。
标准错误输出重定向command 2>file以覆盖的方式,把 command 的错误信息输出到 file 文件中。
command 2>>file以追加的方式,把 command 的错误信息输出到 file 文件中。
正确输出和错误信息同时保存command >file 2>&1以覆盖的方式,把正确输出和错误信息同时保存到同一个文件(file)中。
command >>file 2>&1以追加的方式,把正确输出和错误信息同时保存到同一个文件(file)中。
command >file1 2>file2以覆盖的方式,把正确的输出结果输出到 file1 文件中,把错误信息输出到 file2 文件中。
command >>file1 2>>file2以追加的方式,把正确的输出结果输出到 file1 文件中,把错误信息输出到 file2 文件中。
command >file 2>file不推荐】这两种写法会导致 file 被打开两次,引起资源竞争,所以 stdout 和 stderr 会互相覆盖,
command >>file 2>>file

/dev/null 文件是垃圾箱

不要的输出直接可以输出到这里

文件描述符

文件描述符文件名类型硬件
0stdin标准输入文件键盘
1stdout标准正确输出文件显示器
2stderr标准错误输出文件显示器

输入重定向

    TYPE=Ethernet 
    BOOTPROTO=none 
    NAME=ens160 
    DEVICE=ens160 
    ONBOOT=yes 
    IPADDR=192.168.26.200 
    PREFIX=24 
    GATEWAY=192.168.26.2 
    DNS1=192.168.26.2 
    eof

read命令用法

输出字后面可以让用户输入
**

# cat a.sh
stty -echo
read -p "请你大声的请你大声的告诉我你的QQ密码是什么:"  name
echo
echo 我的密码是: $name
stty echo

&& || 具备逻辑判断

&&是在上一台哦命令执行成功后才执行吓一跳
||是在上一条命令没有成功后才执行下一条

通配符

字符含义实例
*匹配0个或多个任意字符a*b,a与b之间可以有任意长度的字符,也可以没有。例如:aabcb,ab,azxcb...
?匹配一个任意字符a?b,a与b之间必须但也只能存在一个字符,该字符可以是任意字符。例如:aab,abb,acb...
[list]匹配list中的任意单个字符,一个[]只匹配一个位置的字符a[xyz]b,a与b之间必须但也只能存在一个字符,该字符只能是x或y或z。例如:axb,ayb,azb
[!list]匹配除list中的任意单个字符a[!a-z]b,a与b之间必须但也只能存在一个字符,该字符不能是小写字母。例如:aAb,a0b...
[c1-c2]匹配c1-c2间的任意单个字符a[0-1]b,a与b之间必须但也只能存在一个字符,该字符只能是数字。例如:a0b,a1b...
{string1,string2,...}匹配string1、string2等中的一个字符串a{abc,xyz,opq}b,a与b之间必须但也只能存在一个字符串,字符串只能是abc或xyz或opq。例如:aabcb,axyzb,aopqb...
{1..3}匹配1到3

Bash 初始化

环境变量文件有哪些

/etc/profile    使用范围:所有账户

/etc/bashrc	    使用范围:所有账户

~/.bashrc		使用范围:~所代表的账户

~/.bash_profile 使用范围:~所代表的账户

~/.bash_logout

login shell
	登录的时候需要输入用户名
nologin shell
	登录的时候不需要输入用户

变量文件的作用

1、/etc/profile

  • 全局(公有)配置,不管是哪个用户,登录时都会读取该文件。

2、/ect/bashrc

  • Ubuntu 没有此文件,与之对应的是 /ect/bash.bashrc
  • 它也是全局(公有)的
  • bash 执行时,不管是何种方式,都会读取此文件。

3、~/.profile

  • 若 bash 是以 login 方式执行时,读取 ~/.bash_profile,若它不存在,则读取 /.bash_login,若前两者不存在,读取/.profile。

  • 图形模式登录时,此文件将被读取,即使存在 ~/.bash_profile 和 ~/.bash_login。

4、~/.bash_login

  • 若 bash 是以 login 方式执行时,读取 ~/.bash_profile,若它不存在,则读取 ~/.bash_login,若前两者不存在,读取 ~/.profile。

5、~/.bash_profile

  • Unbutu 默认没有此文件,可新建。

  • 只有 bash 是以 login 形式执行时,才会读取此文件。通常该配置文件还会配置成去读取 ~/.bashrc。

6、~/.bashrc

  • 当 bash 是以 non-login 形式执行时,读取此文件。若是以 login 形式执行,则不会读取此文件。

7、~/.bash_logout

  • 注销时,且是 longin 形式,此文件才会读取。在文本模式注销时,此文件会被读取,图形模式注销时,此文件不会被读取。

Bash 环境变量加载

  • 图形模式登录时,顺序读取:/etc/profile 和 ~/.profile

  • 图形模式登录后,打开终端时,顺序读取:/etc/bash.bashrc 和 ~/.bashrc

  • 文本模式登录时,顺序读取:/etc/bash.bashrc,/etc/profile 和 ~/.bash_profile

  • 从其它用户 su 到该用户,则分两种情况:

    • 如果带 -l 参数(或-参数,--login 参数),如:su -l username,则 bash 是 login 的,它将顺序读取以下配置文件:/etc/bash.bashrc,/etc/profile 和~/.bash_profile。
    • 如果没有带 -l 参数,则 bash 是 non-login 的,它将顺序读取:/etc/bashrc 和 ~/.bashrc
  • 注销时,或退出 su 登录的用户,如果是 longin 方式,那么 bash 会读取:~/.bash_logout

    • 执行自定义的 Shell 文件时,若使用 bash -l a.sh 的方式,则 bash 会读取行:/etc/profile 和 ~/.bash_profile,若使用其它方式,如:bash a.sh,./a.sh,sh a.sh(这个不属于bash Shell),则不会读取上面的任何文件。
    • 上面的例子凡是读取到 ~/.bash_profile 的,若该文件不存在,则读取 ~/.bash_login,若前两者不存在,读取 ~/.profile。

Shell 脚本规范

开头有注释其

#!/bin/sh 

除了 bash 之外,可以用下面的命令查看本机支持的解释器:

/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash

参数要规范
判断参数 给出输出回显

if [[ $# != 2 ]];then
    echo "Parameter incorrect."
    exit 1
fi

变量

一般情况下会将一些重要的环境变量定义在开头,确保这些变量的存在。

source /etc/profile
export PATH=”/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/apps/bin/”
  • 这种定义方式有一个很常见的用途,最典型的应用就是,当本地安装了很多 java 版本时,可能需要指定一个java来用。这时就会在脚本开头重新定义JAVA_HOME以及PATH变量来进行控制。
  • 一段好的代码通常是不会有很多硬编码在代码里的“魔数”的。如果一定要有,通常是用一个变量的形式定义在开头,然后调用的时候直接调用这个变量,这样方便日后的修改。

代码有效率

勤用双引号

#!/bin/sh
#已知当前文件夹有一个a.sh的文件
var="*.sh"
echo $var
echo "$var" 

双引号 强制引用生效
单引号 无效引用

学会查路径

查看脚本所在路径

script_dir=$(cd $(dirname $0) && pwd)
script_dir=$(dirname $(readlink -f $0 ))

Shell 脚本调试

sh 带参数
-n 不执行
-v 显示脚本内容
-x 执行脚本是会输出到那一步了

module () {  eval `/usr/bin/modulecmd bash $*`
}
#!/bin/bash
case $1 in
    "one")
    echo "you input number is one"
    ;;
    "two")
    echo "you input number is twp"
    ;;
*)
    echo "you input number is other"
    ;;
esac
you input number is other

位置变量

$0 脚本名(自己本身)

\* 所有的参数** "*" 会将所有的参数作为一个整体,以"1 2 … $n"的形式输出所有参数

@ 所有的参数 "@" 会将各个参数分开,以"1" "2" … "$n" 的形式输出所有参数

$# 参数的个数

$! 上一个后台进程的PID $? 上一个命令的返回值 0表示成功 **示例** echo "第2个位置参数是$2" echo "第1个位置参数是$1" echo "第4个位置参数是$4" echo "所有参数是: $*" echo "所有参数是: $@" echo "参数的个数是: $#" echo "当前进程的PID是: $$" echo '$1='$1 echo '$2='$2 echo '$3='$3 echo '$*='$* echo '$@='$@ echo '$#='$# echo '$$='$$ ## 变量运算