Shell语法详解

发布时间:2025-12-09 16:21:35 浏览次数:4

一:shell概述

 

shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核。

shell还是一个功能强大的编程语言,易编写、易调试、灵活性强

1.1:linux提供的解释器

/bin/sh/bin/bash/sbin/nologin/usr/bin/sh/usr/bin/bash/usr/sbin/nologin

1.2:bash和sh的关系

可知sh是bash的一个软链

-rwxr-xr-x. 1 root root 964544 4月 11 2018 bashlrwxrwxrwx. 1 root root 10 11月 21 18:06 bashbug -> bashbug-64-rwxr-xr-x. 1 root root 6964 4月 11 2018 bashbug-64lrwxrwxrwx. 1 root root 4 11月 21 18:06 sh -> bash

二:shell脚本初始

shell脚本后缀为.sh文件,脚本以#!/bin/bash开头,目的是为了指定解析器

2.1:运行脚本的方式:

第一种:采用bash或sh+脚本的相对路径或绝对路径(不用赋予脚本+x权限)

第二种:采用输入脚本的绝对路径或相对路径执行脚本(必须具有可执行权限+x)

 三:shell中的变量

3.1:系统变量

$PATH、$HOME、$PWD、$SHELL、$USER

显示shell中所有变量:set

说明:在终端输入sh进入到shell交互式界面,当然也可以直接在黑屏终端下操作测试,使用exit回退到终端

3.2:自定义变量

定义变量:变量=值

撤销变量:unset 变量

声明静态变量:readonly 变量,静态变量不能unset

3.2.1:变量的定义规则:

环境变量名建议大写

等号两侧不能有空格

在bash中,变量默认类型都是字符串类型,无法直接进行数值运算

变量的值如果有空格,需要使用双引号或单引号括起来

单引号与双引号的区别:

单引号里面是什么就输出什么

以双引号包围变量的值时,输出时会先解析里面的变量和命令

注意 :将变量提升为全局变量:export,即在.sh 文件外定义的文件可以在文件内使用。

3.2.2:特殊变量:

$n  n为数字,$0代表该脚本名称,$1-$9代表第一到第九个参数,十以上的参数需要用大括号包含,如${10}

sh-4.2$ vim test2.shsh-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第十个参数:10

sh文件内部定义   sh文件外部进行传参

$*与$@ : $* 功能描述:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体

               $@ 功能描述:这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待

注意:如果想让$*和$@ 体现区别必须用双引号括起来,并使用循环变量才能看到效果

$? : 最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0,则证明上一个命令执行不正确了。

1 #!/bin/bash2 3 echo '------------$*--------------'4 for i in $*5 do6 # echo "(带引号)i的值为:$i" 7 echo "(不带引号)i的值为:" $i8 done9 10 11 echo '------------$@--------------'12 for j in $@13 do14 # echo "(带引号)j的值为:$j" 15 echo "(不带引号)j的值为:" $j16 done sh-4.2$ sh test12.sh 1 2 3------------$*--------------(不带引号)i的值为: 1(不带引号)i的值为: 2(不带引号)i的值为: 3------------$@--------------(不带引号)j的值为: 1(不带引号)j的值为: 2(不带引号)j的值为: 3sh-4.2$ vim test12.sh ------------$*--------------(不带引号)i的值为: 1 2 3------------$@--------------(不带引号)j的值为: 1(不带引号)j的值为: 2(不带引号)j的值为: 31 #!/bin/bash2 3 echo '------------$*--------------'4 for i in "$*"5 do6 # echo "(带引号)i的值为:$i" 7 echo "(不带引号)i的值为:" $i8 done9 10 11 echo '------------$@--------------'12 for j in "$@"13 do14 # echo "(带引号)j的值为:$j" 15 echo "(不带引号)j的值为:" $j16 done

四:shell中的运算符

基本语法:$((运算式))或$[运算式]  注意是双括号

sh-4.2$ $[(4+6)*10]sh: 100: 未找到命令sh-4.2$ ret=$[(4+6)*10]sh-4.2$ echo retretsh-4.2$ echo $ret100sh-4.2$ $?sh: 0: 未找到命令sh-4.2$ echo $?127sh-4.2$ ret=$[(4+6)*10]sh-4.2$ echo $?

 五:控制台输入

基本语法:read (选项) (参数)

选项值:

        -p       指定读取值时的提示符

        -t       指定读取值时等待的时间(秒)

1 #!/bin/bash2 3 4 read -p "请输入第一个参数:" num15 6 echo "您输入的第一个参数是 $num1 "7 8 9 read -t 3 -p "请在3秒内输入第二个参数:" num210 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 $?0sh-4.2$ [ -x test3.sh ]sh-4.2$ echo $?1sh-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 $?0sh-4.2$ [ -d test4.sh ]sh-4.2$ echo $?

与或非:

-a、-o、!:在中括号内使用

&&、||、!:在中括号外使用,计算多个中括号中的条件判断

sh-4.2$ [ -r test4.sh -a -w test4.sh -a -x test4.sh/ ]sh-4.2$ echo $?0sh-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.shdrwxrwxr-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.shdrwxrwxr-x. 2 atguigu atguigu 6 11月 21 21:48 test4.shsh-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 $?0sh-4.2$ [ -r test4.sh/ ]&&[ -w test4.sh/ ]sh-4.2$ echo $?

七:选择判断语句

7.1:if语句:

