shell脚本语言入门基础

shell编程基础知识

    • 编程语言分为两种
    • shell介绍
    • shell脚本的组成部分
    • 第一个脚本
    • 检查脚本语法
    • shell多命令执行
    • bash之变量
    • bash的配置文件
    • bash的IO重定向
    • bash算数运算:bash对数字进行隐式的类型转换
    • bash条件测试
    • bash的逻辑运算:true(0)、false(1-255)
    • 编写脚本backup.sh,可实现每日将/etc/目录备份到 /root/etcYYYY-mm-dd中
    • 编写脚本nologin.sh和login.sh,实现禁止和允许普通用户登录系统
    • 编写脚本disk.sh,显示当前硬盘分区中空间利用率最大的值

编程语言分为两种

过程式:以指令为中心,数据服务于指令
对象式:以数据为中心,指令服务于数据

shell介绍

shell是一个用C语言编写的程序,它是用户使用Linux系统的窗口,一个桥梁,起到人机交互的作用。

shell既是一种命令语言,又是一种简单的程序设计语言,为什么说简单,因为有很多复杂的工作不用Shell去做。

shell本身是一种应用程序,运行与内核之上,这个应用程序为提供了一个界面,用户可通过这个界面访问操作系统内核的服务。shell是Linux系统内嵌的,安装操作系统之后看到的界面就是一个shell程序提供的界面。

shell程序: 是一个过程式的解释器,把源代码翻译成机器语言,然后执行,对于过程式语言来讲,是一行一行翻译并执行的;


shell脚本的组成部分

shell程序开头的环境指定:称之为shebang,如下:
	#!/bin/bash
	#!/bin/python
	#!/bin/perl
shebang是告诉操作系统内核通过哪一个解释器来执行当前脚本;
#:行首为#号则为注释行,额外的解释信息

第一个脚本

#!/bin/bash
echo "Hello World !!!"

脚本执行方式

需给予脚本执行权限
	chmod +x hello.sh
通过脚本文件所在绝对路径进行执行
	/root/hello.sh
直接运行解释器,将脚本作为解释器的参数来执行
	sh hello.sh

检查脚本语法

bash -n :测试语法是否正确
bahs -x :查看脚本执行过程
bash -xv :更详细的查看脚本执行过程

例:bash -x hello.sh

shell多命令执行

command1;command2;command3;		:使用分号隔开

例:NUM=`seq 1 10`;echo $NUM

bash之变量

变量=变量名+指向的内存空间

将数据存放于内存中,为了方便使用,为这段数据取了个名字,使用时,直接调用变量名,系统会根据变量名指向的数据位置将数据提取,进行使用

变量赋值:就是将数据存储于这个变量名指向的内存空间的过程

变量的类型:定义数据存储的格式
	字符型
	数值型:
		整数型
		浮点型

对于编程语言来说变量还分为:强类型和弱类型,bash为弱类型变量语言,如果没有明确表明,bash把所有变量统统视为字符型,而当我们运算时,bash会自动将变量值转为数值型。bash不支持浮点型,除非借助外部工具

bash中的变量无需事先声明,随用随时到内存空间中定义

变量的种类:根据生效的范围不同来区分

本地变量:范围是当前shell进程
环境变量:范围是当前shell进程和子shell进程
局部变量:范围是当前shell进程某个代码块(通常指函数)
位置变量:用于放在脚本代码块中调用通过命令行传递给脚本的参数

特殊变量:
	$?:命令执行的状态值,值的范围0-255,其中0为真,表示命令执行成功,1-255为假,表示命令执行失败
	$#:传递给脚本的参数的个数
	$*:传递给脚本的所有参数,全部参数合为一个字符串
	$@:传递给脚本的所有参数,每个参数为独立字符串
	$0:表示命令本身

本地变量

变量赋值:name="value"
	value的值也可以引用:
		可以直接使用字符串:name="username"
		可以使其他变量的值:name="$username"
		可以直接引用命令的值:name=`hostname`或者name=#(hostname);
	
变量引用:${var_name},可简写为$var_name
	"":弱引用,其中的变量引用会被替换成变量的值
		例:[root@centos_7 ~]# NUM="$PATH";echo $NUM             
			/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
	'':强引用,其中的变量引用不会被替换,而是保留引号内原字符串
		例:[root@centos_7 ~]# NUM='$PATH';echo $NUM  
			$PATH
	``:命令引用,如括号内是命令,会被识别,返回的是命令执行完成的值
  		例:[root@centos_7 ~]# NUM=`seq 1 10`;echo $NUM
			1 2 3 4 5 6 7 8 9 10
			
查看变量:set
撤销变量:unset name
输出变量:echo $name

环境变量

变量赋值:export name=value	
	   declare -x name=value

查看变量:export、declare、env

