shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核。
shell还是一个功能强大的编程语言,易编写、易调试、灵活性强1.1:linux提供的解释器
/bin/sh /bin/bash /sbin/nologin /usr/bin/sh /usr/bin/bash /usr/sbin/nologin1.2:bash和sh的关系
可知sh是bash的一个软链
-rwxr-xr-x. 1 root root 964544 4月 11 2018 bash lrwxrwxrwx. 1 root root 10 11月 21 18:06 bashbug -> bashbug-64 -rwxr-xr-x. 1 root root 6964 4月 11 2018 bashbug-64 lrwxrwxrwx. 1 root root 4 11月 21 18:06 sh -> bash二:shell脚本初始
shell脚本后缀为.sh文件,脚本以#!/bin/bash开头,目的是为了指定解析器2.1:运行脚本的方式:
三:shell中的变量 3.1:系统变量第一种:采用bash或sh+脚本的相对路径或绝对路径(不用赋予脚本+x权限)
第二种:采用输入脚本的绝对路径或相对路径执行脚本(必须具有可执行权限+x)
$PATH、$HOME、$PWD、$SHELL、$USER3.2:自定义变量显示shell中所有变量:set
说明:在终端输入sh进入到shell交互式界面,当然也可以直接在黑屏终端下操作测试,使用exit回退到终端
定义变量:变量=值 撤销变量:unset 变量 声明静态变量:readonly 变量,静态变量不能unset3.2.1:变量的定义规则:
环境变量名建议大写 等号两侧不能有空格 在bash中,变量默认类型都是字符串类型,无法直接进行数值运算 变量的值如果有空格,需要使用双引号或单引号括起来单引号与双引号的区别:
单引号里面是什么就输出什么 以双引号包围变量的值时,输出时会先解析里面的变量和命令
注意 :将变量提升为全局变量:export,即在.sh 文件外定义的文件可以在文件内使用。3.2.2:特殊变量:
$n n为数字,$0代表该脚本名称,$1-$9代表第一到第九个参数,十以上的参数需要用大括号包含,如${10}
sh-4.2$ vim test2.sh sh-4.2$ chmod u+x test2.sh sh-4.2$ ./ sh: ./: 是一个目录 sh-4.2$ ./test2.sh 1 2 3 4 5 6 7 8 9 10 文件夹的名字是 :./test2.sh 第一个参数:1 第二个参数:2 第三个参数:3 第四个参数:4 第五个参数:5 第六个参数:6 第七个参数:7 第八个参数:8 第九个参数:9 第十个参数:10sh文件内部定义 sh文件外部进行传参
注意:如果想让$*和$@ 体现区别必须用双引号括起来,并使用循环变量才能看到效果$*与$@ : $* 功能描述:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体
$@ 功能描述:这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待
$? : 最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0,则证明上一个命令执行不正确了。
1 #!/bin/bash 2 3 echo '------------$*--------------' 4 for i in $* 5 do 6 # echo "(带引号)i的值为:$i" 7 echo "(不带引号)i的值为:" $i 8 done 9 10 11 echo '------------$@--------------' 12 for j in $@ 13 do 14 # echo "(带引号)j的值为:$j" 15 echo "(不带引号)j的值为:" $j 16 done
sh-4.2$ sh test12.sh 1 2 3 ------------$*-------------- (不带引号)i的值为: 1 (不带引号)i的值为: 2 (不带引号)i的值为: 3 ------------$@-------------- (不带引号)j的值为: 1 (不带引号)j的值为: 2 (不带引号)j的值为: 3 sh-4.2$ vim test12.sh
------------$*-------------- (不带引号)i的值为: 1 2 3 ------------$@-------------- (不带引号)j的值为: 1 (不带引号)j的值为: 2 (不带引号)j的值为: 3 1 #!/bin/bash 2 3 echo '------------$*--------------' 4 for i in "$*" 5 do 6 # echo "(带引号)i的值为:$i" 7 echo "(不带引号)i的值为:" $i 8 done 9 10 11 echo '------------$@--------------' 12 for j in "$@" 13 do 14 # echo "(带引号)j的值为:$j" 15 echo "(不带引号)j的值为:" $j 16 done四:shell中的运算符
基本语法:$((运算式))或$[运算式] 注意是双括号五:控制台输入sh-4.2$ $[(4+6)*10] sh: 100: 未找到命令 sh-4.2$ ret=$[(4+6)*10] sh-4.2$ echo ret ret sh-4.2$ echo $ret 100 sh-4.2$ $? sh: 0: 未找到命令 sh-4.2$ echo $? 127 sh-4.2$ ret=$[(4+6)*10] sh-4.2$ echo $?
基本语法:read (选项) (参数)选项值:
-p 指定读取值时的提示符
-t 指定读取值时等待的时间(秒)
1 #!/bin/bash 2 3 4 read -p "请输入第一个参数:" num1 5 6 echo "您输入的第一个参数是 $num1 " 7 8 9 read -t 3 -p "请在3秒内输入第二个参数:" num2 10 11 echo "您输入的第二个参数是 $num2"六:条件判断
[ condition ](注意condition前后要有空格) 注意:条件非空即为true [ 0 ] 返回值为true []返回值为false常用判断条件:
整数比较-lt:小于(less than)
-le:小于等于(less equal)
-eq:等于(equal)
-ne:不等于(not equal)
-gt:大于(greater than)
-ge:大于等于(greater equal)
按照文件权限判断-r:有读的权限(read)
-w:有写的权限(write)
-x:-x 有执行的权限(execute)
sh-4.2$ echo [ -r test3.sh ] [ -r test3.sh ] sh-4.2$ [ -r test3.sh ] sh-4.2$ echo $? 0 sh-4.2$ [ -x test3.sh ] sh-4.2$ echo $? 1 sh-4.2$ ls -l 总用量 16 -rwxrw-r--. 1 atguigu atguigu 33 11月 21 20:59 helloworld.sh -rwxrw-r--. 1 atguigu atguigu 64 11月 21 21:20 test01.sh -rwxrw-r--. 1 atguigu atguigu 331 11月 21 21:26 test2.sh -rw-rw-r--. 1 atguigu atguigu 210 11月 21 21:41 test3.sh
按照文件类型判断:
-f:文件存在并且是一个常规的文件(file)
-d:文件存在并是一个目录(directory)
-e:文件存在(existence)
sh-4.2$ [ -f test] test01.sh test2.sh test3.sh test4.sh/ sh-4.2$ [ -f test3.sh ] sh-4.2$ echo $? 0 sh-4.2$ [ -d test4.sh ] sh-4.2$ echo $?
与或非:七:选择判断语句 7.1:if语句:-a、-o、!:在中括号内使用
&&、||、!:在中括号外使用,计算多个中括号中的条件判断
sh-4.2$ [ -r test4.sh -a -w test4.sh -a -x test4.sh/ ] sh-4.2$ echo $? 0 sh-4.2$ ls -l 总用量 16 -rwxrw-r--. 1 atguigu atguigu 33 11月 21 20:59 helloworld.sh -rwxrw-r--. 1 atguigu atguigu 64 11月 21 21:20 test01.sh -rwxrw-r--. 1 atguigu atguigu 331 11月 21 21:26 test2.sh -rw-rw-r--. 1 atguigu atguigu 210 11月 21 21:41 test3.sh drwxrwxr-x. 2 atguigu atguigu 6 11月 21 21:48 test4.sh-rwxrw-r--. 1 atguigu atguigu 33 11月 21 20:59 helloworld.sh -rwxrw-r--. 1 atguigu atguigu 64 11月 21 21:20 test01.sh -rwxrw-r--. 1 atguigu atguigu 331 11月 21 21:26 test2.sh -rw-rw-r--. 1 atguigu atguigu 210 11月 21 21:41 test3.sh drwxrwxr-x. 2 atguigu atguigu 6 11月 21 21:48 test4.sh sh-4.2$ [ -r test4.sh/ ] && [ -w test4.sh/ ] && [ -x test4.sh/ ] sh: [: 参数太多 sh-4.2$ [ -r test4.sh ]&&[ -w test4.sh ]&&[ -x test4.sh/ ] sh: [: 参数太多 sh-4.2$ [ -r test4.sh/ ] && [ -w test4.sh/ ] sh-4.2$ echo $? 0 sh-4.2$ [ -r test4.sh/ ]&&[ -w test4.sh/ ] sh-4.2$ echo $?
if [ 条件判断式 ]
then
语句
fi
1 #!/bin/bash 2 3 read -t 3 -p "请在三秒内输入输入一个数 :" num 4 5 echo "您输入的数为 $num " 6 7 if [ $num -gt 10 ] 8 then 9 echo "恭喜您输入正确" 10 fi7.2:if-else语句:
7.3:if-elif-else语句if [ 条件判断式 ]
then
语句1
else
语句2
fi
if [ 条件判断式1 ];then
语句1
elif [ 条件判断式2 ];then
语句2
elif [ 条件判断式3 ];then
语句3
……
else
语句e
fi
1 #!/bin/bash 2 3 read -t 3 -p "请在三秒输入一个数字" num 4 5 echo "您输入的数字为 $num" 6 7 if [ $num -gt 10 ]; 8 then 9 echo "您输入的值大了" 10 elif [ $num -lt 10 ] 11 then 12 echo "您输入的值小了" 13 else 14 echo "恭喜您猜对了" 15 fi7.4:case语句:
语法:
case $变量名 in
"值1")
语句1
;;
"值2")
语句2
;;
……
*)
语句*
;;
esac
1 #!/bin/bash 2 3 read -t 3 -p "请在三秒内选在一个数字[1-7]" num 4 5 case $num in 6 "1") 7 echo "星期一" 8 ;; 9 "2") 10 echo "星期二" 11 ;; 12 "3") 13 echo "星期三" 14 ;; 15 "4") 16 echo "星期四" 17 ;; 18 "5") 19 echo "星期五" 20 ;; 21 "6") 22 echo "星期六" 23 ;; 24 "7") 25 echo "星期日" 26 ;; 27 esac八:循环语句 8.1:while循环
while [ 条件判断式 ]
do
语句
done
1 #!/bin/bash 2 3 num=1 4 result=0 5 while [ $num -le 100 ] 6 do 7 result=$[$num+$result] 8 num=$[$num+1] 9 done 10 echo "1-100内数的和为:$result"
1 #!/bin/bash 2 3 4 num=1 5 sum=0 6 while [ $num -le 100 ] 7 do 8 sum=$(($num+$sum)) 9 num=$[$num+1] 10 done 11 echo "1-100的和为 $sum"8.2:for循环
1 #!/bin/bash 2 3 num=1 4 sum=0 5 for ((i=1;i<=100;i++)) 6 do 7 sum=$[$num+$sum] 8 num=$(($num+1)) 9 done 10 echo "1-100数的和为:"$sum
注意:在for循环中表达式不需要使用-gt -ne等等 可以使用 = > >= 等。8.3:for-in语句
for 变量 in 计算值1 计算值2 计算值3 ……
do
语句
done
1 #!/bin/bash 2 3 4 #按顺序遍历in后面的所有“计算值” 5 a=1 6 b=2 7 for i in '中' '华' 'ren' 'min' '共' 'he' 'guo' 'Chinese' 8 do 9 echo 'i的值为' $i 10 done九:break与continue
与java一样
1 #!/bin/bash 2 3 echo "----------------break-------------------" 4 for ((i=1;i<=10;i++)) 5 do 6 if [ $i -eq 5 ] 7 then 8 break 9 fi 10 echo "i的值为:$i" 11 done 12 13 echo "----------------continue-------------------" 14 15 for ((i=1;i<=10;i++)) 16 do 17 if [ $i -eq 5 ] 18 then 19 continue 20 fi 21 echo "i的值为:$i" 22 done 23十 :系统函数 10.1:basename
基本语法:basename [string/pathname] [suffix]
basename命令会删掉所有的前缀包括最后一个(‘/’)字符,然后将字符串显示出来
选项suffix:如果suffix被指定了,basename会将pathname或string中的suffix去掉
sh-4.2$ basename /a/b/c/d/e.txt e.txt sh-4.2$ basename /a/b/c/d/e.txt .txt e sh-4.2$ basename /a/b/c/d/e.txt txt10.2: dirname
注意:basename和dirname在使用的时候,路径存不存在无所谓。 十一:自定义函数基本语法:dirname 文件绝对路径
功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)
sh-4.2$ dirname /a/b/c/d/e.txt /a/b/c/d sh-4.2$
[function] funname [()]
{
action;[return int;]
}
11.2:自定义函数调用
function 说明定义函数,可以省略 funname 自定义函数名,遵循标识符规则 () 可以省略,和function不能同时省略 action 封装的功能 return int 函数返回值,只能通过$?系统变量来获取,可以显示添加。如果不添加,将以最后一条命令运行的结果作为返回值。注意return后的数值在[0~255]之间,如果超过255,将返回该值与256的余数。 ; 语句结束标志,可以不写
funname [……]
echo "函数的返回值为:$?"
11.2.1:无参无返回值
funname 要调用的函数名 …… 传递参数,如果无需传参即省略 $? 获取函数的返回值 "" 需要使用双引号,可以使用特殊变量
1 #!/bin/bash
2
3 # 定义函数
4
5 function func()
6 {
7 echo "让我们荡起双桨"
8
9 }
10 echo "-----函数开始执行------"
11
12 # 调用函数
13 func
14 # 获取函数的返回值的值
15 echo "返回值为:$?"
16 echo "-----函数执行完毕------"
11.2.1:使用参数
1 #!/bin/bash
2 function func()
3 {
4 # 使用传递过来的参数值
5 result=$[$1+$2]
6 echo "$1+$2的结果是$result"
7
8 }
9
10 echo "-----函数开始执行------"
11 # 调用函数,传递参数
12 func 3 5
13 echo "返回值为:$?"
14 echo "-----函数执行完毕------"
11.2.2:返回值
说明:return后的数值在[0~255]之间,如果超过255,将返回该值与256的余数
1 #!/bin/bash
2
3 function func()
4 {
5 ret=$[$1+$2]
6 return $ret
7
8 }
9
10 echo "-----函数开始执行------"
11 func 3 5
12 echo "返回值为:$?"
13
14
15 echo "-----函数执行完毕------"