if [ 条件判断式 ]
then
    语句
fi

1 #!/bin/bash2 3 read -t 3 -p "请在三秒内输入输入一个数 :" num4 5 echo "您输入的数为 $num "6 7 if [ $num -gt 10 ]8 then9 echo "恭喜您输入正确"10 fi

7.2:if-else语句:

if [ 条件判断式 ]
then
    语句1
else
    语句2
fi

7.3:if-elif-else语句

if [ 条件判断式1 ];then
    语句1
elif [ 条件判断式2 ];then
    语句2
elif [ 条件判断式3 ];then
    语句3
……
else
    语句e
fi

1 #!/bin/bash2 3 read -t 3 -p "请在三秒输入一个数字" num4 5 echo "您输入的数字为 $num"6 7 if [ $num -gt 10 ];8 then9 echo "您输入的值大了"10 elif [ $num -lt 10 ]11 then12 echo "您输入的值小了"13 else14 echo "恭喜您猜对了"15 fi

7.4:case语句:

语法:

 case $变量名 in
"值1")
    语句1
    ;;
"值2")
    语句2
    ;;
……
*)
    语句*
    ;;
esac

1 #!/bin/bash2 3 read -t 3 -p "请在三秒内选在一个数字[1-7]" num4 5 case $num in6 "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/bash2 3 num=14 result=05 while [ $num -le 100 ]6 do7 result=$[$num+$result]8 num=$[$num+1]9 done10 echo "1-100内数的和为:$result" 1 #!/bin/bash2 3 4 num=15 sum=06 while [ $num -le 100 ]7 do8 sum=$(($num+$sum))9 num=$[$num+1]10 done11 echo "1-100的和为 $sum"

8.2:for循环

1 #!/bin/bash2 3 num=14 sum=05 for ((i=1;i<=100;i++))6 do7 sum=$[$num+$sum]8 num=$(($num+1))9 done10 echo "1-100数的和为:"$sum

 注意:在for循环中表达式不需要使用-gt  -ne等等 可以使用  = >  >= 等。

8.3:for-in语句

for 变量 in 计算值1 计算值2 计算值3 ……
do
    语句
done

1 #!/bin/bash2 3 4 #按顺序遍历in后面的所有“计算值”5 a=16 b=27 for i in '中' '华' 'ren' 'min' '共' 'he' 'guo' 'Chinese'8 do9 echo 'i的值为' $i10 done

九:break与continue

与java一样

1 #!/bin/bash2 3 echo "----------------break-------------------"4 for ((i=1;i<=10;i++))5 do6 if [ $i -eq 5 ]7 then8 break9 fi10 echo "i的值为:$i"11 done12 13 echo "----------------continue-------------------"14 15 for ((i=1;i<=10;i++))16 do17 if [ $i -eq 5 ]18 then19 continue20 fi21 echo "i的值为:$i" 22 done23

十 :系统函数

10.1:basename

基本语法:basename [string/pathname] [suffix]

basename命令会删掉所有的前缀包括最后一个(‘/’)字符,然后将字符串显示出来

选项suffix:如果suffix被指定了,basename会将pathname或string中的suffix去掉

sh-4.2$ basename /a/b/c/d/e.txte.txtsh-4.2$ basename /a/b/c/d/e.txt .txtesh-4.2$ basename /a/b/c/d/e.txt txt

10.2: dirname

基本语法:dirname 文件绝对路径

功能描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分)

sh-4.2$ dirname /a/b/c/d/e.txt/a/b/c/dsh-4.2$

注意:basename和dirname在使用的时候,路径存不存在无所谓。

十一:自定义函数

[function] funname [()]
{
    action;

    [return int;]
}

function说明定义函数,可以省略
funname自定义函数名,遵循标识符规则
()可以省略,和function不能同时省略
action封装的功能
return int函数返回值,只能通过$?系统变量来获取,可以显示添加。如果不添加,将以最后一条命令运行的结果作为返回值。注意return后的数值在[0~255]之间,如果超过255,将返回该值与256的余数。
;语句结束标志,可以不写

 11.2:自定义函数调用

funname [……]
echo "函数的返回值为:$?"

funname要调用的函数名
……传递参数,如果无需传参即省略
$?获取函数的返回值
""需要使用双引号,可以使用特殊变量

 11.2.1:无参无返回值

1 #!/bin/bash2 3 # 定义函数4 5 function func()6 {7 echo "让我们荡起双桨"8 9 }10 echo "-----函数开始执行------"11 12 # 调用函数13 func14 # 获取函数的返回值的值15 echo "返回值为:$?"16 echo "-----函数执行完毕------"

11.2.1:使用参数

1 #!/bin/bash2 function func()3 {4 # 使用传递过来的参数值5 result=$[$1+$2]6 echo "$1+$2的结果是$result"7 8 }9 10 echo "-----函数开始执行------"11 # 调用函数,传递参数12 func 3 513 echo "返回值为:$?"14 echo "-----函数执行完毕------"

11.2.2:返回值

说明:return后的数值在[0~255]之间,如果超过255,将返回该值与256的余数

1 #!/bin/bash2 3 function func()4 {5 ret=$[$1+$2]6 return $ret7 8 }9 10 echo "-----函数开始执行------"11 func 3 512 echo "返回值为:$?"13 14 15 echo "-----函数执行完毕------"
需要做网站?需要网络推广?欢迎咨询客户经理 13272073477