Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具, Linux/UNIX系统的底层及基础应用软件的核心大都涉及Shell脚本的内容。每一个合格 的Linux系统管理员或运维工程师,都需要能够熟练地编写Shell脚本语言,并能够阅 读系统及各类软件附带的Shell脚本内容。只有这样才能提升运维人员的工作效率,适 应曰益复杂的工作环境,减少不必要的重复工作,从而为个人的职场发展奠定较好的基础
1脚本语言的种类
1.1编译型语言
指用专用的编译器,针对特定的操作平台(操作系统)将某种高级语言源代码一次性翻译成可被硬件平台直接运行的二进制机器码(具有操作数,指令、及相应的格式),这个过程叫做编译(./configure make makeinstall );编译好的可执行性文件(.exe),可在相对应的平台上运行(移植性差,但运行效率高)。。
典型的编译型语言有, C语言、C++等。
另外,Java语言是一门很特殊的语言,Java程序需要进行编译步骤,但并不会生成特定平台的二进制机器码,它编译后生成的是一种与平台无关的字节码文件(*.class)(移植性好的原因),这种字节码自然不能被平台直接执行,运行时需要由解释器解释成相应平台的二进制机器码文件;大多数人认为Java是一种编译型语言,但我们说Java即是编译型语言,也是解释型语言也并没有错。
1.2解释型语言
指用专门解释器对源程序逐行解释成特定平台的机器码并立即执行的语言;相当于把编译型语言的编译链接过程混到一起同时完成的。
解释型语言执行效率较低,且不能脱离解释器运行,但它的跨平台型比较容易,只需提供特定解释器即可。
常见的解释型语言有, Python(同时是脚本语言)与Ruby等。
2脚本书写规范
1) 放在统一的目录
2) 脚本以.sh为扩展名
3) 开头指定脚本解释器。
4) 开头加版本版权等信息。
5) 脚本不要用中文注释,尽量用英文注释。(可能会因为兼容性问题出现乱码)
6) 代码书写优秀习惯
a、成对的内容一次性写出来,防止遗漏,如[ ]、‘ ‘、" "等
b、[ ]两端要有空格,先输入[ ],退格,输入2个空格,再退格写。
d、通过缩进让代码易读。
f、脚本中的引号都是英文状态下的引号,其他字符也是英文状态
3Shell脚本的执行
1给脚本添加执行权限 chmod +x XXX
2执行脚本 ./XXX .XXX source XXX (当前目录)
4变量
变量:命名的内存空间
数据存储方式:
作用:
1、数据存储格式
2、参与的运算
3、表示的数据范围
类型:
强类型:变量不经过强制转换,它永远是这个数据类型,不允许隐式的类型转换。一定义变量时必须指定类型、参与运算必须符合类型要求;调用未声明变量会产生错误
如java,c#
弱类型:语言的运行时会隐式做数据类型转换。无须指定类型,默认均为字符型;参与运算会自动进行隐式类型转换;变量无须事先定义可直接调用
如:bash 不支持浮点数,php
变量命名法则:
1、不能使程序中的保留字:例如if, for
2、只能使用数字、字母及下划线,且不能以数字开头
3、见名知义
4、统一命名规则:驼峰命名法(首个单词的首字母小写,其余单词首字母大写)
4.1普通变量
本地变量在用户当前的Shell生存期的脚本中使用。例如,本地变量OLDBOY取值为bingbing,这个值在用户当前Shell生存期中有意义。如果在Shell中启动另一个进程或退出,本地变量值将无效
变量定义
(1) 可以是直接字串; name=“root"
(2) 变量引用:name="$USER"
(3) 命令引用:name=`COMMAND` name=$(COMMAND)
变量引用:
${name} $name
显示已定义的所有变量:set
删除变量:unset name
4.2环境变量
变量引用:$name, ${name}
显示所有环境变量:
env
printenv
export
declare -x
删除变量:
unset name
bash内建的环境变量:
–PATH –SHELL –USER –UID –HOME
–PWD –SHLVL –LANG –MAIL –HOSTNAME
–HISTSIZE
在脚本代码中调用通过命令行传递给脚本的参数
$1, $2, ...:对应第1、第2等参数
4.3特殊变量
特殊变量:
位置变量:
$0 获取当前执行的shell脚本的文件名,如果执行脚本带路径那么就包括脚本路径。
$n 获取当前执行的shell脚本的第n个参数值,n=1..9,当n为0时表示脚本的文件名,如果n大于9用大括号括起来{10},参数以空格隔开。
$* 获取当前shell的所有传参的参数,不加引号同[email protected];如果给$*加上双引号,例如:“$*”,则表示将所有的参数视为单个字符串,相当于“112$3”
[email protected] 获取当前shell的所有传参的参数,不加引号同$*;如果给[email protected]加上双引号,例如:“[email protected]”,则表示将所有参数视为不同的独立字符串,相当于“$1” “$2”“$3” “……”,这是将参数传递 给其他程序的最佳方式,因为他会保留所有内嵌在每个参数里的任何空白。
$# 获取当前执行的shell脚本后面接的参数的总个数
当“$*”和“[email protected]”都加双引号时,两者有区别,都不加双引号时,两者无区别。
进程状态变量
$? 获取执行上一个指令的执行状态返回值(0为成功,非零为失败),这个变量最常用
$$ 获取当前执行的Shell脚本的进程号(PID),这个变量不常用
4.4变量定义的方法
1、 直接赋值
A=lisi
export A= lisi(全局变量)
2、 传参 (传递参数)
A = “$UASE”
3、交互式设置变量,使用read命令
使用read来把输入值分配给一个或多个shell变量
-p指定要显示的提示
-s 静默输入,一般用于密码
-n N指定输入的字符长度N
-d‘字符’ 输入结束符
-t N TIMEOUT为N秒
read从标准输入中读取值,给每个单词分配一个变量所有剩余单词都被分配给最后一个变量
read -p “Enter a filename:“ FILE
练习:编写一个脚本名为/root/bin/createsh.sh, 在执行该脚本时,执行方法如/root/bin/createsh.sh backup.sh ,执行后,会在/root/bin下生成一个名为backup.sh的文件,其中自带以下行,
#!/bin/bash
# ------------------------------------------
# Filename: xx.sh
# Revision: 1.0
# Date: 2017/06/01
# Author: XXX
# Email: [email protected]
# Website: www.XXXXX.com
# Description:
# ------------------------------------------
然后自动用vim打开该文件,且光标直接位于非注释部分下的新行vim + 打开vim至最后一行
5运算
5.1算数运算
bash中的算术运算:
+, -, *, /, %取余, **(乘方)
仅支持整数的运算
echo $((数学运算表达式))
let命令
$[]运算符
可以进行小数运算的命令
bc 命令
awk 命令
自增,自减:
let a+=1 = let b++
let b-=1 = let b—
练习
5.2逻辑运算
true, false
1, 0
与:
1 与1 = 1 1 与0 = 0
0与1 = 0 0与0 = 0
或:
1 或1 = 1 1 或0 = 1
0 或1 = 1 0 或0 = 0
非:!
! 1 = 0 ! 0 = 1
短路运算
短路与
第一个为0,结果必定为0
第一个为1,第二个必须要参与运算
短路或
第一个为1,结果必定为1
第一个为0,第二个必须要参与运算
异或:^
异或的两个值,相同为假,不同为真
5.3条件运算
根据退出状态而定,命令可以有条件地运行
&& 代表条件性的AND THEN
|| 代表条件性的OR ELSE
例如:
grep-qno_such_user/etc/passwd\||echo‘Nosuchuser‘
Nosuchuser
ping-c1-W2station1&>/dev/null\>&&echo"station1isup"\>||(echo‘station1isunreachable‘;exit1)
station1isup
5.4数值测试
数值测试:
-gt是否大于
-ge是否大于等于
-eq是否等于
-ne是否不等于
-lt是否小于
-le是否小于等于
5.5字符串测试
字符串测试:
== 是否等于
> ascii码是否大于ascii码
< 是否小于
!= 是否不等于
=~ 左侧字符串是否能够被右侧的PATTERN所匹配
注意: 此表达式一般用于[[ ]]中;扩展的正则表达式
-z "STRING“字符串是否为空,空为真,不空为假
-n "STRING“字符串是否不空,不空为真,空为假
注意:用于字符串比较时的用到的操作数都应该使用引号
5.6文件测试
存在性测试
-a FILE:同-e
-e FILE: 文件存在性测试,存在为真,否则为假
存在性及类别测试
-b FILE:是否存在且为块设备文件
-c FILE:是否存在且为字符设备文件
-d FILE:是否存在且为目录文件
-f FILE:是否存在且为普通文件
-h FILE 或-L FILE:存在且为符号链接文件
-p FILE:是否存在且为命名管道文件
-S FILE:是否存在且为套接字文件
文件权限测试:
-r FILE:是否存在且可读
-w FILE: 是否存在且可写
-x FILE: 是否存在且可执行
文件特殊权限测试:
-u FILE:是否存在且拥有suid权限
-g FILE:是否存在且拥有sgid权限
-k FILE:是否存在且拥有sticky权限
文件大小测试:
-s FILE: 是否存在且非空
文件是否打开:
-t fd: fd文件描述符是否在某终端已经打开
-N FILE:文件自从上一次被读取之后是否被修改过
-O FILE:当前有效用户是否为文件属主
-G FILE:当前有效用户是否为文件属组
双目测试:
FILE1 -efFILE2: FILE1是否是FILE2的硬链接
FILE1 -ntFILE2: FILE1是否新于FILE2(mtime)
FILE1 -otFILE2: FILE1是否旧于FILE2
练习
1编写脚本/root/bin/excute.sh ,判断参数文件是否为sh后缀的普通文件,如果是,添加所有人可执行权限,否则提示用户非脚本文件
2编写脚本/root/bin/nologin.sh和login.sh,实现禁止和充许普通用户登录系统
login与这个差不多,就不写了
6防止扩展
6.1Bash如何展开命令行
把命令行分成单个命令词-->展开别名-->展开大括号的声明({})-->展开波浪符声明(~)-->命令替换$()和``)-->再次把命令行分成命令词-->展开文件通配(*、?、[abc]等等)-->准备I/0重导向(<、>)-->运行命令
6.2防止扩展
反斜线(\)会使随后的字符按原意解释
$echoYourcost:\$5.00
Yourcost:$5.00
加引号来防止扩展
单引号(’)防止所有扩展
双引号(”)也防止所有扩展,但是以下情况例外:
$(美元符号)-变量扩展
`(反引号)-命令替换
\(反斜线)-禁止单个字符扩展
!(叹号)-历史命令替换
7Bash的配置文件
按生效范围划分,存在两类:
全局配置:
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
个人配置:
~/.bash_profile
8Shell登陆的方法
交互式登录:
(1)直接通过终端输入账号密码登录
(2)使用“su-UserName”切换的用户
执行顺序:/etc/profile --> /etc/profile.d/*.sh --> ~/.bash_profile--> ~/.bashrc--> /etc/bashrc
非交互式登录:
(1)su UserName
(2)图形界面下打开的终端
(3)执行脚本
(4)任何其它的bash实例
执行顺序:~/.bashrc--> /etc/bashrc--> /etc/profile.d/*.sh
9配置文件
profile类
全局:/etc/profile, /etc/profile.d/*.sh
个人:~/.bash_profile
功用:
(1) 用于定义环境变量
(2) 运行命令或脚本
bashrc类
bashrc类:为非交互式和交互式登录的shell提供配置
全局:/etc/bashrc
个人:~/.bashrc
功用:
(1) 定义命令别名和函数
(2) 定义本地变量
配置文件生效的方法
修改profile和bashrc文件后需生效
两种方法:
1重新启动shell进程
2 . 或source
例:
. ~/.bashrc
附:.与source与 ./ 的区别
./script 作为一个可执行文件来运行脚本,启动一个子shell来运行它,当执行完脚本之后,又回到了父shell中,所以在子shell中执行的一切操作都不会影响到父shell;
.script与source script 在当前shell环境中从文件名读取和执行命令。
使用./ 运行脚本的时候,系统变量不会受到影响,而使用source与.的时候,会影响到系统当前的环境变量。
练习
1编写脚本/root/bin/systeminfo.sh,显示当前主机系统信息,包括主机名,IPv4地址,操作系统版本,内核版本,CPU型号,内存大小,硬盘大小
2编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到/root/etcYYYY-mm-dd中
3编写用户的环境初始化脚本reset.sh,包括别名,登录提示符,vim的设置,环境变量等
原文地址:https://www.cnblogs.com/angge/p/9381289.html