// Linux · 2024-11-14

Shell脚本基础开篇:Shell与脚本的基本概念及脚本的执行方式

一、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脚本的特点

  1. 解释型语言:Shell 脚本属于解释型语言,不需要事先编译。Shell 解释器会逐行解析并执行脚本中的命令,适合快速开发和调试,尤其是在系统管理和自动化任务中。
  2. 交互性:Shell 提供了交互式命令行界面,支持用户在运行脚本时与其交互。用户可以在脚本执行过程中提供输入,根据输入的内容,脚本可以执行不同的操作。
  3. 灵活性:Shell脚本支持多种命令类型,包括内置命令、外部命令、以及通过脚本自定义的命令。通过控制结构(如条件语句、循环语句等),Shell脚本能够执行复杂的逻辑和任务。
  4. 可移植性:大多数 Shell 脚本可以在不同的操作系统和Shell解释器上运行。虽然有些Shell具有特定的功能,Shell脚本在不同系统上的兼容性通常较好,可以帮助开发人员实现跨平台自动化任务。

Shell脚本的基本语法

  • 变量:

    • 定义与使用:Shell脚本支持使用变量来存储数据(如字符串、数值等),并可以在脚本中随时调用。例如,使用 name="xiaoyu" 定义一个变量 name,然后通过 $name 或 ${name} 引用该变量。
    • 预定义变量:Shell 提供了一些内置的预定义变量,如 $HOME(用户的主目录),$PATH(可执行文件路径),$USER(当前用户名)等。
    • 环境变量与位置变量:环境变量是影响Shell环境的全局变量,位置变量则是通过脚本参数传递的变量(如 $1, $2, "$@"等)。
  • 运算符:

    • 算术运算符:Shell支持基本的数学运算,如加法(+)、减法(-)、乘法(*)、除法(/)等,使用 (( )) 或 let 来进行数值计算。
    • 逻辑运算符:Shell支持常见的逻辑运算符,如与(&&)、或(||)、非(!)等,用于控制流程和判断条件。
    • 字符串运算符:例如字符串的拼接、长度获取(${#var})、子串提取(${var:position:length})等操作。
  • 控制结构:

    • 条件语句:Shell支持 if-else 语句、case 语句等,用于根据不同的条件执行不同的操作。例如,if [ condition ]; then ... fi 用于根据条件判断执行特定命令。
    • 循环语句:Shell支持 for 循环(用于遍历列表)、while 循环(基于条件判断执行)、until 循环(直到条件为真时停止)等。可以使用这些语句进行重复任务处理。
    • 跳转语句:如 break(跳出循环)、continue(跳过当前循环)等,便于控制脚本执行流程。
  • 函数:

    • 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

重点分析:

  1. 执行权限:

    • 相对路径和绝对路径执行的脚本必须有执行权限(chmod +x),否则无法直接执行。
    • 使用解释器(如sh a.sh)时,不需要执行权限,只需要读取权限。
    • 使用source或.加载脚本时,只要脚本有读取权限即可。
  2. 父shell与子shell:

    • 使用source或.时,脚本在当前shell环境中执行,变量、环境变化会直接影响当前shell。
    • 其他执行方式(如./a.sh、sh a.sh)会启动新的子shell,这些子shell的环境不会影响父shell。
  3. 适用场景:

    • 如果脚本需要修改环境变量或函数定义,建议使用source或.来执行脚本,确保修改影响到当前shell。
    • 如果只是执行脚本中的操作并不需要影响当前shell环境,使用./或绝对路径执行脚本更为合适。

示例对比: 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

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