撤销变量:unset name

输出变量:echo $name

bash有许多内建的环境变量:
	PATH,PWD,USER,HOSTNAME,SHELL,UID,HOME等等

只读变量:只读变量的证明周期为当前shell进程的生命周期,随着shell进程的终止而终止

变量赋值:declare -r name 
	  readonly name 

位置变量:$1,$2……$10,对应第1,第2个参数
shift:轮替,将第1个参数踢掉,第2个参数变为第一个参数,可一次踢多个,shift#;
set – :清空所有位置变量

命令行中定义的变量会随着当前shell进程的生命周期,Shell进程结束,变量时效

变量名的命名规则

只能用数字,字母,下划线,且不能使数字开头
变量名尽量做到见名知意
且不能使用程序的保留字,如PATH、PWD、if、else之类的		

bash的配置文件

全局配置文件:对当前主机所有用生效

/etc/profile
/etc/profile.d/*.sh

个人配置文件:只对当前用户生效

.bash_profile
.bashrc

按照功能分,分为两类:
profile类:为交互式登录的shell提供配置

交互式登录:直接通过某终端输入账号和密码后登录打开的shell进程
		使用su -命令登陆的方式:su - username
全局:/etc/profile,/etc/profile.d/*.sh
个人:.bash_profile

作用:用于定义环境变量
	  运行命令或脚本

交互式登录方式文件的读取顺序:
	/etc/profile --> /etc/profile.d/*.sh --> .bash_profile --> /etc/bashrc --> .bashrc
	注意:仅管理员可修改全局配置文件

bashrc类:为非交互式登录的shell提供配置

非交互式登录:图形界面下打开的终端
		  使用su username
		  运行脚本
全局:/etc/bashrc
个人:.bashrc

作用:定义本地变量
	  定义命令别名

非交互式登录文件的读取顺序:
		.bashrc --> /etc/bashrc --> /etc/profile.d/*.sh

配置文件定义的特性,只对随后的shell进程生效

让通过编辑配置稳健的特性立即生效:
	退出并重新登录
	通过命令行重复定义一次

让shell进程重读配置文件
	source FileName
	. FileName

bash的IO重定向

输出重定向

>	:覆盖输出
>>	:追加输出,在原有文件的尾部添加内容
set -C  :禁止覆盖输出重定向至已存在的文件
	>|	:强行覆盖输出
set +C 	:关闭上述特性

错误输出重定向

2>		:错误覆盖
2>>		:错误追加

合并正常输出和错误输出

&>		:覆盖
&>>		:追加

/dev/null:相当于一个垃圾箱,当我们不需要将命令执行结果输出至屏幕时,可使用&> /dev/null,把结果丢进垃圾箱,只判断命令执行状态返回值;

重定向写入文件

cat << EOF
		content
		...
EOF
----
cat > /PATH/TO/FILE << EOF
		content
		……
EOF

bash算数运算:bash对数字进行隐式的类型转换

+,-,*,/,%(取模),**(乘方)
实现算数运算:
	let var=算数表达式,如:let var=1+2
	  例:
		[root@centos_7 ~]# let var=1+2
		[root@centos_7 ~]# echo $var
		3
	
	var=$[算数表达式],如:var=$[1+2]

	var=$((算数表达式)),如:var=$((1+2))
	
	echo '算数表达式' | bc ,如echo ‘1+2’ | bc 

	expr 数值1 运算符 数值2,如expr 1 + 2
	
增强型复制:
	+=,-=,*=,/=,%=
使用方法:let 变量名运算符算数表达式
	例:let=i+=1即i=i+1
	自增,自减
		let i+=1 即let i++
		let i-=1 即let i--
 例:	
	[root@centos_7 ~]# let i++;echo $i
	1
	[root@centos_7 ~]# let i++;echo $i
	2
	[root@centos_7 ~]# let i++;echo $i
	3


bash条件测试

判断某条件是否满足,满足则完成某项任务,不满足则退出

条件测试命令的表达式:

test 表达式
[ 表达式 ]	
[[ 表达式 ]]
	与[ ]不同,[[ ]]双括号内支持正则表达式,而[ ]单括号不支持

常用例:N=abc;[[ $N =~ ^[0-9]+$ ]] && echo true || echo false	:解释为,如果$N的值为整数型,则返回true,否则返回false。

note:表达式两边必须要有空格!

bash的测试类型

数值测试

-eq:是否等于
-ne:是否不等
-gt:是否大于
-lt:是否小于
-ge:是否大于或等于
-le:是否小于或等于

字符测试

==:是否等于
!=:是否不等
>:是否大于
<:是否小于
=~:左侧字符串是否能被右侧模式所匹配
-z "string":测试字符串是否为空,空则为真,不空则为假
-n "string":测试字符串是否不空,不空为真,空则为假

文件测试:测试文件存在与否,属性信息等
1)测试文件是否存在和文件类别

-e file:测试指定文件是否存在,存在为真,不存在则为假
-b file:文件是否存在且为块设备
-d file:文件是否存在且为目录
-c file:文件是否存在且为字符设备
-f file:文件是否存在且为普通文件
-h file:文件是否存在且为符号链接文件
-p file:文件是否存在且为命名管道文件
-S file:文件是否存在且为套接字文件

2)文件权限测试

-r file:文件是否存在且当前用户是否可读
-w file:文件是否存在且当前用户是否可写
-x file:文件是否存在且当前用户是否有执行权限
-u file:文件是否存在且拥有suid权限
-g file:文件是否存在且拥有sgid权限
-k file:文件是否存在且拥有sticky权限

3)文件大小测试

-s file:文件是否存在且非空

4)文件是否被打开

-N file:文件自从上一次被读取之后是否被修改过
-O file:当前用户是否为文件属主
-G file:当前用户是否为文件属组

bash的逻辑运算:true(0)、false(1-255)

与运算

真 && 真 = 真
真 && 假 = 假
假 && 真 = 假
假 && 假 = 假
只要有假便为假

或运算

真 || 真 = 真
真 || 假 = 真
假 || 真 = 真
假 || 假 = 假
只要有真便为真

非运算

! 真 = 假 
! 假 = 真

示例:

ls / &> /dev/null && echo 'hello'	:当&&左边条件为真时,&&右边条件执行,&&左边条件为假时,&&右边条件不执行

ls /// &> /dev/null || echo 'hello'	:当||左边条件为假时,||右边条件执行,||左边条件为真时,||右边条件不执行

第二种方式

-a:与远算
-o:或运算
!:非运算
	
例:主机名是否为localhost,如果是改为centos
	[ `hostname` == localhsot ] && hostname centos || echo "current hostname is `hostname`"
例:测试文件是否存在
	[ -e /etc/passwd ] && cat /etc/passwd || echo "file not exist.."
例:测试主机名是否为空或者为localhost,如果为空或者为localhost则将其改为centos
	[ -z `hostname` -o hostname == `hostname` ] && hostname centos || echo "current hostname is `hostname`"

编写脚本backup.sh,可实现每日将/etc/目录备份到 /root/etcYYYY-mm-dd中

#!/bin/bash
#
#Filename:      backup.sh
#Description:   create script file
#Date:          2019-08-20 11:20:30
#*************************************************
dir=etc`date +"%Y-%m-%d"`
DIR=/root/$dir
[ -d $DIR ] && echo "dir exist.." && exit 0
mkdir $DIR
cp -ar /etc/* $DIR  &&  echo -e  "\033[1;5;31mcopy finished...\033[0m"

编写脚本nologin.sh和login.sh,实现禁止和允许普通用户登录系统

[root@centos7 bin]#cat nologin.sh 
#!/bin/bash
#
#*************************************************
#Filename:      login.sh
#Description:   create script file
#Date:          2019-08-20 11:38:59
#*************************************************
[ `id -u $1` -ge 1000 ]  || exit 1
[ $# -lt 1 ] && echo "please input a users .." && exit 0
read -p "your ensure ban user nologin ? input y/n:" NOLOGIN
[ $NOLOGIN == y ] && sed -i -r '/^'''$1'''/s#(.*:)([^:]+)$#\1/bin/nologin#' /etc/passwd && exit 0
[ $NOLOGIN == n ] && exit 0

[root@centos7 bin]#cat login.sh 
#!/bin/bash
#
#*************************************************
#Filename:      login.sh
#Description:   create script file
#Date:          2019-08-20 12:55:48
#*************************************************
[ $# -lt 1 ] && echo "please input a user .." && exit 0
[ ` id -u $1 ` -ge 1000 ] && sed -i -r '/^'''$1'''/s#(.*:)([^:]+)$#\1/bin/bash#'  /etc/passwd
read -p "you need login system ? input y/n :" LOGIN
[ $LOGIN == y ] && su - $1
[ $LOGIN == n ] && exit 0                                                                      

编写脚本disk.sh,显示当前硬盘分区中空间利用率最大的值

[root@centos7 bin]#cat disk.sh 
#!/bin/bash
#
#*************************************************
#Filename:      disk.sh
#Description:   create script file
#Date:          2019-08-20 13:08:14
#*************************************************
device=`df | grep "/dev/sd" |tr -s " " % | sort -t% -k5 -nr | cut -d% -f1 |head -1`
DISK=`df | grep "/dev/sd" | tr -s " " : | cut -d: -f5 | sort -nr|head -1`
echo "The most used is $device already use $DISK"

努力!奋斗!

你可能感兴趣的:(shell脚本语言入门基础)