赞
踩
什么是shell呢?shell是用C语言编写的程序,它是用户使用 Linux 的桥梁。Shell既是一种命令语言,又是一种程序设计语言。简单来说Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。也可以这样认为,linux中的shell就是linux内核的一个外层保护工具,并负责完成用户与内核之间的交互
shell脚本就是一种专门使用shell编写的脚本程序,它虽然没有C++、Java、Python等一系列高级语言功能强大,但是在服务器运维领域以及嵌入式开发领域,shell脚本具有举足轻重的地位。
shell脚本编程如同其他编程语言的一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以运行了,而linux下的shell种类众多,常用的用:
在诸多linux发行版系统中,最常用的就是Bash,就是Bourne Again Shell,因为其能工提供环境变量以配置用户shell环境,支持历史记录、内置算数功能、支持通配符表达式等高效性能,将linux常用命令进行的简化,被广泛应用于Debian系列的linux发行版中。
运行shell脚本的方法有两种:
shell脚本编写如下,并将其保存为test.sh,进入存放此文件目录
- #!/bin/bash
- echo "Hello World"
当作为可执行程序运行时候
- chmod +x test.sh # 赋予可执行权限
- ./test.sh # 执行程序
当作为解释器参数运行时
- /bin/sh test.sh # 执行命令
- /bin/php test.php # 执行命令
单行注释:和python注释相同,以#号开头作为单行注释
- # 这是一个注释
- # author:ohuohuoo
- # date:`date`
多行注释:如果在开发过程中,,遇到大段的代码需要临时注释起来,过一会儿又取消注释,可以将其定义为一个花括号的注释函数,也可以用多行注释
- :<<EOF
- 注释内容...
- 注释内容...
- 注释内容...
- EOF
-
- # EOF可以换成其他符号
- :<<E!
- 注释内容...
- 注释内容...
- 注释内容...
- !
shell编程中,定义变量是直接定义的,没有明确的数据类型,shel允许用户建立变量存储数据,但是将认为赋给变量的值都解释为一串字符,如下
- cout=1 # 定义变量
- name="ohuohuo" # 定义变量
- echo $cout # 取变量值
- echo $name # 取变量值
shell中,英文符号"$"用于取变量值
注意点:shell编程的变量名的命名和其他语言一样,需要遵循一定的规则,规则如下
如下所示
有效的命令
- NAME
- LIBRARY_PATH
- _var
- var2
无效的命名
- ?var=123
- user*name=ohuohuo
如果在变量中使用系统命令,需要加上 " `"符号(ESC键下方),如下所示
- DATE1=`date`
- DATE2=$(date)
- 两者功能相同
使用变量的时,用英文符号"$"取变量值,对于较长的变量名,建议加上{ }花括号,帮助解释器识别变量的边界,如下
- name="test_name"
- echo "My name is ${name}and you"
加上花括号时,即时所有后面的语句不留空格,shell也会自动识别边界,默认添加一个空格
此外,已经定义过的变量,可以二次定义并重新被赋值覆盖上一次的变量值,这点如同其他语言
shell编程中也同样存在变量类型,在运行shell时会同时存在三种变量
shell中的变量,默认为可读可写类型,如果想要其只可读,如同url一样,需要将其声明为**只读类型变量(**如同const),使用readonly命令,如下脚本
- #!/bin/bash
- Url="http://www.baidu.com"
- readonly Url
- Url="http://www.csnd.net"
这样的话,这句就会报错,提示/bin/sh: NAME: This variable is read only.此变量为只读变量
如果想要删除变量,使用unset命令解除命令赋值,但是unset不能删除可读变量,如下所示
- #!/bin/sh
- name="ohuohuo"
- Url="http://www.baidu.com"
- readonly Url # 设置可读变量
- unset name # 可以被删除
- unset Url # 不可被删除
- echo $name # 不被打印出
- echo $Url # 打印出
在shell中字符串是shell编程中最常用最有用的数据类型,字符串可以用单引号,也可以用双引号,也可以不用引号。
使用单引号
str='this is a string'
使用单引号的不足:
使用双引号
- name="ohouhuoo"
- str="please input your \"$name"\"
- echo -e $str
输出结果如下图
使用双引号的优势:
由此可见,双引号较单引号而言有更强大的优势
获取字符串长度:在对变量进行取值时,使用" # "符号对字符串进行取值
- string="abcd"
- echo ${#string} # 输出 4
提取子字符串:使用字符串的截取命令,用于提取部分字符串
- string="this is a test"
- echo ${string:2:6} # 表示从第3个字符开始截取,截取长度为6个字符
上式输出结果为is is,如下图
查找字符串:用于查找字符的位置,输出结果为字符在字符串中所占的数据位置,如果查找多个字符,那哪个字母先出现就计算哪个,如下查找it中i和t两个字符,t先出现,输出为1
- string="this is a test"
- echo `expr index "$string" it` # 输出 1
在bash下,仅仅支持一维数组,并且没有限定数组的大小,不支持多维数组。类似于 C 语言,数组元素的下标由 0 开始编号(上述字符串也是这样)。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于 0。
在 Shell 中,用括号()来定义表示数组,数组中元素用"空格"符号分割开。定义数组的一般形式为:
- # 一般定义
- array_name=(value1 value2 value3 value4)
-
- # 多级定义
- array_test=(
- value1
- value2
- value3
- value4
- )
-
- #
- array_text[0]=value0
- array_text[1]=value1
- array_text[3]=value3
- ...
- ...
三种定义形式均可
读取数组:和读取变量名相同,使用$符号,需要加上下标名
- valuen=${array_name[n]}
- echo ${array_name[@]} # 读取所有
获取数组长度:获取数组长度的方法与获取字符串长度的方法相同,如所示
- # 取得数组元素的个数
- length=${#array_name[@]} # 从头到尾取
- # 或者
- length=${#array_name[*]} # 取所有
- # 取得数组单个元素的长度
- lengthn=${#array_name[n]} # 取特定
在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推……,脚本编写如下,保存为test.sh
- echo "传递参数实例!";
- echo "执行的文件名:$0";
- echo "第一个参数为:$1";
- echo "第二个参数为:$2";
- echo "第三个参数为:$3";
执行脚本如下
- chmod +x test.sh
- ./test.sh 1 2 3
输出结果如下图,传递参数的过程在赋予权限执行脚本的过程中就已经完成
在使用shell传递参数的时候,常常需要用到以下的几个字符来处理参数
举例如下
- echo "传递参数实例!";
- echo "第一个参数为:$1";
-
- echo "参数个数为:$#";
- echo "传递的参数作为一个字符串显示:$*";
结果如图
与其他编程语言相同的是,shell同样支持多种运算符:
shell想要使用这些运算符,需要结合其他命令和工具来使用(因为shell中不支持简单的数学运算),如使用算数运算符就需要搭配的常用的工具有两种
运算规则注意点:
如下实例
- #!/bin/bash
-
- val=`expr 3 + 2`
- echo "两数之和为 : $val"
执行脚本后,输出结果为
两数之和为 : 5
shell支持的常用的如下表,举例中这里假定变量 a 为 10,变量 b 为 20,
需要注意的点:
在windows系统中乘号(*)前边必须加反斜杠()才能实现乘法运算;
shell中的关系运算符和其他编程语言不同,shell中使用特殊的字符表示关系运算符,并且只支持数字,不支持字符串,除非字符串是数字,下表为常用关系运算符,同样指定a为10,b为20
- #!/bin/bash
-
- 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
将脚本执行结果如下
- 10 -eq 20: a 不等于 b
- 10 -ne 20: a 不等于 b
需要注意的点:
shell中的布尔运算符使用如下表,同样指定a为10,b为20
脚本编写如下
- #!/bin/bash
-
- a=10
- b=20
-
- if [ $a != $b ]
- then
- echo "$a != $b : a 不等于 b"
- else
- echo "$a == $b: a 等于 b"
- fi
执行脚本,结果如下
10 != 20 : a 不等于 b
shell中的逻辑运算符和其他编程语言有类似的地方,如下表。假定变量 a 为 10,变量 b 为 20
编写脚本如下
- #!/bin/bash
-
- a=10
- b=20
-
- if [[ $a -lt 100 && $b -gt 100 ]]
- then
- echo "返回 true"
- else
- echo "返回 false"
- fi
执行脚本,结果如下
返回 false
需要注意的点:
shell中常用的字符串运算符如下表。假定变量 a 为 “abc”,变量 b 为 “efg”
编写脚本如下
- #!/bin/bash
-
- a="abc"
- b="efg"
-
- if [ $a != $b ]
- then
- echo "$a != $b : a 等于 b"
- else
- echo "$a != $b: a 不等于 b"
- fi
执行脚本,结果输出如下
abc != efg : a 不等于 b
shell中的文件测试运算符用于检测在类unix系统中,文件的各种属性,如下表
编写脚本如下
- #!/bin/bash
-
- file="/var/www/test/test.sh"
- if [ -r $file ]
- then
- echo "文件可读"
- else
- echo "文件不可读"
- fi
执行脚本,结果输出如下
文件可读
echo命令在shell中用于字符串的输出,调用的格式:
echo string
echo命令还可显示复杂的输出格式
显示普通的字符串
echo "this is a test"
显示转义字符
echo "\this is a test\"
显示变量
- name="ohuohuo"
- echo "you name is $name"
显示换行
- echo -e "Right!\n " # -e 表示开启转义
- echo "this is other line"
显示结果定向重定向至文件
echo "this is a test" > testfile
显示command命令执行结果
echo `date`
echo命令还有其他使用规则,经常使用就可熟练掌握
shell中的printf命令如同C语言中一样,调用格式也大抵相同,只是有一点点不同。与echo命令打印字符串不同的是,printf不会自动调价换行符号,可以手动添加
printf命令的语法:
printf format-string [arguments...]
参数说明:
举例如下
- $ echo "Hello, Shell" # 输入
- Hello, Shell # 输出
- $ printf "Hello, Shell\n" # 输入
- Hello, Shell # 输出
printf命令可以较为强大的使用转义字符,shell中常用的转义字符如下表示所示
shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试
数值测试命令表
应用举例如下
- #!/bin/bash
- num1=100
- num2=100
- if test $[num1] -eq $[num2]
- then
- echo '两个数相等!'
- else
- echo '两个数不相等!'
- fi
输出结果
两个字符串不相等!
字符串测试表
脚本实例如下
- # !/bin/bas
- num1="name"
- num2="function"
- if test $num1 = $num2
- then
- echo '两个字符串相等!'
- else
- echo '两个字符串不相等!'
- fi
输出结果
两个字符串不相等!
文件测试表
-b 文件名 如果文件存在且为块特殊文件则为真
脚本编写如下
- # !/bin/bash
- if test -e ./bash
- then
- echo '文件已存在!'
- else
- echo '文件不存在!'
- fi
输出结果如下
文件已存在!
shell作为一种脚本语言,也有着自己的流程控制,而shell中的流程控制主要由条件、循环组成
shell中的if else条件具有一定的模版。其调用格式为:
if - then - fi:
调用格式如下
- if condition
- then
- command1
- command2
- ...
- commandN
- fi
-
- # 写成单行
- if condition;then command1; command2;fi
如果存在不满足的条件的情况
- if condition
- then
- command1
- command2
- ...
- commandN
- else
- command
- fi
在多层嵌套条件情况
- if condition1
- then
- command1
- elif condition2
- then
- command2
- else
- commandN
- fi
应用举例
- num1=$[6]
- num2=$[8]
- if test $[num1] -eq $[num2]
- then
- echo '两个数字相等!'
- else
- echo '两个数字不相等!'
- fi
执行脚本,结果输出如下
两个数字相等!
shell中case语句为多功能选择语句,与其他语言相通的是,可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。case语句调用格式如下:
- case 值 in
- 模式1)
- command1
- command2
- ...
- commandN
- ;;
- 模式2)
- command1
- command2
- ...
- commandN
- ;;
- esac
需要注意的点:
脚本举例如下
- echo '输入 1 到 4 之间的数字:'
- echo '你输入的数字为:'
- read num
- case $num in
- 1) echo '你选择了 1'
- ;;
- 2) echo '你选择了 2'
- ;;
- 3) echo '你选择了 3'
- ;;
- 4) echo '你选择了 4'
- ;;
- *) echo '你没有输入 1 到 4 之间的数字'
- ;;
- esac
执行脚本,运行如下
- 输入 1 到 5 之间的数字:4
- 你输入的数字为 4!
- 输入 1 到 5 之间的数字:8
- 你输入的数字不是 1 到 5 之间的! 游戏结束
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
执行输出如下
- 输入 1 到 5 之间的数字:3
- 你输入的数字为 3!
- 输入 1 到 5 之间的数字:7
- 你输入的数字不是 1 到 5 之间的! 游戏结束
应用举例,同样的将上式修改如下
- #!/bin/bash
- while :
- do
- echo -n "输入 1 到 5 之间的数字: "
- read num
- case $num in
- 1|2|3|4|5) echo "你输入的数字为 $num!"
- ;;
- *) echo "你输入的数字不是 1 到 5 之间的!"
- continue
- echo "游戏结束"
- ;;
- esac
- done
执行脚本,结果输出如下
shell中的for循环调用格式和python中的for循环有点类似,也是有模板的:
- for var in item1 item2 ... itemN
- do
- command1
- command2
- ...
- commandN
- done
-
- # 写成一行同样使用分号将语句分开
需要注意的是:
应用脚本编写如下
- for num in 1 2 3 4 5
- do
- echo "The value is: $num"
- done
输出结果如下
- The value is: 1
- The value is: 2
- The value is: 3
- The value is: 4
- The value is: 5
shell中的while循环用于不断执行一系列命令,也用于从输入文件中读取数据,调用格式如下
- while condition
- do
- command
- done
应用脚本编写如下:
- #!/bin/bash
- num=1
- while(( $num<=5 ))
- do
- echo $num
- let "num++"
- done
执行脚本,结果运行如下
- 1
- 2
- 3
- 4
- 5
只需要知道shell中while循环的格式,同样可以做到和C语言中一样, 使用while循环进行判定或者判断键盘循环,甚至无限循环等,如下使用while循环读取键盘操作
- echo '按下 <Q> 退出'
- echo -n '输入你最喜欢的歌名: '
- while read SONG
- do
- echo "啊!$SONG 真是一首好歌"
- done
执行脚本,运行结果如下
- 按下<Q>退出
- 输入你最喜欢的歌名: Takeway
- 啊!Takeway 真是一首好歌
until 循环执行一系列命令直至条件为 true 时停止。until 循环与 while 循环在处理方式上刚好相反。一般 while 循环优于 until 循环,但在某些时候—也只是极少数情况下,until 循环更加有用。until循环调用格式:
- until condition
- do
- command
- done
condition 一般为条件表达式,如果返回值为 false,则继续执行循环体内的语句,否则跳出循环,脚本编写如下
- #!/bin/bash
-
- a=0
- until [ ! $a -lt 5 ]
- do
- echo $a
- a=`expr $a + 1`
- done
执行脚本,结果输出如下
- 0
- 1
- 2
- 3
- 4
- 5
linux中的shell同样可以定义函数,然后在函数中调用执行相关的shell命令,完成功能,shell中的函数调用格式如下:
- [ function ] funname [()]
- {
- action;
- [return int;]
- }
参数说明:
脚本应用举例如下
- #!/bin/bash
-
- FunReturn(){
- echo "两个数字进行相加运算..."
- echo "输入第一个数字: "
- read num
- echo "输入第二个数字: "
- read anothernum
- echo "两个数字分别为 $num 和 $anothernum !"
- return $(($num+$anothernum)) # 分别返回数值
- }
- FunReturn # 调用函数
- echo "输入的两个数字之和为 $? !" # 使用通配符获取上一条指令的返回值
执行脚本,运行如下
- 两个数字进行相加运算...
- 输入第一个数字:
- 1
- 输入第二个数字:
- 2
- 两个数字分别为 1 和 2 !
- 输入的两个数字之和为 3 !
需要注意的是:
此外想要使用shell函数传递参数时,需要在函数体的内部,通过 $n 的形式来获取参数的值,与其他语言不同的是,这不是在定义函数的时候就给定参数,而是在函数体中获取到的参数,例如,$1表示第一个参数,$2表示第二个参数,参数调用列表如下
应用脚本举例:
- #!/bin/bash
- FunParam(){
- echo "输入第一个参数 $1 !"
- echo "输入第二个参数 $2 !"
- echo "输入第十个个参数 $10 !"
- echo "参数总数共 $# 个!"
- echo "作为一个字符串输出所有参数 $* !"
- }
- FunParam 1 2 3 4 5 6 7 8 9 10
执行脚本如下
- 第一个参数为 1 !
- 第二个参数为 2 !
- 第十个参数为 10 !
- 参数总数有 10 个!
- 作为一个字符串输出所有参数 1 2 3 4 5 6 7 8 9 10!
在之前的学习笔记中,归纳了linux中重定向的使用,这里不再赘述
linux中的重定向
shell编程相较于其他编程语言而言较为简单,只要多敲多练,很快就能入手,但是不可忽视shell编程在嵌入式开发和网络开发中的强大作用,至此作为总结归纳,如诺有错误,欢迎指正。
链接:https://blog.csdn.net/qq_41488943/article/details/105232770
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。