shell脚本基础

检查脚本语法错误
	bash -n script_name.sh
调试脚本:
	bash -x script_name.sh

set -e	或	set +e
	-e表示从当前位置开始,如果出现任何错误都将触发exit,退出脚本
	+e表示不管出现任何错误都将继续执行脚本
	
shift	对参数的左移(参数下标增大,右移),参数个数不确定情况下遍历参数进行处理
	
注释:
	单行注释:#
	多行注释:
		:<<!	被注释的内容,可换行	!
		:'	被注释的内容,可换行	'
双引号和单引号区别:
	" "输出含变量的值先解析变量的值和命令,保留变量原格式
	' '原样输出单引号的内容
` `反引号:可将内容解析为系统命令
exit	1		#退出当前脚本返回一个状态值
nohup	后台执行,通常和&连用
	nohup script_name.sh	>/dev/null	2>1&	&		#后台执行脚本,并将错误输出和正确输出定向到/dev/null中(/dev/null表示空值,表示丢弃一切写入其中的数据)

POSIX字符类

[[:upper:]]    表示大写字母[A-Z]
[[:lower:]]    表示小写字母[a-z]
[[:digit:]]    表示阿拉伯数字[0-9]
[[:alnum:]]    大小写字母和数字[0-9a-zA-Z]
[[:space:]]    表示空格或Tab键
[[:alpha:]]    大小写字母[a-zA-Z]
[[:cntrl:]]    表示ctrl键
[[:graph:]]或[:print:]  ASCII中33-126之间的字符
[[:xdigit:]]   16进制数字
[[:punct:]]    匹配标点符号
[[:blank:]]    匹配空格或制表符			

变量

创建普通变量: name="test"   #"="两边不能有空格
创建局部变量: local name="test"	#关键字local
引用变量: $name	或		${name}
变量重新赋值:	name="new"
只读变量:	
	name="test"
	readonly	name	#关键字readonly
删除变量:	unset name	#不能删除只读变量

字符串变量
	单引号:
		var='test'		#只能原样输出,变量无效,无法转义
	双引号:
		var="this is ${name}"	#变量有效,可以使用转义

参数传递
	获取参数值:
		$0	代表执行的文件
		$1	代表传入的第一个参数
	
	$#	参数总个数
	$*	所有向脚本传递的参数,一个整字符串,"$1 $2 $3..."
	$@	同$*,使用引号将每个参数分开输出,"$1" "$2" "$3"
	$$	返回脚本运行的当前进程号
	$!	后台运行的最后一个进程ID
	$?	显示最后命令的执行状态,0表示无错误,其它表示错误
	$-  显示上一个脚本最后一个传入的参数

算数运算

+ - * \		#乘号必须进行转义

加法运算

val=`expr 2 + 1`	#数字之间必须使用空格隔开
val=$[2+3]			#空格可省略
val=$((2+4))		#空格可省略

关系运算符

-eq: 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 false。
-ne: 检测两个数是否不相等,不相等返回 true。 [ $a -ne $b ] 返回 true。
-gt: 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。
-lt: 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。
-ge: 检测左边的数是否大于等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。
-le: 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。

字符串运算符

=: 检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。
!=:检测两个字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。
-z:检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。
-n:检测字符串长度是否为0,不为0返回 true。 [ -n "$a" ] 返回 true。
$: 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。

布尔运算符

! :非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。
-o:或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a:与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。

逻辑运算符

&&:逻辑的 AND [[ $a -lt 100 && $b -gt 100 ]] 返回 false
||:逻辑的 OR [[ $a -lt 100 || $b -gt 100 ]] 返回 true

文件运算符

