目录
一、shell基础
1、shell的概念
Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务,简单的说就是用户和内核之间进行通信/沟通的翻译官。Shell 是一个用 C 语言编写的程序。
Shell 既是一种命令语言,又是一种程序设计语言。
2、shell环境
Shell 编程跟 JavaScript、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。
系统提供多种shell程序:cat /etc/shells
3、初见shell脚本
打开文本编辑器(可以使用 vi/vim 命令来创建文件),新建一个文件 test.sh
在文件写入下面的东西:
#!/bin/bash
echo "Hello World !"
保存退出!
运行shell的方法
1 | chmod +x ./test.sh #使脚本具有执行权限 |
2 | /bin/bash test.sh |
4、shell中变量
定义一个变量:
your_name="chenpingping"
注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
- 中间不能有空格,可以使用下划线(_)。
- 不能使用标点符号。
使用变量:
echo $your_name
echo ${your_name}
变量名外面的花括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界
另外:已经定义的变量可以重新定义,但是如果是只读的则不可以
readonly +变量名 //表示这个变量只读,不能重新赋值
删除变量
unset[空格] 变量名 (不能删除只读变量)
5、shell字符串
单引号中的内容会被当作普通字符串(java的String)来处理。
双引号中的内容会按照其原本的属性进行输出。
可用转义字符“\”将特殊符号(如$、\、!等)变为一般字符;
拼接字符串
使用双引号拼接
使用单引号拼接
获取字符串长度
获取子字符串
6、shell数组
定义数组: 数组名=(值1 值2 值3 值4)
利用@可以获取元素当中的所有元素
可以给数组单独赋值
array[1]=89
获取数组的长度
# 取得数组元素的个数
length=${#array[@]}
# 或者
length=${#array[*]}
# 取得数组单个元素的长度length=${#array[n]}
7、shell传递参数
我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,其中$0为执行的文件名,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……
举例:
另外,还有几个特殊字符用来处理参数:
$# | 传递到脚本的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数。 如"$*"用「"」括起来的情况、以"$1 $2 … $n"的形式输出所有参数。 |
$$ | 脚本运行的当前进程ID号 |
$! | 后台运行的最后一个进程的ID号 |
$@ | 与$*相同,但是使用时加引号,并在引号中返回每个参数。 如"$@"用「"」括起来的情况、以"$1" "$2" … "$n" 的形式输出所有参数。 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
二、if与test判断
1、if判断
条件判断语句:
语法:
if语法
#!/bin/bash
a=10
b=10
if [ $a -eq $b ] #注意此处空格
then
echo "两个数相等"
fi
if else语法
#!/bin/bash
string="hello"
string1="HELLO"
if test $string = $string1
then
echo "两个字符串一样"
else
echo "两个字符串不一样"
fi
if else-if else语法
以下实例判断两个变量是否相等:
#!/bin/bash
a=$1
b=$2
if [ $a == $b ];then
echo "a等于b"
elif [ $a -gt $b ];then
echo "a大于b"
elif [ $a -lt $b ];then
echo "a小于b"
else
echo "没有符合的条件"
fi
2、test判断
Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。
数值测试
参数 | 说明 |
-eq | 等于则为真 |
-ne | 不等于则为真 |
-gt | 大于则为真 |
-ge | 大于等于则为真 |
-lt | 小于则为真 |
-le | 小于等于则为真 |
举例:
#!/bin/bash
num1=100
num2=100
if test $[num1] -eq $[num2]
then
echo '两个数相等!'
else
echo '两个数不相等!'
fi
字符串测试
参数 | 说明 |
= | 等于则为真 |
!= | 不相等则为真 |
-z 字符串 | 字符串的长度为零则为真 |
-n 字符串 | 字符串的长度不为零则为真 |
举例:
#!/bin/bash
num1="piaolaoshi"
num2="PIAOLAOSHI"
if test $num1 = $num2
then
echo '两个字符串相等!'
else
echo '两个字符串不相等!'
fi
文件测试
参数 | 说明 |
-e 文件名 | 如果文件存在则为真 |
-r 文件名 | 如果文件存在且可读则为真 |
-w 文件名 | 如果文件存在且可写则为真 |
-x 文件名 | 如果文件存在且可执行则为真 |
-s 文件名 | 如果文件存在且至少有一个字符则为真 |
-d 文件名 | 如果文件存在且为目录则为真 |
-f 文件名 | 如果文件存在且为普通文件则为真 |
-c 文件名 | 如果文件存在且为字符型特殊文件则为真 |
-b 文件名 | 如果文件存在且为块特殊文件则为真 |
举例:
#!/bin/bash
cd /bin
if test -e ./bash
then
echo '文件已存在!'
else
echo '文件不存在!'
fi
另外,Shell还提供了与( -a )、或( -o )、非( ! )三个逻辑操作符用于将测试条件连接起来,其优先级为:"!"最高,"-a"次之,"-o"最低。例如:
#!/bin/bash
cd /bin
if test -e ./notFile -o -e ./bash
then
echo '至少有一个文件存在!'
else
echo '两个文件都不存在'
fi
?
三、运算符
1、算术运算符
下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
+ | 加法 | `expr $a + $b` 结果为 30。 |
- | 减法 | `expr $a - $b` 结果为 -10。 |
* | 乘法 | `expr $a \* $b` 结果为 200。 |
/ | 除法 | `expr $b / $a` 结果为 2。 |
% | 取余 | `expr $b % $a` 结果为 0。 |
= | 赋值 | a=$b 将把变量 b 的值赋给 a。 |
== | 相等。用于比较两个数字,相同则返回 true。 | [ $a == $b ] 返回 false。 |
!= | 不相等。用于比较两个数字,不相同则返回 true。 | [ $a != $b ] 返回 true。 |
#!/bin/bash
a=10
b=20
val=`expr $a + $b`
echo "a + b : $val"
val=`expr $a \* $b`
echo "a * b : $val"
if [ $a == $b ]
then
echo "a 等于 b"
fi
if [ $a != $b ]
then
echo "a 不等于 b"
fi
条件表达式要放在方括号之间,并且要有空格,
例如: [$a==$b] 是错误的,必须写成 [ $a == $b ]。
乘号(*)前边必须加反斜杠(\)才能实现乘法运算;
2、关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
-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。 |
#!/bin/bash
a=10
b=20
if [ $a -eq $b ]
then
echo " a 等于 b"
else
echo " a 不等于 b"
fi
if [ $a -gt $b ]
then
echo "a 大于 b"
else
echo "a 不大于 b"
fi
if [ $a -lt $b ]
then
echo "a 小于 b"
else
echo "a 不小于 b"
fi
3、逻辑运算符
以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
&& | 逻辑的 AND | [[ $a -lt 100 && $b -gt 100 ]] 返回 false |
|| | 逻辑的 OR | [[ $a -lt 100 || $b -gt 100 ]] 返回 true |
#!/bin/bash
a=10
b=20
if [[ $a -lt 100 && $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
if [[ $a -lt 100 || $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
4、字符串运算符
下表列出了常用的字符串运算符,假定变量 a 为 "abc",变量 b 为 "efg":
运算符 | 说明 | 举例 |
= | 检测两个字符串是否相等,相等返回 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。 |
#!/bin/bash
a="abc"
b="efg"
if [ $a = $b ]
then
echo "a 等于 b"
else
echo " a 不等于 b"
fi
if [ -z $a ]
then
echo "字符串长度为 0"
else
echo " 字符串长度不为 0"
fi
if [ $a ]
then
echo "$a : 字符串不为空"
else
echo "$a : 字符串为空"
fi
5、文件测试运算符
文件测试运算符用于检测 Unix 文件的各种属性。
属性检测描述如下:
操作符 | 说明 | 举例 |
-b file | 检测文件是否是块设备文件,如果是,则返回 true。 | [ -b $file ] 返回 false。 |
-c file | 检测文件是否是字符设备文件,如果是,则返回 true。 | [ -c $file ] 返回 false。 |
-d file | 检测文件是否是目录,如果是,则返回 true。 | [ -d $file ] 返回 false。 |
-f file | 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 | [ -f $file ] 返回 true。 |
-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。 |
变量 file 表示文件/root/install.log,它的大小为 20k,具有 rwx 权限。下面的代码,将检测该文件的各种属性:
#!/bin/bash
file="/root/install.log"
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
fi
if [ -w $file ]
then
echo "文件可写"
else
echo "文件不可写"
fi
if [ -f $file ]
then
echo "文件为普通文件"
else
echo "文件为特殊文件"
fi
if [ -d $file ]
then
echo "文件是个目录"
else
echo "文件不是个目录"
fi
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi
四、循环语句
1、for语句
for循环一般格式为:
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
举例:
#!/bin/bash
for num in 1 2 3 4 5
do
echo "The value is: $num"
done
顺序输出字符串中的字符:
for str in 'This is a string'
do
echo $str
done
练习:九九乘法表
#!/bin/bash
for i in {1..9};do
for y in {1..9};do
if [ $y -le $i ];then
echo -n "$y*$i=$(($y*$i)) "
fi
done
echo ""
done
~
2、while语句
while循环用于不断执行一系列命令,也用于从输入文件中读取数据其格式为:
while condition
do
command
done
以下是一个基本的while循环,测试条件是:如果int小于等于5,那么条件返回真。int从0开始,每次循环处理时,int加1。运行上述脚本,返回数字1到5,然后终止。
#!/bin/bash
int=1
While [ $ int -le 10]
do
echo $int
let "int++"
done
另外:while循环可用于读取键盘信息。下面的例子中,输入信息被设置为变量FILM,按<Ctrl-D>结束循环。
#!/bin/bash
echo -n '输入你最喜欢的明星: '
while read person
do
echo "是的!$person 是一个好人"
done
3、无限循环
无限循环语法格式:
while :
do
command
done
或者
while true
do
command
done
4、until循环
until 循环执行一系列命令直至条件为 true 时停止。
until 循环与 while 循环在处理方式上刚好相反。
以下实例我们使用 until 命令来输出 0 ~ 9 的数字:
#!/bin/bash
a=0
until [ ! $a -lt 10 ]
do
echo $a
a=`expr $a + 1`
done
5、case
Shell case语句为多选择语句。可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令
下面的脚本提示输入1到4,与每一种模式进行匹配:
echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read num
case $num in
1) echo '你选择了 1'
;;
2) echo '你选择了 2'
;;
3) echo '你选择了 3'
;;
4) echo '你选择了 4'
;;
*) echo '你没有输入 1 到 4 之间的数字'
;;
esac
6、break命令
break命令允许跳出所有循环(终止执行后面的所有循环)。
下面的例子中,脚本进入死循环直至用户输入数字大于5。要跳出这个循环,返回到shell提示符下,需要使用break命令。
#!/bin/bash
while :
do
echo -n "输入 1 到 5 之间的数字:"
read num
case $num in
1|2|3|4|5) echo "你输入的数字为 $num!"
;;
*) echo "你输入的数字不是 1 到 5 之间的数字! 游戏结束"
break
;;
esac
done
五、函数
Shell 函数
linux shell 可以用户定义函数,然后在shell脚本中可以随便调用。
举例:
#!/bin/bash
sayHi(){
echo "hello student"
}
sayHi
下面定义一个带有return语句的函数:
#!/bin/bash
funWithReturn(){
echo "这个函数会对输入的两个数字进行相加运算..."
echo "输入第一个数字: "
read num1
echo "输入第二个数字: "
read num2
echo "两个数字分别为 $num1 和 $num2 "
return $(($num1+$num2))
}
funWithReturn
echo "输入的两个数字之和为 $? "
函数参数
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数...
带参数的函数示例:
#!/bin/bash
funWithParam(){
echo "第一个参数为 $1 "
echo "第二个参数为 $2 "
echo "第十个参数为 $10 "
echo "第十个参数为 ${10} "
echo "第十一个参数为 ${11} "
echo "参数总数有 $# 个"
echo "作为一个字符串输出所有参数 $* "
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
注意:$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。
六、练习
1、练习1
写一个脚本:
1.创建目录/tmp/scripts
2.切换工作目录至此目录中
3.复制/etc/pam.d目录至当前目录,并重命名为test
4.将当前目录test属主改为bin,属组改为adm
5.将test文件的权限改为用户可读可写可执行,用户组可读可写,其他人没有任何权限
#!/bin/bash
mkdir -p /tmp/scripts
cd /tmp/scripts
cp -r /etc/pam.d ./test
chown bin:adm ./test
chmod 760 ./test
查看结果:
2、练习2
写一个脚本:
脚本生成一个 100 以内的随机数,提示用户猜数字,根据用户的输入,提示用户猜对了,
# 猜小了或猜大了,直至用户猜对脚本结束。
# RANDOM 为系统自带的系统变量,值为 0‐32767的随机
# 使用取余算法将随机数变为 1‐100 的随机数
#!/bin/bash
num=$[RANDOM%100+1]
echo "$num"
while :
do
read -p "计算机生成了一个 1‐100 的随机数,你猜: " cai
if [ $cai -eq $num ]
then
echo "恭喜,猜对了"
exit
elif [ $cai -gt $num ]
then
echo "不好意思,猜大了"
else
echo "不好意思,猜小了"
fi
done