一、Shell概述
1、什么是shell
Shell是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务,在用户和内核之间充当翻译官的角色,是一个命令解释器。
Shell是一种编程语言,只是比较古老。Shell是由 C语言开发出来的,它是用户使用 Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言。
Shell是一种弱数据类型的脚本语言,无需声明变量类型,直接定义使用,默认的都是字符串类型。
对于 Linux操作系统内部应用而言,Shell是最好的工具,因为 Linux底层命令都支持 Shell语句,以及结合grep、sed、awk进行的高级用法。
Shell本质上是 Linux命令,一条一条命令组合在一起,实现某一个目的,就变成了 Shell脚本。它从一定程度上减轻了工作量,提高了工作效率。
2、什么是 Shell脚本
Shell 脚本(shell script),是一种为 shell 编写的脚本程序文件。
计算机执行这个文件,就是计算机读取这个文件中的代码,然后将这些 Linux命令一次执行完毕。
计算机在执行 Shell脚本文件的时候是不需要交互的,就是非交互方式执行的,一旦代码有问题,出现交互,就表示没有一次执行完毕所有的语句,是执行半截卡住了,就得重新修改代码逻辑。
业界所说的 shell 通常都是指 shell 脚本,由于习惯的原因,一般大家所说的 “shell编程” 都是指 shell 脚本编程,不是指开发 shell 自身。
Linux系统中常会用到 *.sh 脚本文件,通常使用 vim编辑,由linux命令、bash shell 指令、逻辑控制语句和注释等信息组成。
Shell脚本语言非常适合处理纯文本类型数据,如日志文件、配置文件、文本、网页文件。
3、Shell 环境
Shell 编程跟 JavaScript、Python编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。
Linux 的 Shell 种类众多,常见的有:
- Bourne Shell(/usr/bin/sh或/bin/sh)
- Bourne Again Shell(/bin/bash)
- C Shell(/usr/bin/csh)
- K Shell(/usr/bin/ksh)
- Shell for Root(/sbin/sh)
在一般情况下,人们并不区分 Bourne Shell 和 Bourne Again Shell,所以,像 #!/bin/sh,它同样也可以改为 #!/bin/bash。
Bash,也就是 Bourne Again Shell,由于其易用和免费,Bash 在日常工作中被广泛使用。同时,Bash 也是大多数 Linux系统默认的 Shell。
4、编写 Shell脚本
新建一个文件 test.sh,扩展名为 sh(sh代表shell),扩展名并不影响脚本执行,见名知意就好。
shell脚本格式:
#!/bin/bash # 脚本以#!开头(指定解析器)
# 编写需要的命令
编写第一个 Shell脚本。
#!/bin/bash
echo "Hello World"
- #! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。
- echo 命令用于向窗口输出文本。
5、运行 Shell脚本
shell脚本常用的执行方式。
5.1 作为可执行程序运行
输入脚本的绝对路径或相对路径执行脚本(必须具有可执行权限+x),一般使用这种方式执行脚本语言。
[root@centos7 tmp]# chmod +x ./test.sh
[root@centos7 tmp]# ./test.sh
Hello World
注意:
./表示当前目录,整条命令的意思是执行当前目录下的 test.sh 脚本。如果不写./,Linux 会到系统路径(由 PATH 环境变量指定)下查找 test.sh,而系统路径下显然不存在这个脚本,所以会执行失败。
通过这种方式运行脚本,脚本文件第一行的#!/bin/bash一定要写对,好让系统查找到正确的解释器。
5.2 作为解释器参数运行
采用 bash 或 sh + shell脚本的相对路径或绝对路径(脚本可以不具有可执行权限+x)。
[root@centos7 tmp]# /bin/sh ./test.sh
Hello World
[root@centos7 tmp]# /bin/bash ./test.sh
Hello World
[root@centos7 tmp]# bash ./test.sh
Hello World
[root@centos7 tmp]# sh ./test.sh
Hello World
这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。
这两种写法在本质上是一样的:
- 第一种写法给出了Bash的绝对路径,会直接运行 Bash 解释器;
- 第二种写法通过 bash 命令找到 Bash 解释器所在的目录,然后再运行,只不过多了一个查找的过程而已。
5.3 在当前进程中运行 Shell脚本
source 是 Shell 内置命令的一种,它会读取脚本文件中的代码,并依次执行所有语句。你也可以理解为,
source 命令会强制执行脚本文件中的全部命令,而忽略脚本文件的权限。
source 命令的用法为:
source shell脚本的相对路径或绝对路径
# 也可以简写为:
. shell脚本的相对路径或绝对路径
两种写法的效果相同。对于第二种写法。注意:
点号.和文件名中间有一个空格。
[root@centos7 ~]# source /tmp/test.sh
Hello World
[root@centos7 ~]# . /tmp/test.sh
Hello World
不管使用哪一种方式,如果找不到指定的解析器解析就使用默认解析器解析。
6、Shell 注释
(1)单行注释
以 # 开头的行就是注释,会被解释器忽略。
##### 开始 #####
#
#
# 这里可以添加脚本描述信息
#
#
##### 结束 #####
(2)多行注释
- 1)使用 Here 文档
多行注释格式如下:
:<<EOF
注释内容...
注释内容...
注释内容...
EOF
:冒号是一个空命令,用于执行后面的 Here 文档,<<‘EOF’ 表示开启 Here 文档,COMMENT 是 Here 文档的标识符,在这两个标识符之间的内容都会被视为注释,不会被执行。
EOF 也可以换成其他符号:
: <<'COMMENT'
这是注释的部分。
可以有多行内容。
COMMENT
:<<!
注释内容...
注释内容...
注释内容...
!
- 2)直接使用 : 号
也可以直接使用冒号 : 命令,并用单引号 ’ 将多行内容括起来。由于冒号是一个空命令,这些内容不会被执行。
格式为:: + 空格 + 单引号。
: '
这是注释的部分。
可以有多行内容。
'
二、变量使用
变量是用来存储数据值的名称。
Shell是一种弱数据类型的脚本语言,脚本语言在定义变量时通常不需要指明类型,直接赋值就可以,Shell 变量也遵循这个规则。
在 Bash shell 中,每一个变量的值都是字符串,无论你给变量赋值时有没有使用引号,值都会以字符串的形式存储。
Bash shell 在默认情况下不会区分变量类型,即使你将整数和小数赋值给变量,它们也会被视为字符串,这一点和大部分的编程语言不同。
1、定义变量
定义变量时,变量名不加 $美元符号,格式如下:
#!/bin/sh
your_variable_name=value1
your_variable_name='value2'
your_variable_name="value3"
echo $your_variable_name
如果 value 不包含任何空白符(例如空格、Tab 缩进等),那么可以不使用引号;
如果 value 包含了空白符,那么就必须使用引号包围起来。
注意:
- 赋值号=的周围不能有空格,这可能和你熟悉的大部分编程语言都不一样。
- 已定义的变量,可以被重新定义,即修改变量的值。
变量名的命名须遵循如下规则:
- 只包含字母、数字和下划线: 变量名可以包含字母(大小写敏感)、数字和下划线 _,不能包含其他特殊字符。
- 不能以数字开头: 变量名不能以数字开头,但可以包含数字。
- 避免使用 Shell 关键字: 不要使用Shell的关键字(例如 if、then、else、fi、for、while 等)作为变量名,以免引起混淆。
- 使用大写字母表示常量: 习惯上,常量的变量名通常使用大写字母,例如 PI=3.14。
- 避免使用特殊符号: 尽量避免在变量名中使用特殊符号,因为它们可能与 Shell 的语法产生冲突。
- 避免使用空格: 变量名中不应该包含空格,因为空格通常用于分隔命令和参数。
2、使用变量
变量引导符$:在变量前加美元符号,即可取该变量的值。
使用一个定义过的变量,只要在变量名前面加美元符号即可。
示例如下:
#!/bin/sh
your_variable_name="value"
echo $your_variable_name
echo ${your_variable_name}
变量名外面的花括号{ }是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界。推荐给所有变量加上花括号{ },这是个好的编程习惯。
比如下面这种情况:
#!/bin/sh
skill="Java"
echo "I am good at ${skill}Script"
如果不给skill变量加花括号,写成echo "I am good at s k i l l S c r i p t " ,解释器就会把 skillScript",解释器就会把 skillScript",解释器就会把skillScript当成一个变量(其值为空),代码执行结果就不是我们期望的样子了。
3、只读变量
使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
示例如下:如果尝试更改只读变量,结果报错:
#!/bin/bash
your_variable_name=value1
readonly your_variable_name
your_variable_name=value2
echo $your_variable_name
4、删除变量
使用 unset 命令可以删除变量。语法:
unset your_variable_name
变量被删除后不能再次使用。unset 命令不能删除只读变量。
示例如下:
#!/bin/sh
your_variable_name="value1"
unset your_variable_name
echo $your_variable_name
– 求知若饥,虚心若愚。