一 什么是shell?
1 概念解释
内核外面有一层,叫做shell,shell会解释你在Linux下面敲的命令,然后再与内核打交道。shell有不同的形式,有不同的shell,
c shell -------c 语言形式的shell,不同的shell执行的命令是不一样的,同样的命令在不同的shell底下不能通用,常用的命令,可以通用。
咱们用的shell叫做 bash,以前叫做bsh,名字的由来,是由一个叫做bone的人,写的,所以叫做bsh,后来他又写了一遍,bone again shell ,所以叫做 bash。
shell
是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。
2 什么叫脚本
脚本”其实就是一段代码,一个程序。
shell脚本 是应用于某个应用程序的一段通俗易懂的解释型代码,运行脚本能实现对应用程序的一些操作
编写脚本的语言被称之为脚本语言,是解释型语言。
常见的脚本语言有:
JavaScript(JS,前端),VBScript, ASP,JSP,PHP(后端),SQL(数据库操作语言),Perl,Shell,python,Ruby,JavaFX,Lua等。
3 为啥学习shell脚本?
- Shell属于内置的脚本
- 程序开发的效率非常高,依赖于功能强大的命令可以迅速地完成开发任务(批处理)
- 语法简单,代码写起来比较轻松,简单易学
二 shell入门基础
1 文件命名规范
xxx.sh .sh是linux下bash shell 的默认后缀
2 代码规范
#!/bin/bash
Shell相关指令
3 注释
“# ”开头的就是注释,被编译器忽略
单行注释: #
多行注释: :<<EOF … EOF 或者 :<<! … !
(:<< 标识多行注释开始,并指定一个标识符作为开始结束的标志)
使用流程:
①创建.sh文件 touch/vim
②编写shell代码
③执行shell脚本 脚本必须得有执行权限
案例1:创建test.sh,实现第一个shell脚本程序,输出hello world.
输出命令:# echo “hello world”
- 注意:输出的内容如果包含字母和符号(不包含变量),则需要用引号包括起来。如果是纯数字可以包也可以不包。
脚本内容为
#!/bin/bash
echo 'hello world'
- 注意:这里在运行时一定要写成 ./test.sh,而不是 test.sh,运行其它二进制的程序也一样。
- 如果直接写 test.sh,Linux 系统会去 PATH(环境变量) 里寻找有没有叫 test.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,你的当前目录通常不在 PATH 里,所以写成 test.sh 是会找不到命令的,要用 ./test.sh 告诉系统说,就在当前目录找。
三 shell进阶
3.1变量
3.1.1 变量类型
运行shell时,会同时存在三种变量:
- 局部变量:局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
- 环境变量:所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
- shell变量:shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行
3.1.2 变量的定义和使用
变量,先定义后使用。
定义形如:
class_name="yunwe"
(把yunwe赋值给class_name)
使用形如:
echo $class_name
- 变量就是由2部分组成,一个是变量名(左边),另外一部分是变量的值(右边)
- 变量名和变量值是什么关系?
变量名和变量值是使用和被使用关系; 我们的变量名来使用变量值;
在使用变量的时候一定需要在变量名前面添加一个$符号,该要求在其他语言中也存在的(例如php)。
变量名的规范
1 变量名后面的等号左右不能有空格
,这可能和你熟悉的所有编程语言都不一样。
2 变量名的命名须遵循如下规则:
one: 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头。
two:中间不能有空格,可以使用下划线“_”。
three: 不能使用标点符号。
four: 不能使用bash里的关键字(可用help命令查看保留关键字)
3 关于单双引号
的问题:
双引号能够识别变量,双引号能够实现转义(类似于“\”)
单引号是不能识别变量,只会原样输出,单引号是不能转义的。
3.1.3 只读变量(可忽略):
name=“only_read” -> readonly name (使用readonly标识后的变量,不可被修改)
删除变量: unset name; (删除之后不可访问,删除不掉只读变量)
3.1.4 接收用户输入(重点)
语法:read -p 提示信息 变量名
案例:编写一个脚本test6.sh,要求执行之后提示用户输入文件的名称(路径),然后自动为用户创建该文件
接收用户输入(重点)
语法:read -p 提示信息 变量名
3.2 循环判断
3.2.1 if
- 语法1(一个条件):
if 条件判断
then
命令
命令
...
fi
- 语法2(俩个条件)
if 判断
then
命令
命令
...
else
命令
fi
- 语法3(多个条件)
if 条件
then
命令
elif 判断
then
命令
else
命令
fi
操作运算符
运算符 | 描述 | 示例 |
---|---|---|
运算比较符 | ||
-e filename | 如果 filename 存在,则为真 | [ -e /var/log/syslog ] |
-e filename | 如果 filename 存在,则为真 | [ -e /var/log/syslog ] |
-d filename | 如果 filename 为目录,则为真 | [ -d /tmp/mydir ] |
-f filename | 如果 filename 为常规文件,则为真 | [ -f /usr/bin/grep ] |
-L filename | 如果 filename 为符号链接,则为真 | [ -L /usr/bin/grep ] |
-r filename | 如果 filename 可读,则为真 | [ -r /var/log/syslog ] |
-w filename | 如果 filename 可写,则为真 | [ -w /var/mytmp.txt ] |
-x filename | 如果 filename 可执行,则为真 | [ -L /usr/bin/grep ] |
filename1 -nt filename2 | 如果 filename1 比 filename2 新,则为真 | [/tmp/install/etc/services -nt /etc/services ] |
字符串比较运算符 (请注意引号的使用,这是防止空格扰乱代码的好方法) | ||
-z string | 如果 string 长度为零,则为真 | [ -z "$myvar" ] |
-n string | 如果 string 长度非零,则为真 | [ -n "$myvar" ] |
string1 = string2 | 如果 string1 与 string2 相同,则为真 | [ $myvar = "one two three" ] (注意等号左右用空格) |
string1 != string2 | 如果 string1 与 string2 不同,则为真 | [ "$myvar" != "one two three" ] |
算术比较运算符 | ||
num1 -eq num2 | 等于 | [ 3 -eq $mynum ] |
num1 -ne num2 | 不等于 | [ 3 -ne $mynum ] |
num1 -lt num2 | 小于 | [ 3 -lt $mynum ] |
num1 -le num2 | 小于或等于 | [ 3 -le $mynum ] |
num1 -gt num2 | 大于 | [ 3 -gt $mynum ] |
num1 -ge num2 | 大于或等于 | [ 3 -ge $mynum ] |
read -p "please input a number :" i
if [ $i -gt 5 ];then
echo true
else
echo false
fi
运行结果:
注意事项:
1、[ ]表示条件测试。注意这里的空格很重要。要注意在’[‘后面和’]'前面都必须要有空格
2、在shell中,then和fi是分开的语句。如果要在同一行里面输入,则需要用分号将他们隔开。
3、注意if判断中对于变量的处理,需要加引号,以免一些不必要的错误。没有加双引号会在一些含空格等的字符串变量判断的时候产生错误。比如[ -n “$var” ]如果var为空会出错
4、判断是不支持浮点值的
5、如果只单独使用>或者<号,系统会认为是输出或者输入重定向,虽然结果显示正确,但是其实是错误的,因此要对这些符号进行转意
6、在默认中,运行if语句中的命令所产生的错误信息仍然出现在脚本的输出结果中
7、使用-z或者-n来检查长度的时候,没有定义的变量也为0
8、空变量和没有初始化的变量可能会对shell脚本测试产生灾难性的影响,因此在不确定变量的内容的时候,在测试号前使用-n或者-z测试一下
9、? 变量包含了之前执行命令的退出状态(最近完成的前台进程)(可以用于检测退出状态)
3.2.2 for
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
3.2.3 while
条件判断
while condition
do
command
done
循环