-b file :检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。
-c file :检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ] 返回 false。
-d file :检测文件是否是目录,如果是,则返回 true。 [ -d $file ] 返回 false。
-f file :检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 [ -f $file ] 返回 true。
-g file :检测文件是否设置了 SGID 位,如果是,则返回 true。 [ -g $file ] 返回 false。
-k file :检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 [ -k $file ] 返回 false。
-p file :检测文件是否是有名管道,如果是,则返回 true。 [ -p $file ] 返回 false。
-u file :检测文件是否设置了 SUID 位,如果是,则返回 true。 [ -u $file ] 返回 false。
-r file :检测文件是否可读,如果是,则返回 true。 [ -r $file ] 返回 true。
-w file :检测文件是否可写,如果是,则返回 true。 [ -w $file ] 返回 true。
-x file :检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true。
-s file :检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true。
-e file :检测文件(包括目录)是否存在,如果是,则返回 true。 [ -e $file ] 返回 true。

括号运算

[ ]		运算符两边必须添加空格,字符串和数字比较
[[ ]]	运算符两边必须添加空格,字符串比较加强版
(( ))	运算符两边必须添加空格,数字比较加强版
( )		用于shell命令及输出,在其中变量赋值不影响当前进程环境影响(会新开一个进程执行其中的命令),括号外的值不受括号里面赋值影响,但可以受里面的值影响
{ }		快速替换,其中的命令由当前进程执行,多命令之间用";"隔开

字符串实例

