一、什么是shell
1、定义:
shell 是一个命令行解释器,它为用户提供了与操作系统交互的接口。用户可以在 shell 中输入命令,然后由 shell 解释并执行这些命令。直白的说,shell 就是一个程序,它允许用户通过命令行与计算机操作系统进行交互。用户可以在 shell 中输入命令,然后 shell 会解释并执行这些命令,完成各种任务。
2、用途
shell 还提供了许多高级功能,例如命令历史、命令补全、命令别名、脚本编程等。这些功能可以帮助用户更快捷、更高效地使用操作系统。
3、shell主要种类
常见的 shell 包括 Bourne shell(sh)、Bourne Again shell(bash)、C shell(csh)、Z shell(zsh)等。不同的 shell 有不同的特性和语法,但它们都提供了基本的命令行解释功能。
二、shell的执行方式
当 shell 执行一个外部命令时,它通常会创建一个子进程来执行这个命令。这种方式称为子进程执行。
例如,假设我们在 shell 中执行 ls 命令。shell 会创建一个子进程,并在这个子进程中执行 ls 命令。当 ls 命令执行完成后,子进程会退出,然后 shell 会继续等待用户输入下一条命令。
子进程执行的优点是,即使子进程崩溃或被终止,父进程(即 shell)也不会受到影响,仍然可以继续运行。此外,父进程和子进程之间可以通过管道、重定向等方式进行通信,实现更复杂的功能。
有些情况下,shell 也可以直接执行命令,而不创建子进程。这种方式称为父进程执行。
它通常发生在执行 shell 内置命令时。例如,cd、echo、exit 等命令都是 shell 内置命令,它们会直接由 shell 执行,而不会创建子进程。
父进程执行的优点是速度快,因为不需要创建子进程。但是,如果命令执行过程中出现错误,可能会影响到父进程(即 shell)的运行。
三、shell的配置文件读取
当 shell 启动时,它会读取一些配置文件来初始化环境。不同的 shell 有不同的配置文件,它们的位置和名称也不同。
例如,对于 bash shell,它会按顺序读取以下配置文件:
/etc/profile:系统级别的配置文件,对所有用户生效。~/.bash_profile、~/.bash_login、~/.profile:用户级别的配置文件,只对当前用户生效。bash 会按顺序查找这些文件,只读取第一个存在的文件。
当用户退出 bash shell 时,它还会读取 ~/.bash_logout 文件来执行一些清理操作。
对于其他类型的 shell,它们也有类似的配置文件。例如,zsh 会读取 /etc/zshenv、~/.zshenv、/etc/zprofile、~/.zprofile 等文件。
用户可以在这些配置文件中设置环境变量、定义函数、创建别名等。这些设置会在 shell 启动时自动生效。
四、shell的命令执行机制
老师课程里说的是:字符解析,展开,查找命令、执行。这里再补充一下后面的两步--- 等待结果、返回结果。
展开来说:当用户在 shell 中输入一条命令并按回车键时,shell 会按照以下步骤执行这条命令:
- 解析命令行:shell 会对用户输入的命令行进行解析,将其分割成多个单词。每个单词都可以是命令、选项、参数或特殊字符(如管道符
|、重定向符<和>等)。 - 查找命令:shell 会在环境变量
PATH指定的目录中查找命令。如果找到了,就执行这个命令;否则,显示错误信息。 - 执行命令:如果命令是一个外部命令(即不是 shell 内置命令),则 shell 会创建一个子进程来执行这个命令。如果命令是一个内置命令,则 shell 会直接执行这个命令。
- 等待结果:如果命令是一个外部命令,则 shell 会等待子进程执行完成并返回结果。如果命令是一个内置命令,则 shell 会直接显示结果。
- 返回提示符:当命令执行完成后,shell 会显示一个提示符,等待用户输入下一条命令。
这就是 shell 命令执行的基本机制。当然,实际情况可能更复杂,因为 shell 还支持许多高级功能,例如管道、重定向、变量替换、命令替换等。
五、运算符和引用
这里图中很明确了,不做解释。
六、管道和重定向
在 shell 中,管道(pipe)是一种将多个命令连接起来的机制。它允许用户将一个命令的输出作为另一个命令的输入,从而实现复杂的操作。
管道使用竖线符号 | 来表示。例如,下面的命令使用管道将 ls 命令的输出作为 wc 命令的输入:
sh
复制代码
ls | wc -l
上面的命令会列出当前目录中的文件和目录,然后使用 wc 命令计算它们的数量。wc -l 命令会统计输入行数,因此最终结果就是当前目录中文件和目录的数量。
管道可以连接任意多个命令。例如,下面的命令使用两个管道将三个命令连接起来:
sh
复制代码
ls | grep '.txt' | wc -l
上面的命令会列出当前目录中的文件和目录,然后使用 grep 命令过滤出以 .txt 结尾的文件,最后使用 wc 命令计算它们的数量。最终结果就是当前目录中以 .txt 结尾的文件数量。
补充几个点,使用管道时需要注意:
- 管道只能传递标准输出(stdout)。如果
cmd1产生了错误输出(stderr),则这些输出不会被传递给cmd2。 - 管道中的每个命令都是在一个单独的子进程中执行的。这意味着,如果
cmd1修改了环境变量或当前目录,这些修改不会影响到cmd2。 - 管道中的命令会同时执行。也就是说,
cmd1和cmd2会同时启动,而不是等待cmd1执行完成后再启动cmd2。 - 如果管道中的某个命令失败(即退出状态非零),则整个管道的退出状态也是非零。但是,这并不会影响到其他命令的执行。也就是说,即使
cmd1失败,cmd2仍然会执行。
2、重定向
什么时候会触发重定向呢,
七、判断、选择命令
1、判断命令(官方的说法叫条件成立)
在 shell 中,test、[ 和 [[ 都是用于判断的命令。
test命令用于检查某个条件是否成立。例如,test -e filename会检查文件filename是否存在。如果存在,则命令返回真(退出状态为 0);否则返回假(退出状态为非 0)。[命令实际上是test命令的另一种写法。它的语法与test命令相同,只是需要在最后添加一个]。例如,[ -e filename ]等同于test -e filename。[[命令是一种扩展的测试命令,它提供了比test和[更多的功能。例如,它支持模式匹配和正则表达式匹配。它的语法与[类似,只是需要在最后添加一个]]。例如,[[ -e filename ]]等同于[ -e filename ]。
这些命令通常用于 shell 脚本中的条件判断。例如:
sh
复制代码
if [ -e filename ]; then
echo "文件存在"
else
echo "文件不存在"
fi
上面的脚本使用 [ 命令检查文件 filename 是否存在,然后根据检查结果执行不同的操作。
2、选择
shell主要的选择结构分别是 if else 语句和 case in 语句和if elif else。它们都是根据命令的退出状态来判断条件是否成立。写法如下图。
- if else 语句 最简单的用法就是只使用 if 语句,它的语法格式为:
sh
复制代码
if condition
then
statement(s)
fi
condition 是判断条件,如果 condition 成立(返回“真”),那么 then 后边的语句将会被执行;如果 condition 不成立(返回“假”),那么不会执行任何语句。注意,最后必须以 fi 来闭合。
如果有两个分支,就可以使用 if else 语句,它的格式为:
sh
复制代码
if condition
then
statement1
else
statement2
fi
如果 condition 成立,那么 then 后边的 statement1 语句将会被执行;否则,执行 else 后边的 statement2 语句。
- if elif else 语句 Shell 支持任意数目的分支,当分支比较多时,可以使用 if elif else 结构,它的格式为:
sh
复制代码
if condition1
then
statement1
elif condition2
then
statement2
elif condition3
then
statement3
……
else
statementn
fi
注意,if 和 elif 后边都得跟着 then。
- case in 语句 case in 语句的语法格式为:
sh
复制代码
case 变量 in
情况一)
statement1;;
情况二)
statement2;;
*)
default statement;;
esac
八、循环
在 Shell 脚本中,常用的循环语句包括 for 循环、while 循环和 until 循环。for 循环通常用于遍历一组数据,while 循环和 until 循环则用于在满足条件的情况下重复执行一段代码。
举个例子 好的,这里是关于 Shell 中三种循环语句的具体含义和解释:
- for 循环 for 循环通常用于遍历一组数据,它的语法格式为:
sh
复制代码
for 变量 in 列表
do
命令序列
done
其中,列表可以是一组数字、字符或字符串,也可以是一个命令的输出结果。for 循环会依次将列表中的每个元素赋值给变量,并执行命令序列。
- while 循环 while 循环用于在满足条件的情况下重复执行一段代码,它的语法格式为:
sh
复制代码
while 条件测试
do
命令序列
done
其中,条件测试可以是一个命令或一组命令,也可以是一个逻辑表达式。当条件测试返回真时,while 循环会执行命令序列;当条件测试返回假时,while 循环结束。
- until 循环 until 循环与 while 循环类似,但它是在条件不满足的情况下重复执行一段代码,它的语法格式为:
sh
复制代码
until 条件测试
do
命令序列
done
其中,条件测试可以是一个命令或一组命令,也可以是一个逻辑表达式。当条件测试返回假时,until 循环会执行命令序列;当条件测试返回真时,until 循环结束。