文章目录
- 一、Shell是什么?
- 二、Shell脚本的格式及其运行方式
- 三、变量
- 四、运算符
- 五、条件判断
- 六、程序流程
- 八、函数
一、Shell是什么?
shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核。并且提供一个交互式的命令行窗口。
shell的定位:相当于外层应用层和linux
内核的之间的翻译官,并且是一个功能相当强大的编程语言,易编写,易调试,灵活性强。
二、Shell脚本的格式及其运行方式
1.脚本格式
脚本以#!/bin/bash
开头(指定解析器)
2.第一个脚本:helloworld.sh
vim helloworld.sh
在helloworld.sh中输入如下内容
#!/bin/bash
echo "hello,world!"
3.脚本的运行
- bash 或者 sh + 脚本的相对路径或绝对路径(不用赋予脚本+x权限)
bash ./helloworld.sh
或者
sh ./helloworld.sh
- 直接出入脚本的绝对路径或者相对路径执行脚本(必须要有可执行权限+x)
chmod 744 helloworld.sh
./holleworld.sh
- (了解) 在脚本路径前加上‘ . ’ 或者 source
在当前路径下执行
. helloworld.sh
source helloworld.sh
注意:
- 前两种方式都是在当前shell中打开一个子shell来执行脚本内容,当脚本内容结束,则子shell关闭,回到父shell中。
- 第三种使用
.
或者source
的方式,可以使脚本内容在当前shell里执行,而无需打开子shell。这也是为什么我们每次要修改完/etc/profile文件以后,需要source一下的原因。 - 开了子shell与不开子shell的区别就在于,环境变量的继承关系,如在子shell中设置的当前变量,父shell是不可见的。
三、变量
1.系统预定义变量
常见系统变量 $HOME
、$PWD
、$SHELL
、$USER
等
案例实操
(1)查看系统变量的值
echo $HOME
/home/xy
(2)显示当前Shell中所有变量:set
2.自定义变量
基本语法
- 定义变量:变量名=变量值,注意,=号前后不能有空格
- 撤销变量:unset变量名
- 声明静态变量:readonly变量,注意:不能unset
变量定义规则
- 变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写。
- 等号两侧不能有空格
- 在bash中,变量默认类型都是字符串类型,无法直接进行数值运算。
- 变量的值如果有空格,需要使用双引号或单引号括起来。
3.特殊变量 – 参数
(1)$n
$n
(功能描述:n为数字,$0
代表该脚本名称,$1
-$9
代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如${10})
(2)$#
(功能描述:获取所有输入参数个数,常用于循环,判断参数的个数是否正确以及加强脚本的健壮性)。
(3) $*
(功能描述:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体)
$@
(功能描述:这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待)
[root@hadoop100 cripts]# vim parameter.sh
#!/bin/bash
echo $0
echo $1
echo $2
echo $*
echo $@
[root@hadoop100 cripts]# . parameter.sh 1 2
bash
1
2
1 2
1 2
(4)$?
(功能描述:最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。)
[root@hadoop100 cripts]# parameter.sh
bash: parameter.sh: 未找到命令...
[root@hadoop100 cripts]# echo $?
127
[root@hadoop100 cripts]# ./hello.sh
hello,world!
hello
[root@hadoop100 cripts]# echo $?
0
四、运算符
由于linux
默认是字符创的形式,因此不能直接像其他编程语言那样直接使用‘+ - * / ’这些运算符
而要采用如下形式:$((运算式))
或 $[运算式]
例子:传入两个参数并计算他们的和
[root@hadoop100 cripts]# vim add.sh
#!/bin/bash
echo "calculation:"
echo $[$1 + $2]
[root@hadoop100 cripts]# ./add.sh 12 12
bash: ./add.sh: 权限不够
[root@hadoop100 cripts]# chmod +x add.sh
[root@hadoop100 cripts]# ./add.sh 12 12
calculation:
24
五、条件判断
1. 基本语法
- test condition
- [ condition ] (两边一定要有空格)
注意:条件非空即为true,[hello]返回true,[ ]返回false。
2. 常用判断条件
(1)两个整数之间比较
-eq
等于(equal)-ne
不等于(not equal)-lt
小于(less than)-le
小于等于(less equal)-gt
大于(greater than)-ge
大于等于(greater equal)
注:如果是字符串之间的比较,用等号“=”判断相等;用“!=”判断不等。
(2)按照文件权限进行判断
-r
有读的权限(read)-w
有写的权限(write)-x
有执行的权限(execute)
(3)按照文件类型进行判断
-e
文件存在(existence)-f
文件存在并且是一个常规的文件(file)d
文件存在并且是一个目录(directory)
3.例子
[root@hadoop100 cripts]# [ -r hello.sh ]
[root@hadoop100 cripts]# echo $?
0
[root@hadoop100 cripts]# [ 1 -eq 2 ]
[root@hadoop100 cripts]# echo $?
1
4.多条件判断
(&& 表示前一条命令执行成功时,才执行后一条命令, || 表示上一条命令执行失败后,才执行下一条命令)
例一
[root@hadoop100 cripts]# [ hello ] && echo hello || echo world
hello
[root@hadoop100 cripts]# echo $?
0
例二
[root@hadoop100 cripts]# a=15
[root@hadoop100 cripts]# [ $a -lt 20 ]&& echo "$a < 20 " || echo "$a >= 20"
15 < 20
六、程序流程
1. if 单分支语法
if [ 条件判断式 ]
then
程序
fi
2. 多分支语法
if [ 条件判断式 ]
then
程序
elif [ 条件判断式 ]
then
程序
...
else
程序
fi
注意事项:
- [ 条件判断式 ] ,中括号和条件之间必须有空格
- if 后面要有空格
小练习:实现输入不同年龄,输出你所在的年龄段
[root@hadoop100 cripts]# vim if.sh
bin/bash
if [ $1 -le 18 ]
then
echo "Juveniles"
elif [ $1 -le 50 ]
then
echo "adult"
else
echo "aged"
fi
[root@hadoop100 cripts]# chmod +x if.sh
[root@hadoop100 cripts]# ./if.sh 10
Juveniles
[root@hadoop100 cripts]# ./if.sh 20
adult
[root@hadoop100 cripts]# ./if.sh 66
aged
3. case语法
case $变量名 in
"值1")
程序1
;;
"值2")
程序2
;;
"值3")
程序3
;;
...其他分支...
*)
程序
;;
esac
注意事项:
- case行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束。
- 双分号“;;”表示命令序列结束,相当于其他编程语言中的break。
- 最后的“*)”表示默认模式,相当于其他编程语言中的default。
小练习:输入数字,输出数字对应的英文(支持到3即可)
[root@hadoop100 cripts]# vim case.sh
#!/bin/bash
case $1 in
"1")
echo "one"
;;
"2")
echo "two"
;;
"3")
echo "three"
;;
*)
echo "other"
esac
[root@hadoop100 cripts]# chmod +x case.sh
[root@hadoop100 cripts]# ./case.sh 1
one
[root@hadoop100 cripts]# ./case.sh 2
two
[root@hadoop100 cripts]# ./case.sh 4
other
4. for循环语法
实现方式一
for ((初始值;循环控制条件;变量变化))
do
程序
done
实现方式二(类似于加强for循环)
for 变量 in 值1 值2 值3 值4
do
程序
done
小练习:输入一个数a,输出1到a之间所有数的和
[root@hadoop100 cripts]# vim for1.sh
#!/bin/bash
sum=0
for (( i=1;i<=$1;i++))
do
let sum+=i
done
echo $sum
[root@hadoop100 cripts]# chmod +x for1.sh
[root@hadoop100 cripts]# ./for1.sh 100
5050
5. while循环语法
while [ 条件判断 ]
do
程序
done
小练习:输入一个数a,输出1到a之间所有数的和
[root@hadoop100 cripts]# vim while.sh
#!/bin/bash
i=1
sum=0
while [ $i -le $1 ]
do
let sum+=i
let i++
done
echo $sum
[root@hadoop100 cripts]# chmod +x while.sh
[root@hadoop100 cripts]# ./while.sh 100
5050
七、read读取控制台输入
read基本语法
read(选项) (参数)
①选项:
-p:指定读取值时的提示符;
-t:指定读取值时等待的时间(秒)如果-t不加表示一直等待
②参数
变量:指定读取值的变量名
小练习:提示七秒内,读取控制台输入的名称
#!/bin/bash
read -t 7 -p "Enteryournamein7seconds:" name
echo $name
八、函数
1.系统函数
(1) basename
bsename [string/pathname][suffix]
(功能描述:basename
命令会删掉所有的前缀包括最后一个(‘/’)字符,然后将字符串显示出来。basename
可以理解为取路径里的文件名称
选项:
suffix为后缀,如果suffix被指定了,basename
会将pathname或string中的suffix去掉。
[root@hadoop100 cripts]# basename /root/cripts/for1.sh
for1.sh
[root@hadoop100 cripts]# basename /root/cripts/for1.sh .sh
for1
(2) dirname
dirname
文件绝对路径(功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分))dirname
可以理解为取文件路径的绝对路径名称
[root@hadoop100 cripts]# dirname /root/cripts
/root
2. 自定义函数
语法:
[function]funname[()]{
Action;
[returnint;]
}
经验技巧
- 必须在调用函数地方之前,先声明函数,shell脚本是逐行运行。不会像其它语言一样先编译。
- 函数返回值,只能通过$?系统变量获得,可以显示加:return返回,如果不加,将以最后一条命令运行结果,作为返回值。return后跟数值n(0-255)
小练习:计算两个输入参数的和
#!/bin/bash
function sum ()
{
let s=($1+$2)
echo $s
}
read -p "input the number1" n1;
read -p "input the number2" n2;
sum $n1 $n2;
exit