一、Linux系统结构
一、内核层
内核是Linux系统的核心部分,它负责管理系统各种硬件设备、文件系统、内存管理和进程管理等核心任务。Linux内核设计了良好的模块化结构,可以动态地加载和卸载内核模块,这使得内核可以兼容各种不同的硬件设备和外围设备。
二、Shell层
Shell是Linux系统的命令行解释器,它负责将用户输入的命令解释并执行。Linux系统上有多种Shell,其中最常用的是Bash Shell。Bash Shell 提供了各种丰富的功能和处理能力,如通配符、重定向、管道、变量等等。
三、应用层
应用层是Linux系统上的各种应用程序和服务,包括文本编辑器、图形界面、Web服务器、邮件服务器、数据库服务器等。在Linux系统中,应用程序通常以开放源代码方式呈现,用户可以自由学习和使用,也可以根据需求自己编写、修改或扩展。
二、shell基础语法
一、shell介绍
Shell是一种用于与操作系统进行交互的命令行解释器。它是一种脚本语言,可以通过编写一系列的命令和脚本来执行操作系统的功能和任务。
二、shell的种类
- Bourne Shell(/bin/sh):是Unix系统最早的shell程序,由史蒂夫·伯恩斯(Steve Bourne)编写。该shell程序是许多Linux发行版中默认使用的程序。
- Bourne-Again SHell(/bin/bash):是GNU项目的一部分,是Bourne Shell的增强版,目前在大部分Linux发行版中是默认的shell程序。
- C Shell (/bin/csh):是Bill Joy编写的一个具有面向对象设计理念的shell程序,它采用与C语言相似的语法和控制结构。C Shell中的命令提示符为%号。
- TENEX C Shell(/bin/tcsh):是C Shell的增强版,它对历史命令和别名等方面进行了改进,同时也支持C Shell中的所有特性。TENEX C Shell中的命令提示符也为%号。
- Korn Shell(/bin/ksh):是由David Korn编写的shell程序,它是Bourne Shell和C Shell的结合,拥有两种不同的工作模式:交互模式和批处理模式。
- Z Shell(/bin/zsh):是一个功能强大的shell程序,它是Bourne Shell的增强版,具有缩写、自动完成、句法高亮等功能,同时也支持Korn Shell、C Shell以及Bourne Shell的语法和命令。
三、基础语法
shell脚本可以编写在一个xxx.sh结尾的文件中,xxx.sh文件我们称为shell脚本文件。
shell脚本文件是一个可执行文件,类似于windows环境中的xxx.exe 或 xxx.bat 等文件。
一、切换shell
在CentOS中,可以使用
chsh
命令切换默认Shell。chsh
命令允许您更改用户的登录Shell。以下是切换Shell的步骤:1、查看已安装的Shell。
cat /etc/shells
2、更改Shell。
chsh -s /bin/sh
3、重新登录后:检查Shell是否已更改
echo $SHELL
二、注释
一、单行注释
单行注释是一行文本,它以井号(#)开头,从该字符开始一直延伸到该行的结束。在此行内,任何内容都会被 Shell 解释器忽略:
# 这是一行注释 echo "Hello, World!" # 这是一行带有注释的代码
二、多行注释
Shell 脚本也支持多行注释,这种注释也被称为块注释。块注释在脚本中可以用于分组一系列代码,或将一段代码置于未被执行的状态。在 Bash Shell 中,块注释通常使用以下语法:和'之间有一个空格,这个不能忽略,否者会出错。
: ' 这里是注释内容。 可以是多行,直到下面一行的单独引号为止。 '
三、变量
一、shell变量有三种:
- 环境变量
- 本地变量
- 特殊变量
二、环境变量
1、环境变量是在Shell会话外设置的,可以由多个脚本和进程共享。在Linux中,环境变量没有固定的值,而是在需要时通过脚本或命令进行设置或更新。(系统环境变量一般在/etc/profile文件中设置。)
2、查看当前所有环境变量
printenv 或 env
3、设置一个新的环境变量
export MY_VAR="Hello World"
4、要使用环境变量,在变量名称前必须加上$符号
echo $MY_VAR
三、本地变量
一、shell脚本变量命名规范
- 变量名由字母、数字和下划线组成。
- 不能以数字开头。
- 区分大小写。
- 等号两侧不能有空格。
- 不能使用特殊字符作为变量名,如$, &, !, (, ), *等。
- 环境变量一般是全部大写,单词和单词之间采用下划线分割:JAVA_HOME, CATALINA_HOME
本地变量一般是小写
二、本地变量是一种临时变量,在Shell会话中设置和使用。与环境变量不同,本地变量仅限于当前Shell会话,不会被其他脚本或命令使用。设置本地变量可以使用“=”号操作符。
my_var="Hello World"echo $my_var
四、特殊变量
一、特殊变量是在Shell中预定义的变量名称,具有特殊的含义。这些变量与当前Shell会话有关,可以用于许多不同的用途,包括文件和目录操作、命令历史记录和处理脚本参数等等。
二、常见的一些特殊变量
$0
: 当前脚本的文件名
$1, $2...
: 脚本参数列表中的第1个、第2个参数等等 (例如:./first.sh abc def,在执行这个脚本时,第一个参数abc,第二个参数def。)
$#
: 脚本参数的数量
$*
: 所有脚本参数的列表(将所有的参数作为一个字符串:"zhangsan lisi wangwu")
$@
: 所有脚本参数的列表(将每一个参数作为一个独立的字符串:"zhangsan" "lisi" "wangwu")
$$
: 当前脚本的进程ID号
$?
: 上一个命令的退出状态,一个数值。三、$? 这个特殊变量的用法
ls -l /etc/passwd if [ $? -eq 0 ]; thenecho "ls command succeeded" elseecho "ls command failed" fi
这个变量可以用来获取上一条命令的执行结果是否正确,如果执行结果是0表示成功,其他值表示失败
四、控制语句
一、shell中的中括号用法
一、用于比较操作符:用于比较两个值的大小或者判断两个值是否相等
-eq
: 判断两个值是否相等(equal to),例如[ $a -eq $b ]
-ne
: 判断两个值是否不相等(not equal to),例如[ $a -ne $b ]
-lt
: 判断左边的值是否小于右边的值(less than),例如[ $a -lt $b ]
-gt
: 判断左边的值是否大于右边的值(greater than),例如[ $a -gt $b ]
-le
: 判断左边的值是否小于等于右边的值(less than or equal to),例如[ $a -le $b ]
-ge
: 判断左边的值是否大于等于右边的值(greater than or equal to),例如[ $a -ge $b ]
在Shell中,比较操作符可以用于中括号[]中,例如:
[ $a -eq $b ]
。在比较时,要注意两个值之间必须有空格分隔,否则会出现语法错误。二、用于测试表达式:用于测试某个表达式是否成立
-f
: 判断某个文件是否存在并且是一个常规文件(regular file),例如[ -f file.txt ]
-d
: 判断某个文件是否存在并且是一个目录(directory),例如[ -d dir ]
-z
: 判断某个字符串是否为空(zero length),例如[ -z "$str" ]
-n
: 判断某个字符串是否非空(not zero length),例如[ -n "$str" ]
-e
: 判断某个文件或目录是否存在(exist),例如[ -e file.txt ]
在Shell中,测试表达式也可以用于中括号[]中,例如:
[ -f file.txt ]
。在多数Linux发行版中,测试表达式可以用中括号[]或者test命令实现,例如:test -f file.txt
等价于[ -f file.txt ]
。需要注意的是,中括号中的空格很重要,空格缺少会导致语法错误。另外,在使用中括号[]时,要注意变量用双引号括起来,避免空值引起的语法错误。二、if语句详解
if condition thencommand1command2... elif condition2 thencommand3command4... elsecommand5command6... fi栗子:#!/bin/bashif [ -f file.txt ] thenecho "file.txt exists." elif [ -d dir ] thenecho "dir exists." elseecho "file.txt and dir not found." fi
其中,
condition
是要检查的条件,可以是命令、变量、表达式等任何Shell语法,then
表示条件成立要执行的语句块,如果有多个条件,可以使用elif
语句来添加多个条件,每个条件使用then
分别表示要执行的语句块,如果所有条件都不成立,则执行else
分支中的语句块。
if语句的执行过程是从上到下依次判断每个条件,如果条件成立,则执行对应的语句块,执行完后跳出if语句。栗子:
#!/bin/bashif [ -f file.txt ] thenecho "file.txt exists." elif [ -d dir ] thenecho "dir exists." elseecho "file.txt and dir not found." fi
三、for循环详解
1、语法
for var in list docommand1command2... done
其中,
var
是一个临时的变量名,用于存储当前循环的值,list
是一个值或者多个带有空格或换行符分隔的值组成的列表。在每一次循环迭代时,var
会被list
列表中的一个值所替换,直到list
中的所有值都被处理完为止。#!/bin/bashfor i in 1 2 3 4 5 doecho "The value of i is: $i" done
四、while循环详解
1、语法:
while condition docommand1command2... done
其中,
condition
是要检查的条件,如果条件为真,则执行do
语句块中的命令,执行完后再回到while
语句中检查条件是否依然为真,如果条件仍为真,则继续执行命令块,否则跳出循环。注意:在shell编程中 ((...)) 被称为算术扩展运算符,做数学运算的,并且将运算结果返回。(...)运算符会将结果直接返回。
- $((j+1)),如果j是5的话,结果就会返回6 (注意,使用这个运算符的时候,括号里面不能有空格)
- $(echo "hello world"),会将"hello world"打印,然后再将"hello world"字符串返回。
栗子:
#!/bin/bashj=0 while [ $j -lt 5 ] doecho "The value of j is: $j"j=$((j+1)) done
五、until循环详解
1、语法:
until condition docommand1command2... done
其中,
condition
是要检查的条件,如果条件为假,则执行do
语句块中的命令,执行完后再回到until
语句中检查条件是否依然为假,如果条件仍为假,则继续执行命令块,否则跳出循环。#!/bin/bashk=0 until [ $k -ge 5 ] doecho "The value of k is: $k"k=$((k+1)) done
六、break和continue语句
1、break语句用于跳出当前循环块,例如在for循环和while循环中使用该语句时,可以跳出当前循环并停止迭代。break语句可以嵌套在多重循环中,用于跳出内层循环和外层循环
while condition docommand1command2if condition2 thenbreakficommand3... done
在上述示例中,如果在执行
command2
时,条件condition2
成立,那么会执行break
语句,跳出循环块并停止迭代。2、continue语句用于跳过本次循环迭代,直接进入下一次的迭代。在for循环和while循环中使用该语句时,可以用于跳过本次迭代,执行下一次迭代。其语法格式如下
while condition docommand1command2if condition2thencontinueficommand3... done
如果在执行
command2
时,条件condition2
成立,那么会执行continue
语句,跳过本次迭代,直接进入下一次迭代。栗子:
#!/bin/bashfor l in 1 2 3 4 5 doif [ $l -eq 3 ] thencontinuefiecho "The value of l is: $l"if [ $l -eq 4 ] thenbreakfi done
五、函数
一、什么是函数
在Shell编程中,函数是一种可重用的代码块,其实就是相当于java的方法。
二、定义函数
1、语法
function_name() {commands }
2、栗子
function say_hello() {echo "Hello, world!" }
使用function关键字来定义函数是可选的。当使用function关键字时,要注意不要加空格,否则会出现语法错误。函数体中可以包含任意数量的命令和语句。
三、调用函数
成功定义一个函数后,可以在程序的任何地方调用它。只需要使用函数的名称,即可调用函数。例如:
say_hello
四、传递参数
Shell函数也支持传递参数。在调用函数时,可以把参数传递给函数,让函数使用这些参数来完成特定的任务
function greet() {echo "Hello, $1 $2" }greet "John" "Doe"
上述示例中,我们定义了一个名为
greet
的函数,它输入参数1和2,并把这些参数用于输出字符串Hello, $1 $2
。我们调用greet
函数,并把参数"John"和"Doe"传递给它,最终输出Hello, John Doe
字符串。在函数中,参数可以使用1、2、3等占位符来引用。1表示第一个参数,$2表示第二个参数,以此类推。
栗子:
#!/bin/sh# 定义函数say_hello say_hello() {echo "Hello, world!" }# 调用函数say_hello say_hello# 定义函数greet greet() {echo "Hello, $1 $2" }# 调用函数greet greet "John" "Doe"