Chapter 1--Shell的基本知识
一、Shell的分类
-
Bourne Shell:标识为sh,该shell由Steve Bourne在贝尔实验室编写,众多Unix系统中该shell是root用户的默认shell
-
Bourne-Again Shell:标识为bash,是绝大多数localhost发行版的默认shell
-
Korn Shell:标识为ksh,完全向上兼容Bourne Shell,包含了C Shell的很多特性
-
C Shell:标识为csh,其语法类似于C语言
查看当前系统支持的shell操作
查看当前系统的默认shell
二、shell脚本的基本元素
- 声明:声明用哪个命令解释器来解释并执行当前脚本文件中的语句,一般的解释器为#!/in/bash
- 命令:可执行语句,实现程序的某种功能
- 注释:说明某些代码的功能,通过在代码中增加注释来提高程序的可读性
注释的分类:
- 单行注释
#comment1
#comment2
- 多行注释:冒号+任意两单词,在两单词中间可插入注释内容
:<<Block
注释内容
Block
三、shell脚本编写规范
- 脚本文件名应见名知意,如backup_mysql.sh
- 文件开头指定脚本解释器#!/bin/sh或#!/bin/bash
- 开头加版本特权等信息
#Date:日期
#Author:作者
#Mail:联系方式
#Function:功能
#Version:版本
4.脚本中尽量不使用中文注释
5.多使用内部命令
常用的内部命令:echo eval exec export read shift exit
- echo可在屏幕上输出信息
echo参数选项 | 说明 |
-n | 不换行输出内容 |
-e | 解析转义字符 |
转义字符 | 说明 |
\n | 换行 |
\r | 回车 |
\t | 制表符 |
\b | 退格 |
\v | 纵向制表符 |
- eval
命令格式:eval args
功能:当shell程序执行到eval语句时,shell读入参数args并将它们组合成一个新命令然后执行
- exec命令能够在不创建新的子进程的前提下,转去执行指定的命令,当指定的命令执行完毕后,进程终止
- export设置或显示环境变量
- read命令可从标准输入读取字符串等信息,传给shell程序内部定义的变量
-p prompt:设置提示信息
-t timeout:设置输入等待时间,单位默认为秒
- shift:在程序中每使用一次shift语句,都会使所有的位置参数依次向左移动一个位置,并使位置参数$#减一,直到减到0为止
- exit:退出shell程序,在exit之后可有选择的指定一个数作为返回状态
6.代码缩进:规范编码使代码更美观
四、脚本的执行方式
1.交互式执行
[root@localhost ~]# for filename in `ls /etc`
> do
> if echo "$filename" | grep "passwd"
> then
> echo "$filename"
> fi
> done
2.作为程序文件执行(常用)
对于一组需要经常重复执行的shell语句来说,将它们保存在一个文件中执行,称这种包含多个shell语句的文件为shell脚本,shell脚本文件是普通的文本文件,可使用任何文本编辑器查看或修改shell脚本
mkdir /test
cd /test
vim test1.sh
for filename in `ls /etc`
do
if echo "$filename" | grep "passwd"
then
echo "$filename"
fi
done
五、执行脚本的方法
1.bash ./filename.sh 产生子进程,再运行,使用当前指定的bash shell去运行
2. ./filename.sh 产生子进程再运行,使用脚本里指定的shell去运行,使用该方式需要x权限
3.source ./filename.sh source命令是一个shell内部命令,其功能是读取指定shell程序文件,并依次执行其中所有的语句,并没有创建新的子shell进程,所以脚本里创建的变量都会保存到当前的shell里
4. ./filename.sh
Chapter 2 变量和引用
一、变量的类型
-
根据数据类型分类
shell是一种动态类型语言和弱类型语言,变量的数据类型会根据不同操作而有所变化,即shell中的变量是不分数据类型的
弱类型&强类型语言
- 强类型:变量一旦被定义类型就被固定,不能再改变
- 弱类型:变量的类型不固定,可任意改变
用declare定义变量的相关操作:
-p:显示所有变量的值
-i:将变量定义为整数,之后可直接对表达式求值,结果只能是整数
-r:将变量声明为制度变量,不允许修改/删除
-a:将变量声明为数组变量
-f:显示所有自定义函数,包括名称&函数体
-x:将变脸设置成环境变量,可使用+x将变量变成非环境变量
-
根据作用域分类
可分为环境变量(全局变量)和普通变量(局部变量)
1.环境变量:可称为全局变量,可在创建它们的shell及派生出来的任意子进程shell中使用(su -切换用户会读取新的环境变量),环境变量又可分为自定义环境变量和bash内置的环境变量
(1)自定义环境变量
用户的环境变量配置(non-login shell),~/.bash_profile或~/.bashrc
全局环境变量的配置(login shell),/etc/bashrc,/etc/profile文件或/etc/profile.d目录中定义
(2)bash内置的环境变量
shell内置的环境变量是所有shell程序中都可以使用的变量,环境变量会影响到所有脚本的执行结果。
2.普通变量:称局部变量,相比于全局变量,局部变量的使用范围较小,仅限于在某个程序段中访问。函数的参数也称为局部变量
二、变量的定义
1.变量定义实例:变量名=变量值
注意:
(1)“=”前后不能有空格
(2)字符串类型用括号括起来
引用变量:$变量名或${变量名}
查看变量:echo $变量名,set(可查看所有变量:包括自定义变量和环境变量),env显示全局变量,declare输出所有变量、函数、整数和已导出的变量
取消变量:unset变量名
作用范围:仅在当前shell中有效
2.位置参数和预定义变量
shell脚本需要根据用户的输入的不同参数来执行不同的操作
从命令行传递给shell脚本的参数称为位置参数,shell脚本根据参数的位置使用不同的位置参数变量来读取他们的值
变量 | 说明 |
$# | 命令行参数的个数 |
$n | 表示传递给脚本的第n个参数,如$1表示第一个 |
$0 | 当前脚本的名称 |
$* | 以“参数1 参数2”的形式返回所有的值(整体) |
$@ | 以“参数1”“参数2”的形式返回所有的值(分隔) |
$? | 前一个命令或函数的返回状态码,$?返回值的用法:1.判断命令、脚本或函数等程序是否执行成功 2.如果在脚本中调用执行exit,则会返回这个数字给$?变量 |
$$ | 返回本程序的进程ID |
$! | 获取上一个在后台工作的进程号 |
$_ | 保存之前执行命令的最后一个参数 |
三、shell中的引用
符号 | 说明 |
转义字符"\" | 放在特殊字符前shell就忽略这些字符的原有含义,当成普通字符输出 |
单引号 | 字符串放在单引号之前,则字符串中所有字符的特殊含义被忽略 |
双引号 | 与单引号相同,仍有一些特殊字符保留自身特殊含义,如"$","\"以及"`" |
Tips:反引号中的字符串将被解释为shell命令,单引号中的语句原封不动输出,双引号中语句仍有特殊字符的含义
四、变量的运算
-
运算符和说明
运算符 | 说明 |
+ - | 求和、差 |
* / % | 求乘积、商、余数 |
** | 幂运算,3**3是求3的立方 |
+= -= *= /= %= | 单目运算 |
++variable --variable | 先加/减再赋值 |
位运算符<< >> | 针对2进制,2>>1,将二进制形式的2,即10左移1位,即变为100;4<<2,将100左移两位 |
& | ~ ^ | 按位与,8&4,将8和4进制行按位与运算,结果为0;按位或,8|4,将8和4进行按位或运算,结果为12,;按位非,~8,将8进行按位非运算,结果为-9;按位异或^ |
<<= >>= | 将变量的值左移指定位数后重新赋值给该变量,x<<3,将x的值左移3位,重新赋值给变量x;将变量的值右移指定位数后重新赋值给变量x |
&= |= ^= | 将变量的值与指定的数值按位与之后重新赋值给该变量,x&=8,即将变量x的值与8按位与后赋值给变量x |
运算符与运算命令 | 意义 | 说明 |
let | 用于整数运算 | 使用let命令可以执行一个或多个算数表达式,变量名无需使用$符号 |
expr | 可用于整数运算 | 使用expr时,运算符或待计算的数字两边都需有空格,否则出现报错;使用乘号时用反斜线屏蔽其特定含义;使用expr做计算,可将一个未知变量和已知整数相加,查看返回码是否为0,如果是,则可确定未知变量的数据类型为整数,否则就不是整数 |
bc | 一个计算器程序 | |
$[] | 用于整数运算 | |
awk | 用于小数、整数运算 | |
declare | 定义变量值和属性,-i参数可用于定义整型变量做运算 | |
(()) | 用于整数运算的常用运算符 | 在(())中使用变量时可去掉变量前的$符号 |
-
变量相关的表达式
表达式 | 说明 |
${parameter} | 返回变量的内容 |
${#parameter} | 返回变量内容的长度(按字符) |
${paramater:offset} | 在变量${parameter}中从offset之后开始提取子串到结尾 |
${paramater:offset:length} | 在变量${parameter}中,从位置offset之后开始提取长度为length的子串 |
${paramater#word} | 从变量${paramater}开头开始删除最短匹配的word子串 |
${paramater##word} | 从变量${paramater}开头开始删除最长匹配的word子串 |
${paramater%word} | 从变量${paramater}结尾开始删除最短匹配的word子串 |
${paramater%%word} | 从变量${paramater}结尾开始删除最短匹配的word子串 |
${paramater:/pattern/string} | 使用string代替第一个匹配的pattern |
${paramater//pattern/string} | 使用string代替所有匹配的pattern |