Shell是一门解释性语言
#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即是用哪一种 Shell
新建一个文件 test.sh,扩展名为 sh(sh代表shell)
#!/bin/bash
echo "Hello World"
//运行方式1
sh test.sh
//运行方式2
chmod +x ./test.sh #使脚本具有执行权限
./test.sh #执行脚本
Shell变量
变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
- 中间不能有空格,可以使用下划线(_)。
- 不能使用标点符号。
- 不能使用bash里的关键字
//定义变量
your_name="tang"
//使用变量
echo $your_name
echo ${your_name}
字符串
字符串可以用单引号,也可以用双引号,也可以不用引号
双引号
双引号里可以有变量,也可以出现转义字符
name="xia"
str="Hello,I know you are \"${name}\"! \n"
echo $str
输出结果:
Hello,I know you are "xia"!
单引号
单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的,单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
str='this is a string'
字符串拼接
name="runoob"
# 使用双引号拼接
greeting="hello, "$name" !"
greeting_1="hello, ${name} !"
echo $greeting $greeting_1
输出结果:
hello, runoob ! hello, runoob !
# 使用单引号拼接
greeting_2='hello, '$name' !'
greeting_3='hello, ${name} !'
echo $greeting_2 $greeting_3
输出结果:
hello, runoob ! hello, ${name} !
获取字符串长度
name="xia"
echo ${#name}
提取子字符串
string="runoob is a great site"
echo ${string:1:4}
输出结果:
unoo
数组
bash支持一维数组(不支持多维数组),并且没有限定数组的大小。 在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的一般形式为:
数组名=(值1 值2 ... 值n)
//定义数组
array=(str str1 str2 str3)
//读取数组 ${数组名[下标]}
echo ${array[2]}
//打印所有数组
echo ${#array[@]} 或 echo ${#array[*]}
注释
单行注释
以 # 开头的行就是注释,会被解释器忽略。 通过每一行加一个 # 号设置多行注释,像这样:
#--------------------------------------------
# 这是一个注释
# author:tang
#--------------------------------------------
##### 用户配置区 开始 #####
#
#
# 这里可以添加脚本描述信息
#
#
##### 用户配置区 结束 #####
多行注释
多行注释还可以使用以下格式:
//方式1
:<<EOF
注释内容...
注释内容...
注释内容...
EOF
//方式2
:<<'
注释内容...
注释内容...
注释内容...
'
//方式3
:<<!
注释内容...
注释内容...
注释内容...
!
参数传递
我们可以在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数
#!/bin/bash
echo "Shell 传参实例"
echo "执行的文件名:$0"
echo "第一个参数: $1"
echo "第二个参数: $2"
echo "第三个参数: $3"
echo "参数个数: $#"
echo "参数拼成字符串: $*"
执行脚本: sh rui.sh 1 2 3
打印结果:
Shell 传参实例
执行的文件名:rui.sh
第一个参数: 1
第二个参数: 2
第三个参数: 3
参数个数: 3
参数拼成字符串: 1 2 3
@ 区别
- 相同点:都是引用所有参数。
- 不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1" "2" "3"(传递了三个参数)。
#!/bin/bash
echo "-- \$* 演示--"
for i in "$*"; do
echo $i
done
echo "-- \$@ 演示-- "
for i in "$@"; do
echo $i
done
执行脚本:
sh tangge.sh 1 2 3
执行结果:
-- $* 演示--
1 2 3
-- $@ 演示--
1
2
3
运算符
算数运算符
原生bash不支持简单的数学运算,可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。 expr 是一款表达式计算工具,使用它能完成表达式的求值操作。 例如,两个数相加 ( 注意使用的是反引号 ` 而不是单引号 ' )
#!/bin/bash
//表达式和运算符之间要有空格,例如 2+3 是不对的,必须写成 2 + 3,完整的表达式要被 ` ` 包含
val=`expr 2 + 3`
echo "结果: $val
执行脚本,输出结果:
结果: 5
运算符示例
#!/bin/bash
# author:tangge
a=10
b=20
val=`expr $a + $b`
echo "a + b : $val"
val=`expr $a - $b`
echo "a - b : $val"
//乘号(*)前边必须加反斜杠(\)才能实现乘法运算
val=`expr $a \* $b`
echo "a * b : $val"
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 : 30
a - b : -10
a * b : 200
a / b : 0
a % b : 10
a 不等于 b
关系运算符
关系运算符示例
#!/bin/bash
# author:tangge
a=10
b=20
if [ $a -eq $b ]
then
echo "$a -eq $b : a 等于 b"
else
echo "$a -eq $b : a 不等于 b"
fi
if [ $a -ne $b ]
then
echo "$a -ne $b : a 不等于 b"
else
echo "$a -ne $b : a 等于 b"
fi
if [ $a -gt $b ]
then
echo "$a -gt $b : a 大于 b"
else
echo "$a -gt $b : a 不大于 b"
fi
if [ $a -lt $b ]
then
echo "$a -lt $b : a 小于 b"
else
echo "$a -lt $b : a 不小于 b"
fi
if [ $a -ge $b ]
then
echo "$a -ge $b : a 大于或等于 b"
else
echo "$a -ge $b : a 小于 b"
fi
if [ $a -le $b ]
then
echo "$a -le $b : a 小于或等于 b"
else
echo "$a -le $b : a 大于 b "
fi
执行脚本,输出结果:
10 -eq 20 : a 不等于 b
10 -ne 20 : a 不等于 b
10 -gt 20 : a 不大于 b
10 -lt 20 : a 小于 b
10 -ge 20 : a 小于 b
10 -le 20 : a 小于或等于 b
布尔运算符
#!/bin/bash
# author:tangge
a=10
b=20
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a != $b : a 等于 b"
fi
if [ $a -lt 100 -a $b -gt 15 ]
then
echo "$a -lt 100 -a $b -gt 15 : 返回true"
else
echo "$a -lt 100 -a $b -gt 15 : 返回false"
fi
if [ $a -lt 100 -o $b -gt 100 ]
then
echo "$a -lt 100 -o $b -gt 100 : 返回true"
else
echo "$a -lt 100 -o $b -gt 100 : 返回false"
fi
if [ $a -lt 5 -o $b -gt 100 ]
then
echo "$a -lt 5 -o $b -gt 100 : 返回true"
else
echo "$a -lt 5 -o $b -gt 100 : 返回false"
fi
执行脚本,运行结果:
10 != 20 : a 不等于 b
10 -lt 100 -a 20 -gt 15 : 返回true
10 -lt 100 -o 20 -gt 100 : 返回true
10 -lt 5 -o 20 -gt 100 : 返回false
逻辑运算符
#!/bin/bash
# author:tangge
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
执行脚本,输出结果:
返回 false
返回 true
字符串运算符
#!/bin/bash
# author:tangge
a="abc"
b="efg"
if [ $a = $b ]
then
echo "$a = $b : a 等于 b"
else
echo "$a = $b : a 不等于 b"
fi
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a != $b : a 等于 b"
fi
if [ -n $a ]
then
echo "-n $a : 字符串长度不为 0"
else
echo "-n $a : 字符串长度为 0"
fi
if [ -z $a ]
then
echo "-z $a : 字符串长度为 0"
else
echo "-z $a : 字符串长度不为 0"
fi
if [ $a ]
then
echo "$a : 字符串不为空"
else
echo "$a : 字符串为空"
fi
执行脚本,输出结果:
abc = efg : a 不等于 b
abc != efg : a 不等于 b
-n abc : 字符串长度不为 0
-z abc : 字符串长度不为 0
abc : 字符串不为空
文件测试运算符
示例
#!/bin/bash
# author:tangge
file="/Users/tangge/test.sh"
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
fi
if [ -w $file ]
then
echo "文件可写"
else
echo "文件不可写"
fi
if [ -x $file ]
then
echo "文件可执行"
else
echo "文件不可执行"
fi
if [ -f $file ]
then
echo "文件为普通文件"
else
echo "文件为特殊文件"
fi
if [ -d $file ]
then
echo "文件是个目录"
else
echo "文件不是个目录"
fi
if [ -s $file ]
then
echo "文件不为空"
else
echo "文件为空"
fi
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi
执行脚本,输出结果:
文件可读
文件可写
文件可执行
文件为普通文件
文件不是个目录
文件不为空
echo命令
Shell 的 echo 指令与 PHP 的 echo 指令类似,都是用于字符串的输出。
普通字符串
这里的双引号完全可以省略,以下命令与上面实例效果一致:
echo "It is a test"
echo It is a test
转义字符
echo "\"It is a test\""
输出结果:
"It is a test"
显示变量
read 命令从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量
#!/bin/bash
# author:tangge
read name
echo "$name It is a test"
执行脚本:
sh demo5.sh
OK
输出结果:
OK It is a test
显示换行
echo -e "OK! \n" # -e 开启转义
执行结果:
OK!
流程控制
if else-if else
#!/bin/bash
# author:tangge
a=10
b=20
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
执行脚本,输出结果:
a 小于 b
for 循环
#!/bin/bash
# author:tangge
for num in 1 2 3 4 5
do
echo "value is : $num"
done
执行脚本,输出结果:
value is : 1
value is : 2
value is : 3
value is : 4
value is : 5
#!/bin/bash
for str in This is a string
do
echo $str
done
执行脚本,输出结果:
This
is
a
string
while循环
#!/bin/bash
num=1
while(( $num<=5 ))
do
echo $num
let "num++"
done
执行脚本,输出结果:
1
2
3
4
5
case ... esac
#!/bin/bash
echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
1) echo '你选择了 1'
;;
2) echo '你选择了 2'
;;
3) echo '你选择了 3'
;;
4) echo '你选择了 4'
;;
*) echo '你没有输入 1 到 4 之间的数字'
;;
esac
执行脚本,输出结果:
sh demo5.sh
输入 1 到 4 之间的数字:
你输入的数字为:
3
你选择了 3
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
执行脚本,输出结果:
-n 输入 1 到 5 之间的数字:
6
你输入的数字不是 1 到 5 之间的,游戏结束
函数
- 可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
- 参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)
无参无返回值函数
#!/bin/bash
demoFun(){
echo "这是我的第一个 shell 函数!"
}
echo "----函数开始执行----"
demoFun
echo "---函数执行完毕----"
执行脚本,返回结果:
----函数开始执行----
这是我的第一个 shell 函数!
---函数执行完毕----
有参数函数
函数返回值在调用该函数后通过 $? 来获得
#!/bin/bash
funWithReturn(){
echo "这个函数会对输入的两个数字进行相加运算..."
echo "输入的第一个数字:"
read num
echo "输入第二个数字:"
read anotherNum
echo "两个数字分别为 $num 和 $anotherNum !"
return $(($num+$anotherNum))
}
funWithReturn
echo "输入的两个数字的和为 $? !"
执行脚本,输入结果:
这个函数会对输入的两个数字进行相加运算...
输入的第一个数字:
8
输入第二个数字:
7
两个数字分别为 8 和 7 !
输入的两个数字的和为 15 !
有参函数
#!/bin/bash
funWithParam(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "总共有 $# 个参数 !"
echo "将所有参数拼成字符串输出: $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
执行脚本,输出结果:
第一个参数为 1 !
第二个参数为 2 !
第十个参数为 10 !
第十个参数为 34 !
总共有 11 个参数 !
将所有参数拼成字符串输出: 1 2 3 4 5 6 7 8 9 34 73 !
输入/输出重定向
输出重定向
输出重定向会覆盖文件内容
echo "堂哥学Shell" > test
cat test
输出结果:
堂哥学Shell
如果不希望文件内容被覆盖,可以使用 >> 追加到文件末尾
echo "杭杭爱吃肉" >> test
cat test
输出结果:
堂哥学Shell
杭杭爱吃肉
输入重定向
#!/bin/bash
# author:tangge
cat << EOF
欢迎来到
闲湖城-山景湾
www.hanghang.com
EOF
输出结果:
欢迎来到
闲湖城-山景湾
www.hanghang.com