一、Shell 基础知识
Shell的基本概念
-
定义: Shell 是操作系统中的命令解释器,位于用户与操作系统内核之间。它接收并解释用户输入的命令,将任务传递给操作系统内核执行,然后将执行结果返回给用户。Shell 使得用户能够通过命令行与操作系统交互,控制和管理计算机的各种资源和应用。Shell 是系统与用户之间的桥梁,通过 Shell,用户可以直接控制操作系统进行文件操作、程序执行、系统配置等。
-
Shell 脚本: Shell 脚本是由一系列 Shell 命令组成的文件,可以自动执行任务,通常用于简化和自动化操作。Shell 脚本是一种解释型语言,不需要编译,它会逐行解释并执行脚本中的命令。通过编写 Shell 脚本,用户可以在多个操作系统中执行相同的任务,而无需手动输入每一条命令。
-
Shell 脚本的主要用途:
- 自动化任务:通过编写 Shell 脚本,用户可以自动执行重复性的任务,如文件备份、日志分析、定时任务等。
- 批量文件管理:Shell 脚本可以处理大量文件的管理任务,如批量重命名、移动、删除或修改文件内容等。
- 系统命令执行:系统管理员常常使用 Shell 脚本执行操作系统命令,如安装软件包、配置系统设置、管理用户权限等。
- 程序调度:Shell 脚本可与任务调度程序(如
cron)结合,定期执行特定任务,例如定时备份、数据清理等。 - 网络服务管理:Shell 脚本广泛用于配置和管理网络服务,例如启动和停止 Web 服务器、数据库服务器等。
常见Shell类型
-
/bin/sh:传统的Shell,最早由Steve Bourne在1970年代开发,因此也称为 Bourne Shell。许多脚本使用/bin/sh作为默认的Shell解释器。在现代Linux系统中,/bin/sh通常是指向其他Shell(如bash或dash)的符号链接。 -
/bin/bash:Bash(Bourne Again Shell)是Linux中最常用的Shell,它是Bourne Shell的增强版本,增加了更多的功能和灵活性,比如命令补全、历史命令、数组支持等。几乎所有Linux用户都在使用Bash作为默认Shell。 -
/bin/dash:Dash(Debian Almquist Shell)是一个轻量级、高效的Shell,常用于需要快速启动和执行脚本的场景,特别是在Debian及其衍生发行版中。与bash相比,dash提供的功能较少,但它遵循POSIX标准并执行速度更快,因此被许多系统(如Ubuntu)选择作为/bin/sh的实现。dash适用于那些没有依赖bash特有功能的脚本,并且在执行效率上有优势。 -
/sbin/nologin和/usr/sbin/nologin:这两者并不是Shell,而是一个特殊的程序,用于阻止某些用户通过Shell登录系统。通常,系统管理员或受限账户(例如服务账户)会被配置为使用这类Shell,以防止他们直接访问系统。这些Shell会向用户显示一条“登录已禁用”的消息,并拒绝任何登录尝试。
Shell脚本的特点
- 解释型语言:Shell 脚本属于解释型语言,不需要事先编译。Shell 解释器会逐行解析并执行脚本中的命令,适合快速开发和调试,尤其是在系统管理和自动化任务中。
- 交互性:Shell 提供了交互式命令行界面,支持用户在运行脚本时与其交互。用户可以在脚本执行过程中提供输入,根据输入的内容,脚本可以执行不同的操作。
- 灵活性:Shell脚本支持多种命令类型,包括内置命令、外部命令、以及通过脚本自定义的命令。通过控制结构(如条件语句、循环语句等),Shell脚本能够执行复杂的逻辑和任务。
- 可移植性:大多数 Shell 脚本可以在不同的操作系统和Shell解释器上运行。虽然有些Shell具有特定的功能,Shell脚本在不同系统上的兼容性通常较好,可以帮助开发人员实现跨平台自动化任务。
Shell脚本的基本语法
-
变量:
- 定义与使用:Shell脚本支持使用变量来存储数据(如字符串、数值等),并可以在脚本中随时调用。例如,使用
name="xiaoyu"定义一个变量name,然后通过$name或${name}引用该变量。 - 预定义变量:Shell 提供了一些内置的预定义变量,如
$HOME(用户的主目录),$PATH(可执行文件路径),$USER(当前用户名)等。 - 环境变量与位置变量:环境变量是影响Shell环境的全局变量,位置变量则是通过脚本参数传递的变量(如
$1,$2,"$@"等)。
- 定义与使用:Shell脚本支持使用变量来存储数据(如字符串、数值等),并可以在脚本中随时调用。例如,使用
-
运算符:
- 算术运算符:Shell支持基本的数学运算,如加法(
+)、减法(-)、乘法(*)、除法(/)等,使用(( ))或let来进行数值计算。 - 逻辑运算符:Shell支持常见的逻辑运算符,如与(
&&)、或(||)、非(!)等,用于控制流程和判断条件。 - 字符串运算符:例如字符串的拼接、长度获取(
${#var})、子串提取(${var:position:length})等操作。
- 算术运算符:Shell支持基本的数学运算,如加法(
-
控制结构:
- 条件语句:Shell支持
if-else语句、case语句等,用于根据不同的条件执行不同的操作。例如,if [ condition ]; then ... fi用于根据条件判断执行特定命令。 - 循环语句:Shell支持
for循环(用于遍历列表)、while循环(基于条件判断执行)、until循环(直到条件为真时停止)等。可以使用这些语句进行重复任务处理。 - 跳转语句:如
break(跳出循环)、continue(跳过当前循环)等,便于控制脚本执行流程。
- 条件语句:Shell支持
-
函数:
- Shell 脚本支持函数的定义和调用,函数使得脚本更具模块化和可维护性。函数可以接收参数、执行特定任务并返回结果。例如,定义一个简单的问候函数:
function greet() { echo "Hello, $1" } greet "World"该函数将打印
"Hello, World"。通过使用函数,用户可以将常用的代码封装成模块,便于重复使用和管理。
二、创建和运行 Shell 脚本
创建 Shell 脚本
使用 vim 编辑器或其他文本编辑器创建一个名为 1.sh 的文件:
vim 1.sh
在文件中加入以下内容:
#!/bin/bash
echo "Hello, World!"
#!/bin/bash:这行被称为 shebang,它告诉系统使用/bin/bash作为解释器来执行脚本。这行代码确保脚本在任何环境中都能正确执行。
编辑完成后,按 ESC 键退出编辑模式,输入 :x 保存并退出 vim 编辑器。
运行 Shell 脚本
有了执行权限之后,脚本就可以运行了。你可以通过以下命令来执行脚本:
./1.sh
终端将输出:
Hello, World!
./:表示当前目录。如果没有./,Shell 会在系统的PATH环境变量中查找该脚本,而不会默认查找当前目录。使用./使脚本能够在当前目录下执行。
除了使用 ./ 执行脚本,还有其他几种运行脚本的方法:
1. 使用 sh 命令执行
如果你不想给脚本赋予执行权限,可以使用 sh 命令来运行脚本:
sh 1.sh
- 这种方法不需要脚本文件的执行权限,
sh命令会自动解析并执行脚本中的命令。 - 使用
sh执行脚本时,脚本会在一个新的 shell 中运行,环境变量和其他设置不会影响当前 shell 环境。它启动了一个子 shell 来执行命令,执行完毕后,环境中的任何更改(如变量的定义)都会丢失。
2. 使用 source 或 . 命令执行
使用 source 或 . 命令可以在当前 shell 环境中执行脚本:
source 1.sh
或者
. /1.sh
source或.:这两个命令作用相同,都可以在当前的 shell 环境中执行脚本。它们不会启动新 shell,而是直接在当前 shell 中执行脚本。- 使用这种方式时,脚本中的变量、函数或其他设置会直接影响当前的 shell 环境。例如,如果脚本中定义了一个新的变量,该变量会在当前的 shell 中保留,可以在后续的命令中使用。
总结
| 执行方式 | 描述 | 优缺点 | 是否需要执行权限 | 父/子shell |
|---|---|---|---|---|
相对路径 (./a.sh) |
使用相对路径执行脚本。脚本位于当前目录下,使用./来指定。 |
优点:快速执行,路径清晰。 缺点:如果当前目录没有加入 $PATH,需要每次指定相对路径。 |
需要执行权限 | 子shell |
绝对路径 (/home/user/a.sh) |
使用绝对路径执行脚本。通过完整路径指定脚本位置。 | 优点:无论当前目录在哪里,都可以明确执行脚本。 缺点:路径较长,不便于移动或管理。 |
需要执行权限 | 子shell |
解释器执行 (sh a.sh) |
使用解释器(如sh)直接执行脚本。解释器会逐行解析并执行脚本。 |
优点:不需要脚本文件有执行权限,只需文件有读取权限即可。 缺点:无法直接执行脚本,需要依赖解释器。 |
不需要执行权限,可以是普通文本文件 | 子shell |
. a.sh 或 source a.sh |
使用.或source命令将脚本加载到当前shell环境中,逐行执行。不会创建子进程。 |
优点:脚本中的变量、函数等会影响当前shell环境,适用于需要修改环境的脚本。 缺点:脚本执行后不会生成新的子进程,执行时如果脚本有问题,当前环境也会受到影响。 |
不需要脚本执行权限,但需要脚本能够被读取 | 父shell |
重点分析:
-
执行权限:
- 相对路径和绝对路径执行的脚本必须有执行权限(
chmod +x),否则无法直接执行。 - 使用解释器(如
sh a.sh)时,不需要执行权限,只需要读取权限。 - 使用
source或.加载脚本时,只要脚本有读取权限即可。
- 相对路径和绝对路径执行的脚本必须有执行权限(
-
父shell与子shell:
- 使用
source或.时,脚本在当前shell环境中执行,变量、环境变化会直接影响当前shell。 - 其他执行方式(如
./a.sh、sh a.sh)会启动新的子shell,这些子shell的环境不会影响父shell。
- 使用
-
适用场景:
- 如果脚本需要修改环境变量或函数定义,建议使用
source或.来执行脚本,确保修改影响到当前shell。 - 如果只是执行脚本中的操作并不需要影响当前shell环境,使用
./或绝对路径执行脚本更为合适。
- 如果脚本需要修改环境变量或函数定义,建议使用
示例对比:

原文 https://blog.csdn.net/2301_79518550/article/details/143755645