Shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核
Shell还是一个功能相当强大的编程语言,易编写、易调试、灵活性强
[guozihan@hadoop100 ~]$ cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
/bin/tcsh
/bin/csh
-rwxr-xr-x. 1 root root 964536 11月 25 2021 bash
lrwxrwxrwx. 1 root root 10 8月 25 20:20 bashbug -> bashbug-64
-rwxr-xr-x. 1 root root 6964 11月 25 2021 bashbug-64
lrwxrwxrwx. 1 root root 4 8月 25 20:20 sh -> bash
[guozihan@hadoop100 bin]$ echo $SHELL
/bin/bash
脚本以==#!/bin/bash== 开头(指定解析器)
需求:创建一个 Shell 脚本,输出 helloworld
实例实操
首先我们先创建文件夹program,然后在文件夹里创建sh文件,vim编辑
[guozihan@hadoop100 桌面]$ mkdir program
[guozihan@hadoop100 桌面]$ cd program/
[guozihan@hadoop100 program]$ touch helloword.sh
[guozihan@hadoop100 program]$ vim helloword.sh
#!/bin/bash
echo "helloworld"
采用 bash 或 sh+脚本的相对路径或绝对路径(不用赋予脚本+x 权限)
sh+脚本的相对路径
[guozihan@hadoop100 program]$ sh ./helloworld.sh
helloworldsh+脚本的绝对路径
[guozihan@hadoop100 program]$ sh /home/guozihan/桌面/program/helloworld.sh
helloworldbash+脚本的相对路径
[guozihan@hadoop100 program]$ bash ./helloworld.sh
helloworldbash+脚本的相对路径
[guozihan@hadoop100 program]$ bash /home/guozihan/桌面/program/helloworld.sh
helloworld
采用输入脚本的绝对路径或相对路径执行脚本(必须具有可执行权限+x)
①首先要赋予 helloworld.sh 脚本的+x 权限
[guozihan@hadoop100 program]$ chmod +x helloworld.sh
②执行脚本
[guozihan@hadoop100 program]$ ./helloworld.sh
helloworld[guozihan@hadoop100 program]$ /home/guozihan/桌面/program/helloworld.sh
helloworld
注意:第一种执行方法,本质是 bash 解析器帮你执行脚本,所以脚本本身不需要执行 权限。第二种执行方法,本质是脚本需要自己
执行,所以需要执行权限。
在脚本的路径前加上“.”或者 source
①现有文件test.sh,内容如下
#!/bin/bash
A=5
echo $A
②分别使用 sh,bash,./ 和 . 的方式来执行,结果如下
[guozihan@hadoop100 program]$ bash test.sh
5[guozihan@hadoop100 program]$ sh test.sh
5[guozihan@hadoop100 program]$ chmod +x test.sh
[guozihan@hadoop100 program]$ ./test.sh
5[guozihan@hadoop100 program]$ . test.sh
5
原因:
前两种方式都是在当前 shell 中打开一个子 shell 来执行脚本内容,当脚本内容结束,则 子 shell 关闭,回到父 shell 中。
第三种,也就是使用在脚本路径前加“.”或者 source 的方式,可以使脚本内容在当前 shell 里执行,而无需打开子 shell!这也是为什么我们每次要修改完/etc/profile 文件以后,需要 source 一下的原因。
开子 shell 与不开子 shell 的区别就在于,环境变量的继承关系,如在子 shell 中设置的当前变量,父 shell 是不可见
常用系统变量
$HOME、$PWD、$SHELL、$USER 等
案例实操
查看系统变量的值
[guozihan@hadoop100 ~]$ echo $HOME
/home/guozihan显示当前 Shell 中所有变量:set
[guozihan@hadoop100 ~]$ set
基本语法
(1)定义变量:变量名=变量值,注意,=号前后不能有空格
(2)撤销变量:unset 变量名
(3)声明静态变量:readonly 变量,注意:不能 unset
变量定义规则
(1)变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写。
(2)等号两侧不能有空格
(3)在 bash 中,变量默认类型都是字符串类型,无法直接进行数值运算。
(4)变量的值如果有空格,需要使用双引号或单引号括起来。
案例实操
定义变量 A
[guozihan@hadoop100 ~]$ A=5
[guozihan@hadoop100 ~]$ echo $A
5给变量 A 重新赋值
[guozihan@hadoop100 ~]$ A=8
[guozihan@hadoop100 ~]$ echo $A
8撤销变量 A
[guozihan@hadoop100 ~]$ unset A
[guozihan@hadoop100 ~]$ echo $A
声明静态的变量 B=2,不能 unset
[guozihan@hadoop100 ~]$ readonly B=2
[guozihan@hadoop100 ~]$ echo $B
2[guozihan@hadoop100 ~]$ B=9
-bash: B: 只读变量在 bash 中,变量默认类型都是字符串类型,无法直接进行数值运算
[guozihan@hadoop100 ~]$ C=1+2
[guozihan@hadoop100 ~]$ echo $C
1+2变量的值如果有空格,需要使用双引号或单引号括起来
[guozihan@hadoop100 ~]$ D=I love sunchen
bash: love: 未找到命令…[guozihan@hadoop100 ~]$ D=“I love sunchen”
[guozihan@hadoop100 ~]$ echo $D
I love sunchen可把变量提升为全局环境变量,可供其他 Shell 程序使用
export 变量
在 helloworld.sh 文件中增加 echo $B
#!/bin/bash
echo "helloworld"
echo $B
[guozihan@hadoop100 program]$ ./helloworld.sh
helloworld[guozihan@hadoop100 program]$ export B
[guozihan@hadoop100 program]$ ./helloworld.sh
helloworld
2
基本语法
$n 功能描述:n 为数字,$0 代表该脚本名称,$1-$9 代表第一到第九个参数,十以上的参数需要用大括号包含,如${10})
案例实操
[guozihan@hadoop100 program]$ touch parameter.sh
[guozihan@hadoop100 program]$ vim parameter.sh
#!/bin/bash
echo '=$n='
echo $0
echo $1
echo $
[guozihan@hadoop100 program]$ chmod 777 parameter.sh
[guozihan@hadoop100 program]$ ./parameter.sh cls xz
=$n=
./parameter.sh
cls
xz
基本语法
$# 功能描述:获取所有输入参数个数,常用于循环,判断参数的个数是否正确以及加强脚本的健壮性
实例实操
[guozihan@hadoop100 program]$ vim parameter.sh
#!/bin/bash
echo '==========$n=========='
echo $0
echo $1
echo $2
echo '==========$#=========='
echo $
[guozihan@hadoop100 program]$ chmod 777 parameter.sh
[guozihan@hadoop100 program]$ ./parameter.sh cls xz
=$n=
./parameter.sh
cls
xz
=$n=
2
基本语法
$* 功能描述:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体
$@ 功能描述:这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待
案例实操
[guozihan@hadoop100 program]$ vim parameter.sh
#!/bin/bash
echo '==========$n=========='
echo $0
echo $1
echo $2
echo '==========$#=========='
echo $#
echo '==========$*=========='
echo $*
echo '==========$@=========='
echo $@
[guozihan@hadoop100 program]$ ./parameter.sh a b c d e f g
=$n=
./parameter.sh
a
b
=$n=
7
=$n=
a b c d e f g
=$n=
a b c d e f g
基本语法
$? 功能描述:最后一次执行的命令的返回状态。如果这个变量的值为 0,证明上一 个命令正确执行;如果这个变量的值为非 0(具体是哪个数,由命令自己来决定),则证明 上一个命令执行不正确了
案例实操
判断 helloworld.sh 脚本是否正确执行
[guozihan@hadoop100 program]$ ./helloworld.sh
helloworld[guozihan@hadoop100 program]$ echo $?
0
基本语法
“$((运算式))” 或 “$[运算式]”
案例实操
计算(2+3)* 4 的值
[guozihan@hadoop100 program]$ S=$[(2+3)*4]
[guozihan@hadoop100 program]$ echo $S
20
基本语法
(1)test condition
(2)[ condition ](注意 condition 前后要有空格)
注意:条件非空即为 true,[ guozihan ]返回 true,[ ] 返回 false。
常用判断条件
两个整数之间比较
-eq 等于(equal)
-ne 不等于(not equal)
-lt 小于(less than)
-le 小于等于(less equal)
-gt 大于(greater than)
-ge 大于等于(greater equal)
注:如果是字符串之间的比较 ,用等号“=”判断相等;用“!=”判断不等。
按照文件权限进行判断
-r 有读的权限(read)
-w 有写的权限(write)
-x 有执行的权限(execute)
按照文件类型进行判断
-e 文件存在(existence)
-f 文件存在并且是一个常规的文件(file)
-d 文件存在并且是一个目录(directory)
案例实操
23 是否大于等于 22
[guozihan@hadoop100 program]$ [ 23 -ge 22 ]
[guozihan@hadoop100 program]$ echo $?
0helloworld.sh 是否具有写权限
[guozihan@hadoop100 program]$ [ -w helloworld.sh ]
[guozihan@hadoop100 program]$ echo $?
0
/home/atguigu/cls.txt 目录中的文件是否存在
[guozihan@hadoop100 program]$ [ -e /home/guozihan/cls.txt ]
[guozihan@hadoop100 program]$ echo $?
1多条件判断(&& 表示前一条命令执行成功时,才执行后一条命令,|| 表示上一 条命令执行失败后,才执行下一条命令)
[guozihan@hadoop100 program]$ [ guozihan ] && echo OK || echo notOK
OK[guozihan@hadoop100 program]$ [ ] && echo OK || echo notOK
notOK
基本语法
单分支
if [ 条件判断式 ];then
程序
fi
或者
if [ 条件判断式 ]
then
程序
fi
多分支
if [ 条件判断式 ]
then
程序
elif [ 条件判断式 ]
then
程序
else
程序
fi
注意事项:
①[ 条件判断式 ],中括号和条件判断式之间必须有空格
②if 后要有空格
案例实操
输入一个数字,如果是 1,则输出 banzhang zhen shuai,如果是 2,则输出 cls zhen mei, 如果是其它,什么也不输出。
[guozihan@hadoop100 program]$ touch if.sh
[guozihan@hadoop100 program]$ vim if.sh
#!/bin/bash
if [ $1 -eq 1 ]
then
echo "banzhang zhen shuai"
elif [ $1 -eq 2 ]
then
echo "cls zhen mei"
fi
[guozihan@hadoop100 program]$ chmod 777 if.sh
[guozihan@hadoop100 program]$ ./if.sh 1
banzhang zhen shuai
[guozihan@hadoop100 program]$ ./if.sh 2
cls zhen mei
基本语法
case $变量名 in
“值 1”)
如果变量的值等于值 1,则执行程序 1
;;
“值 2”)
如果变量的值等于值 2,则执行程序 2
;;
…省略其他分支…
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
注意事项:
(1)case 行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束。
(2)双分号“;;”表示命令序列结束,相当于 java 中的 break。
(3)最后的“*)”表示默认模式,相当于 java
案例实操
输入一个数字,如果是 1,则输出 banzhang,如果是 2,则输出 cls,如果是其它,输出 renyao。
[guozihan@hadoop100 program]$ touch case.sh
[guozihan@hadoop100 program]$ vim case.sh
#!/bin/bash
case $1 in
"1")
echo "banzhang"
;;
"2")
echo "cls"
;;
*)
echo "renyao"
;;
esac
[guozihan@hadoop100 program]$ chmod 777 case.sh
[guozihan@hadoop100 program]$ ./case.sh
renyao
[guozihan@hadoop100 program]$ ./case.sh 1
banzhang
基本语法1
for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
案例实操1
从 1 加到 100
[guozihan@hadoop100 program]$ touch for1.sh
[guozihan@hadoop100 program]$ vim for1.sh
#!/bin/bash
sum=0
for((i=0;i<=100;i++))
do
sum=$[$sum+$i]
done
echo $sum
[guozihan@hadoop100 program]$ chmod 777 for1.sh
[guozihan@hadoop100 program]$ ./for1.sh
5050
基本语法2
for 变量 in 值 1 值 2 值 3…
do
程序
done
案例实操2
打印所有输入参数
[guozihan@hadoop100 program]$ touch for2.sh
[guozihan@hadoop100 program]$ vim for2.sh
#!/bin/bash
#打印数字
for i in cls mly wls
do
echo "ban zhang love $i"
done
[guozihan@hadoop100 program]$ chmod 777 for2.sh
[guozihan@hadoop100 program]$ ./for2.sh
ban zhang love cls
ban zhang love mly
ban zhang love wls
$*和$@的区别
$*和$@都表示传递给函数或脚本的所有参数,不被双引号“”包含时,都以$1 $2 …$n 的形式输出所有参数。
当它们被双引号“”包含时,$*会将所有的参数作为一个整体,以“$1 $2 …$n”的形式输 出所有参数;$@会将各个参数分开,以“$1” “$2”…“$n”的形式输出所有参数。
基本语法
while [ 条件判断式 ]
do
程序
done
案例实操
从 1 加到 100
[guozihan@hadoop100 program]$ touch while.sh
[guozihan@hadoop100 program]$ vim while.sh
#!/bin/bash
sum=0
i=1
while [ $i -le 100 ]
do
sum=$[$sum+$i]
i=$[$i+1]
done
echo $sum
[guozihan@hadoop100 program]$ chmod 777 while.sh
[guozihan@hadoop100 program]$ ./while.sh
5050
基本语法
read (选项) (参数)
①选项:
-p:指定读取值时的提示符;
-t:指定读取值时等待的时间(秒)如果-t 不加表示一直等待
②参数
变量:指定读取值的变量名
案例实操
提示 7 秒内,读取控制台输入的名称
[guozihan@hadoop100 program]$ touch read.sh
[guozihan@hadoop100 program]$ vim read.sh
#!/bin/bash
read -t 7 -p "Enter your name in 7 seconds :" NN
echo $NN
[guozihan@hadoop100 program]$ chmod 777 read.sh
[guozihan@hadoop100 program]$ ./read.sh
Enter your name in 7 senconds:guozihan
guozihan