1. 取长度
	str="abcd"
	expr length $str     # 4
	echo ${#str}         # 4
	expr "$str" : ".*"   # 4
2. 查找子串的位置
	str="abc"
	expr index $str "a"  # 1
	expr index $str "b"  # 2
	expr index $str "x"  # 0
	expr index $str ""   # 0
3. 选取字串
	str="abcdef"
	expr substr "$str" 1 3  #从第一个位置开始取3个字符,abc
	expr substr "$str" 2 5  #从第二个位置开始取5个字符,abcdef
	expr substr "$str" 4 5  #从第四个位置开始取5个字符,def
	expr ${str:2}       #从第二个位置开始提取字符串,bcdef
	expr ${str:2:3}     #从第二个位置开始提取3个字符,bcdef
	expr ${str:(-6):5}  #从倒数第二个位置向左提取字符串,abcdef
	expr ${str:(-4):3}  #从倒数第二个位置开始向左提取6个字符,cde
4. 截取子串
	str="abbc,def,ghi,abcjkl"
	echo ${str#a*c}     # 输出,def,ghi,abcjkl  一个井号(#) 表示从左边截取掉最短的匹配 (这里把abbc字串去掉)
	echo ${str##a*c}    # 输出jkl,             两个井号(##) 表示从左边截取掉最长的匹配 (这里把abbc,def,ghi,abc字串去掉)
	echo ${str#"a*c"}   # 输出"abbc,def,ghi,abcjkl" 因为str中没有"a*c"子串
	echo ${str##"a*c"}  # 输出"abbc,def,ghi,abcjkl" 同上
	echo ${str#*a*c*}   # 空
	echo ${str##*a*c*}  # 空
	echo ${str#d*f)     # 输出abbc,def,ghi,abcjkl,
	echo ${str#*d*f}    # 输出,ghi,abcjkl
	echo ${str%a*l}     # abbc,def,ghi  一个百分号(%)表示从右边截取最短的匹配
	echo ${str%%b*l}    # a             两个百分号表示(%%)表示从右边截取最长的匹配
	echo ${str%a*c}     # abbc,def,ghi,abcjkl
5. 字符串替换
	str="apple, tree, apple tree"
	echo ${str/apple/APPLE}   # 替换第一次出现的apple
	echo ${str//apple/APPLE}  # 替换所有apple
	echo ${str/#apple/APPLE}  # 如果字符串str以apple开头,则用APPLE替换它
	echo ${str/%apple/APPLE}  # 如果字符串str以apple结尾,则用APPLE替换它
6. 比较
	[[ "a.txt" == a* ]]        # 逻辑真 (pattern matching)
	[[ "a.txt" =~ .*\.txt ]]   # 逻辑真 (regex matching)
	[[ "abc" == "abc" ]]       # 逻辑真 (string comparision)
	[[ "11" < "2" ]]           # 逻辑真 (string comparision), 按ascii值比较
	
7. 判断读取字符串值
	${var}	变量var的值, 与$var相同
	${var-DEFAULT}	如果var没有被声明, 那么就以$DEFAULT作为其值
	${var:-DEFAULT}	如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值,判断var变量是否没有定义
	${var=DEFAULT}	如果var没有被声明, 那么就以$DEFAULT作为其值
	${var:=DEFAULT}	如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值 ,判断var变量是否没有定义,并确保变量始终有值
	${var+OTHER}	如果var声明了, 那么其值就是$OTHER, 否则就为null字符串
	${var:+OTHER}	如果var被设置了, 那么其值就是$OTHER, 否则就为null字符串
	${var?ERR_MSG}	如果var没被声明, 那么就打印$ERR_MSG
	${var:?ERR_MSG}	如果var没被设置, 那么就打印$ERR_MSG
	${!varprefix*}	匹配之前所有以varprefix开头进行声明的变量
	${!varprefix@}	匹配之前所有以varprefix开头进行声明的变量

echo

输出,将参数打印到标准输出,参数之间用空格隔开,以换行符结束
参数:
	-n		不换行输出(默认换行)
	-e		启用反斜杠转义解释
	-E	禁用反斜杠转义解释

echo -e "\033[字背景颜色;文字颜色m字符串\033[0m"
\033 等价 \e 
多格式用;隔开
字颜色:30—–37   字背景颜色:40—–47
30      40      黑色
31      41      红色
32      42      绿色
33      43      黄色
34      44      蓝色
35      45      紫红色
36      46      青蓝色
37      47      白色

ANSI控制码说明:
	\33[0m 关闭所有属性
	\33[1m 设置高亮度
	\33[3m 斜体
	\33[4m 下划线
	\33[5m 闪烁
	\33[7m 反显
	\33[8m 消隐
	\33[9m 中划线
	\33[30m -- \33[37m 设置前景色
	\33[40m -- \33[47m 设置背景色
	\33[nA 光标上移n行
	\33[nB 光标下移n行
	\33[nC 光标右移n行
	\33[nD 光标左移n行
	\33[y;xH设置光标位置
	\33[2J 清屏
	\33[K 清除从光标到行尾的内容
	\33[s 保存光标位置
	\33[u 恢复光标位置
	\33[?25l 隐藏光标
	\33[?25h 显示光标

printf

输出,不会自动提供换行符
%s	输出字符串
%d	或%i	输出整数
%3.2f	输出浮点数,3表示整数位,2表示小数位
\f	换页
\n	换行
\r	回车
\v	垂直制表符
\b	退格
printf	'%s'	$(ls /tmp)		#输出后面命令的结果

read

从标准输入获取值
参数:
	-p		添加提示语句
	-n		限制参数个数
	-r		屏蔽转义字符,作普通字符处理
	-s		静默模式,输入内容不显示在屏幕
	-t		指定时间,超出时间后退出read,不读取任何内容

if判断语句

单分支结构:
	if	[ 判断操作 ]		#if后面与"["必须空格
	then
		[ 操作序列 ]
	fi
	#if和then同行时
	if [ 判断操作 ];then
		[ 操作序列 ]
	fi
多分支结构:
	if	[ 判断操作 ]
	then
		[ 操作序列 ]
	elif	[ 判断操作 ]
	then
		[ 操作序列 ]
	else
		[ 操作序列 ]
	fi
其它:
	if  [ 判断操作 ]  &&  [ 判断操作 ]  &&  [ 判断操作 ]
	if  [ 判断操作 ]	;then :			#	":"表示不作任何操作

for循环语句

结构:
	for 变量名 in 取值列表
	do
		[ 操作序列 ]
	done
	
	取值列表:
		in 1 2 3 4 5		#取1,2,3,4,5这几个参数
		in {1..5}			#同上,取1到5的值简写
		in {1..100..2}		#取1,3,5...97,99值,1-100且步长为2
		in $(seq 1 2 100)	#seq命令实现1到100且步长为2的取值,同上
C语言风格:
	for((表达式1;表达式2;表达式3))
	do
		[ 操作序列 ]
	done
	#所有变量可以不用加$前缀,可以使用逻辑运算和四则运算,支持多个表达式之间用","隔开

从文件中获取变量值
	for line in `cat file`
	do
		echo	$line
	done

while循环语句

结构:
	while	测试操作
	do
		[ 操作序列 ]
	done

从文件中获取变量值
	while read -r line
	do
		echo $line
	done < filename

case条件语句

结构:
	case 变量 in 
		模式1)
			命令序列
			;;
		模式2)
			命令序列
			;;
			....
		*)
			默认命令序列
			;;
		esac

until语句

until与while循环类似
结构:
	until
		do
			command....
		done
	#首次执行为0状态时,一次也不执行

select选择语句

功能类似于case,用于交互菜单显示
结构:
	select 变量 in 列表值
	do
		command...
		break
	done

函数

定义:
	function func 
	{
		shell command
	}
	或
	func () {
		shell command
	}
local		在函数内部声明局部变量,覆盖全局变量

数组

shell只支持一维数组
调用随机数函数$RANDOM,返回一个范围在0-32767之间的随机整数
$[RANDOM%100+100]

定义数组:
	array_name=(beijing shanghai guangzhou shenzhen)	#小括号作边界,使用空格分离
单独定义数组的元素:
	array_name[0]="北京"
	array_name[1]="上海"
	array_name[3]="深圳"		#下标可不连续
	
	unset 	array[1]		#清空数组元素
	unset	array			#清空整个数组
获取数组元素:
	echo ${array_name[1]}
	echo ${array_name[@]}		#输出数组所有元素,没有元素的下标省略
	echo ${array_name[*]}		#输出数组所有元素

获取元素个数:
	${#array_name[@]}	或	${#array_name}
获取单个元素长度:
	${#array_name[1]}

参数传递
	获取参数值:
		$0	代表执行的文件
		$1	代表传入的第一个参数
		
read -a array	#从标准输入获取值

##for i in "{array[@]}"		#遍历含空格的元素需要使用引号
##for i in "{array[*]}"		#使用*时加引号,不分行打印
for i in ${array[@]}	#可将@替换为*,遍历数组的所有赋值过的元素,分行打印
do
	echo $i
done

特殊用法:
	${array[*]:0}	#抽取整个数组
	${array[*]:4}	#取从第4个元素到结束
	${array[*]:1:2}	#取从1个到第2个元素
	${array[*]#z*c}	#匹配每个元素删除以"z"开头"c"结束的最长字串
	${array[*]/m*x/new}	#替换数组中每个元素第一次相匹配的字串
	${array[*]//m*x/new}	#替换数组每个元素所有匹配的字串

加密shell脚本

安装shc加密工具
#wget http://www.datsi.fi.upm.es/%7Efrosal/sources/shc-3.8.7.tgz
#tar  zvxf shc-3.8.7.tgz
#cd shc-3.8.7
#make test  && make strings  && make install
yum安装
#yum -y install shc
#shc -rvf  文件
shc命令参数:
	-e  date  指定过期时间
	-m  message  指定过期时间提示信息
	-f  script_filename 指定加密的文件名或者路径
	-r  可在相同操作系统的不同主机行执行
	-v  加密详细过程
#shc  -e  03/23/2021  -f  test.sh  脚本过期时间设置
#shc  -m  “hello”  -f  test.sh     指定到期时间后返回的信息
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值