轻轻松松玩转Linux Shell编程 Part One

发布时间:2023年12月31日

轻轻松松玩转Linux Shell编程 Part One

1、Shell 简介

Shell 是一种计算机操作系统的命令行解释器,用于提供用户与操作系统内核进行交互的界面。它允许用户通过输入和执行命令来控制计算机的操作和管理文件系统。Shell 提供了一种将多个命令组合在一起执行的方式,从而实现更复杂的任务。

常见的 Shell 实现包括 Bash(Bourne Again SHell)、C Shell、Korn Shell 等。其中,Bash 是最常用的 Shell,它是许多 Linux 和 macOS 系统的默认 Shell。

Shell 提供了一种脚本编程语言,允许用户编写一系列的命令和控制结构来自动化常见的任务。这些脚本可以包含条件判断、循环、变量和函数等,使得用户可以编写复杂的脚本程序来自动化系统管理和任务处理。

Shell 还支持通配符扩展、管道和重定向等功能。通配符扩展允许用户使用特殊字符来匹配文件名,以便进行批量操作。管道允许用户将一个命令的输出传递给另一个命令进行处理,从而实现数据流的处理。重定向则允许用户将命令的输入或输出重定向到文件或其他设备。

PowerShell 是一种命令行 shell 和脚本语言,它是在 Windows 平台上广泛使用的工具。与传统的 Windows 命令提示符(Command Prompt)相比,PowerShell 提供了更强大的功能和更丰富的脚本编程支持。

PowerShell 基于 .NET 框架,并集成了命令行解释器、脚本语言和自动化任务处理的功能。它支持许多与操作系统相关的任务,如文件和文件夹管理、进程管理、注册表操作等。此外,PowerShell 还可以与许多 Microsoft 产品和技术进行集成,如 Active Directory、Exchange Server、Azure 等,以便进行系统管理和自动化操作。

PowerShell 提供了一种强大的脚本语言,使得用户可以编写复杂的脚本程序来自动化任务和系统管理。它支持变量、条件语句、循环、函数等常见的编程结构,同时还提供了丰富的命令集合和模块化的扩展机制,方便用户进行脚本开发和扩展。

除了命令行交互和脚本编写,PowerShell 还支持远程管理,允许用户通过网络远程执行命令和脚本,从而方便管理远程计算机和服务器。

综上所述,PowerShell 是一种功能强大的命令行 shell 和脚本语言,适用于 Windows 平台上的系统管理、自动化任务和脚本开发。无论是在个人电脑上进行日常管理,还是在企业环境中进行系统管理和自动化运维,PowerShell 都是一个非常有用的工具。

PowerShell 和 Linux 的 Shell(如 Bash)在某些方面有相似之处,但也存在一些区别。以下是一些主要区别的概述:

  1. 平台:PowerShell 是针对 Windows 平台开发的,而 Linux 的 Shell 是为 Linux 和其他类 Unix 系统设计的。因此,它们运行在不同的操作系统上,并针对各自平台提供特定的功能和命令。

  2. 语法:PowerShell 和 Linux Shell 在语法上有一些不同。PowerShell 使用基于对象的命令和管道,通过处理和传递对象来实现数据处理。它的语法更接近编程语言,支持面向对象的概念和.NET 框架。相比之下,Linux Shell 使用基于文本的命令和管道,通过处理和传递文本流来实现数据处理。

  3. 命令和工具:PowerShell 和 Linux Shell 提供了不同的命令和工具集。虽然它们都具有基本的文件和目录操作命令,如 cdlsmkdirrm,但具体的命令和选项可能不同。此外,PowerShell 还提供了与 Windows 相关的命令和功能,如处理注册表、管理 Active Directory 等。

  4. 脚本编程:PowerShell 和 Linux Shell 都支持脚本编程,但有一些语法和特性上的差异。PowerShell 使用 .NET 框架,并提供了强大的对象处理和面向对象编程的能力。它还具有异常处理、事件处理和模块化等高级编程功能。Linux Shell 则更加注重文本处理和管道操作,并提供了丰富的命令和工具来支持 Shell 脚本编程。

  5. 生态系统和社区:Linux Shell(特别是 Bash)在 Linux 和类 Unix 系统中得到广泛应用,并拥有庞大的用户社区和丰富的第三方工具和脚本资源。PowerShell 的生态系统和社区在 Windows 平台上也逐渐发展壮大,但与 Linux Shell 相比较而言,它相对较新且规模较小。

需要注意的是,随着 PowerShell 的发展,它在某些方面与 Linux Shell 之间的差距正在缩小。例如,PowerShell 已经增加了对跨平台的支持,可以在 Linux 和 macOS 上运行,并且越来越多的 Linux 命令和工具适配到了 PowerShell 上。总的来说,Shell 是一种强大的命令行界面和脚本编程语言,它在计算机系统管理和自动化任务方面发挥着重要的作用。通过编写 Shell 脚本,用户可以提高工作效率,并实现自动化的系统管理和任务处理。

2、Shell脚本

Shell 脚本是一种在 Shell 环境下编写的脚本程序,用于自动化执行一系列的命令和任务。通过编写 Shell 脚本,可以将多个命令组合在一起,实现复杂的系统管理和任务处理。脚本可以根据需要进行参数化,并具有灵活性和可重复性,提高了工作效率和一致性。

创建Sell的流程:

  1. 选择 Shell:首先确定要使用的 Shell。在大多数 Linux 和 macOS 系统上,Bash 是默认的 Shell,也是最常用的选择。在 Windows 上,可以使用 PowerShell 或其他可用的 Shell。

  2. 创建脚本文件:使用文本编辑器创建一个新文件,命名为脚本文件,并以特定的扩展名结尾(如 .sh.bash)。例如,my_script.sh

  3. 添加脚本声明:在脚本文件的第一行添加脚本声明,指定要使用的 Shell。例如,对于 Bash,可以在第一行添加 #!/bin/bash

  4. 编写脚本内容:在脚本文件中编写要执行的命令和任务。可以使用 Shell 的语法和特性,如变量、条件语句、循环、函数等。脚本可以包含任意数量的命令和控制结构,以实现所需的功能。

  5. 保存脚本文件:保存脚本文件,并确保它具有可执行权限。在终端中,可以使用 chmod +x my_script.sh 命令为脚本文件添加执行权限。

  6. 运行脚本:在终端中,使用以下命令运行脚本:./my_script.sh。这将执行脚本文件中的命令,并按照编写的逻辑进行处理。

#! /bin/bash      (shell脚本第一行必须写上,是明确用什么语言来解释脚本!如果不写默认用 /bin/bash)
# 这是一个简单的 Shell 脚本示例
# 该脚本用于列出指定目录下的所有文件和目录,并统计它们的数量

# 设置要列出的目录
directory="/path/to/directory"

# 统计文件和目录的数量
file_count=0
directory_count=0

# 遍历目录下的所有文件和目录
for item in "$directory"/*; do
    if [ -f "$item" ]; then
        # 文件
        file_count=$((file_count + 1))
    elif [ -d "$item" ]; then
        # 目录
        directory_count=$((directory_count + 1))
    fi
done

# 输出统计结果
echo "文件数量:$file_count"
echo "目录数量:$directory_count"

1、Sell 数据类型

  • 字符串(String):字符串是 Shell 脚本中最常用的数据类型,用于表示文本或字符序列。可以使用单引号或双引号来定义字符串,例如 'Hello'"World"。Shell 脚本中的字符串可以进行拼接、截取、替换等操作。

  • 整数(Integer):Shell 脚本中的整数数据类型是没有明确的类型声明的,可以直接在变量中存储整数值。例如,num=10。对于整数运算,Shell 提供了一些算术运算符,如加法、减法、乘法等。

  • 浮点数(Floating Point):Shell 脚本默认不直接支持浮点数运算,但可以使用一些工具和技巧来实现浮点数计算,例如使用 bc 命令或利用 Shell 内置的数学函数。

  • 数组(Array):Shell 脚本中的数组用于存储一组相关的值。可以使用一对圆括号来定义数组,例如 array=("apple" "banana" "orange")。数组可以根据索引访问和修改其中的元素,也可以遍历数组进行处理。

  • 布尔值(Boolean):Shell 脚本中没有直接的布尔数据类型,通常使用整数来表示布尔值。约定一般将 0 视为假(false),非零值视为真(true)。在条件判断和逻辑运算中,可以使用布尔值来控制流程和判断条件。

2、变量定义

直接赋值:通过使用等号(=)将值赋给变量来定义变量。等号两边不能有空格。例如:

name="John"
age=25

命令输出赋值:可以使用命令替换语法($(command) 或者 command)来将命令的输出结果赋给变量。例如:

current_date=$(date +%Y-%m-%d)
files_count=$(ls -l | wc -l)

环境变量赋值:可以将环境变量的值赋给变量。例如:

home_dir=$HOME
path_var=$PATH

通过参数传递:可以通过命令行参数将值传递给脚本,并将其赋给变量。例如:

# 假设脚本名为 my_script.sh
# 运行脚本时可以传递参数,如:./my_script.sh argument1 argument2

arg1=$1  # 第一个参数
arg2=$2  # 第二个参数

echo "参数1: $arg1"
echo "参数2: $arg2"

需要注意的是,变量名是区分大小写的,并且不能以数字开头。另外,定义变量时,最好避免使用 Shell 保留的特殊字符和关键字,以免引起问题。

可以通过使用 $ 符号来引用变量的值。 例如,echo $name 将输出变量 name 的值。

在 Shell 脚本中,变量默认被视为字符串类型。如果需要进行数值运算,可能需要进行类型转换或使用适当的数值运算操作。

3、变量的作用域

在 Shell 脚本中,存在两种主要的变量作用域:

  1. 全局作用域(Global Scope):在脚本的任何地方定义的变量都具有全局作用域,可以在脚本的任何位置访问和修改这些变量。全局变量可以在整个脚本中使用,包括脚本的各个函数和代码块。如果在函数内部使用 global 关键字声明变量,则可以将其声明为全局变量。

示例:

#!/bin/bash

global_var="Global Variable"  # 全局变量

my_function() {
    local local_var="Local Variable"  # 局部变量

    echo "在函数内部访问全局变量:$global_var"
    echo "在函数内部访问局部变量:$local_var"
}

echo "在脚本中访问全局变量:$global_var"
my_function

这个例子中,global_var 是一个全局变量,在整个脚本中都可见。函数 my_function 中的 local_var 是一个局部变量,只在函数内部可见。在函数内部和脚本中都可以访问和使用全局变量。

局部作用域(Local Scope):在函数内部定义的变量具有局部作用域,只能在函数内部访问和修改。这些变量在函数外部是不可见的。

示例:

#!/bin/bash

my_function() {
    local local_var="Local Variable"  # 局部变量

    echo "在函数内部访问局部变量:$local_var"
}

my_function

echo "在脚本中无法访问局部变量:$local_var"

这个例子中,local_var 是在函数内部定义的局部变量,只能在函数内部访问。在函数外部是不可见的。

在 Shell 中,父 Shell 和子 Shell 之间存在一定的变量作用域关系。一般情况下,子 Shell 无法直接访问或修改父 Shell 中的变量。以下是一些常见情况:

  1. 子 Shell 继承父 Shell 的环境变量:当创建子 Shell 时,子 Shell 会继承父 Shell 的环境变量。这意味着子 Shell 可以访问和使用父 Shell 中已经设置的环境变量。

  2. 子 Shell 无法直接访问父 Shell 中的普通变量:普通变量在父 Shell 中定义,子 Shell 默认无法直接访问或修改这些变量。每个 Shell 进程都有自己的变量空间。

  3. 使用导出(export)来传递变量给子 Shell:通过使用 export 命令,可以将父 Shell 中的变量导出为环境变量,从而使得子 Shell 可以访问和使用这些变量。

  4. 子 Shell 可以使用命令替换或参数传递获取父 Shell 的值:子 Shell 可以通过命令替换或参数传递的方式,获取父 Shell 中的值,并将其赋给子 Shell 中的变量。

parent_var="Parent Variable"
export parent_var

# 在子 Shell 中访问父 Shell 的变量
echo "在子 Shell 中访问父 Shell 的变量:$parent_var"

需要注意的是,当子 Shell 结束后,其所做的任何变量更改都不会影响父 Shell。子 Shell 的变量更改只在子 Shell 的生命周期内有效。

4、单双引号与反引号

  1. 单引号('):

    • 单引号用于创建字符串字面值,其中的内容会被原样输出,不进行变量扩展、命令替换和转义字符处理。这意味着在单引号内部,变量名、特殊字符和命令替换都不会被解释,而被视为普通字符。例如:echo 'Hello $NAME' 会输出 Hello $NAME,而不会替换变量 NAME 的值。
    • 单引号内部可以包含双引号和反引号,它们不会被解释,而是作为普通字符对待。例如:echo 'I have "double quotes" in this string' 会输出 I have "double quotes" in this string
  2. 双引号("):

    • 双引号用于创建字符串字面值,其中的变量扩展、命令替换和转义字符会被解释和处理。在双引号内部,变量会被替换为其对应的值,命令替换会执行替换后的命令并将结果插入到字符串中,转义字符会被解释为特殊字符。例如:echo "Hello $NAME" 会根据变量 NAME 的值进行替换。
    • 双引号内部也可以包含单引号和反引号,它们会被解释为特殊字符。例如:echo "I'm using single quotes in this string" 会输出 I'm using single quotes in this string
  3. 反引号(`):

    • 反引号用于执行命令替换。将命令包裹在反引号内部,Shell 会执行该命令,并将其输出结果插入到反引号的位置。例如:echo "Today is date" 会将 date 命令的输出结果插入到字符串中。

需要注意的是,反引号在某些上下文中已被弃用,推荐使用 $() 语法进行命令替换,例如:echo "Today is $(date)"

综上所述,单引号、双引号和反引号在 Shell 中具有不同的用途和行为,可以根据具体的需求选择合适的引号来处理字符串和命令。

5、环境变量

在 Shell 中,可以通过设置环境变量来影响 Shell 进程和其子进程的行为。下面是关于环境变量的一些重要信息:

  1. 查看环境变量:

    • 在 Linux 和 macOS 的 Shell 中,可以使用 echo $变量名echo ${变量名} 来查看环境变量的值。例如:echo $PATH 查看 PATH 环境变量的值。

    • 在 Windows 的 CMD 中,可以使用 echo %变量名% 来查看环境变量的值。例如:echo %PATH% 查看 PATH 环境变量的值。

  2. 系统预定义环境变量:

    • 操作系统会预定义一些常用的环境变量,例如:
      • PATH:指定可执行程序的搜索路径。
      • HOME(在 Linux 和 macOS 中)或 USERPROFILE(在 Windows 中):指定用户的主目录路径。
      • USER(在 Linux 和 macOS 中)或 USERNAME(在 Windows 中):指定当前登录用户的用户名。
    • 这些预定义环境变量的名称和含义可能会因操作系统而异。
  3. 自定义环境变量:

    • 可以在 Shell 中定义自己的环境变量,用于存储自定义配置信息或其他需要在程序中使用的值。
    • 在 Linux 和 macOS 的 Shell 中,可以使用 export 变量名=值变量名=值 来定义环境变量。例如:export MY_VAR="Hello"MY_VAR="Hello"
    • 在 Windows 的 CMD 中,可以使用 set 变量名=值 来定义环境变量。例如:set MY_VAR="Hello"
  4. 环境变量的传递和继承:

    • 子 Shell 进程会继承父 Shell 的环境变量。也就是说,子进程可以访问和使用父进程中已定义的环境变量。
    • 修改父 Shell 中的环境变量不会影响已经启动的子 Shell 进程,但对新的子 Shell 进程是可见的。

6、检查系统环境变量的命令

  1. Linux 和 macOS 上的命令:

    • env:这个命令会显示当前用户的所有环境变量,包括用户自定义的和系统预定义的变量。

    • printenv:与 env 命令类似,它也会显示当前用户的所有环境变量。

  2. Windows 上的命令:

    • set:这个命令会显示当前用户的所有环境变量,包括用户自定义的和系统预定义的变量。
    • echo %变量名%:使用该命令可以查看特定环境变量的值。将 “变量名” 替换为要查看的环境变量名称。

这些命令将列出当前用户的环境变量及其对应的值。如果你希望查看全局的系统环境变量(对所有用户有效),则需要具有管理员权限或以管理员身份运行命令。

需要注意的是,环境变量的输出可能会非常长,特别是在 Windows 系统中。你可以使用输出重定向来将结果导出到文件进行查看,例如 env > 环境变量.txtset > 环境变量.txt。这将把环境变量输出到名为 “环境变量.txt” 的文件中,你可以使用文本编辑器打开并查看其中内容。

7、环境变量的初始化与加载顺序

环境变量的初始化和加载顺序可能会因操作系统和 Shell 的类型而有所不同。下面是一般情况下环境变量的初始化和加载顺序的概述:

  1. 初始化顺序:

    • 操作系统会首先加载系统级别的环境变量。这些环境变量是在操作系统启动时设置的,通常包括一些系统路径、全局配置等。
    • 然后,Shell 进程会启动并加载用户级别的环境变量。这些环境变量是在用户登录时或启动 Shell 时设置的,可以包括用户自定义的变量、路径等。
  2. 加载顺序:

    • Shell 进程会按照一定的顺序加载环境变量。典型的加载顺序如下(以 Bash 为例):
      • 登录 Shell 的加载顺序:
        1. /etc/profile:系统级别的全局配置文件,对所有登录用户生效。
        2. ~/.bash_profile:当前用户的个人登录配置文件,仅对当前用户生效。
        3. ~/.bash_login:如果 ~/.bash_profile 不存在,则加载该文件。
        4. ~/.profile:如果 ~/.bash_profile~/.bash_login 都不存在,则加载该文件。
      • 非登录 Shell 的加载顺序:
        1. /etc/bash.bashrc:系统级别的全局非登录 Shell 配置文件。
        2. ~/.bashrc:当前用户的个人非登录 Shell 配置文件。

    注意:加载顺序可能会因操作系统和用户配置而有所不同。一些 Shell 还支持其他配置文件,例如 Zsh 的 ~/.zshrc

在加载环境变量时,后续加载的配置文件可以覆盖前面加载的配置文件中的相同变量。这意味着,在后续的配置文件中定义的变量值将取代先前的定义。

需要注意的是,对于已经启动的 Shell 进程,修改环境变量的配置文件不会立即生效。你需要重新启动 Shell 或使用特定的命令来加载新的环境变量设置,例如 source ~/.bashrc(对 Bash)或 source ~/.zshrc(对 Zsh)。

8、配置文件

  1. Bash 的配置文件:

    • ~/.bashrc:用于每次启动一个新的交互式 Bash Shell 时加载的配置文件。可以在这里设置自定义的别名、环境变量、命令行提示符等。
    • ~/.bash_profile:用于登录 Bash Shell 时加载的配置文件。在登录过程中,通常只会加载一次该文件。可以在这里设置与登录 Shell 相关的配置,例如添加环境变量、执行一些初始化命令等。
    • ~/.bash_login:类似于 ~/.bash_profile,在登录 Bash Shell 时加载。
    • ~/.profile:在登录 Shell 时加载的通用配置文件,适用于多种类型的 Shell,不仅限于 Bash。
  2. Zsh 的配置文件:

    • ~/.zshrc:用于每次启动一个新的交互式 Zsh Shell 时加载的配置文件。可以在这里设置别名、环境变量、插件等。
    • ~/.zshenv:在每次启动 Zsh 时加载的配置文件,无论是交互式还是非交互式 Shell。可以在这里设置全局的环境变量。
  3. 其他 Shell 的配置文件:

    • 不同的 Shell 可能有不同的配置文件名称和用法。例如,C Shell 使用 ~/.cshrc,Korn Shell 使用 ~/.kshrc

9、特殊变量

  • $0:表示当前脚本或程序的名称。在Shell脚本中,它表示脚本本身的名称。
  • $1, $2, …:表示命令行参数(或函数参数)中的位置参数。$1 表示第一个参数,$2 表示第二个参数,以此类推。例如,在Shell脚本中,$1 表示脚本的第一个命令行参数。
  • ** @ ? ? :表示所有命令行参数的列表。它以列表的形式提供了所有位置参数。在 S h e l l 脚本中,可以使用 " @**:表示所有命令行参数的列表。它以列表的形式提供了所有位置参数。在Shell脚本中,可以使用" @??:表示所有命令行参数的列表。它以列表的形式提供了所有位置参数。在Shell脚本中,可以使用"@"来遍历所有命令行参数。
  • **KaTeX parse error: Expected 'EOF', got '#' at position 1: #?**:表示命令行参数的数量。在…#"获取传递给脚本的参数个数。
  • $?:表示上一个命令的退出状态码。通常,0表示成功,非零值表示失败或错误。
  • $$:表示当前进程的进程ID(PID)。
  • ** ! ? ? :表示最近一个在后台运行的进程的进程 I D 。在 S h e l l 脚本中,可以使用 " !**:表示最近一个在后台运行的进程的进程ID。在Shell脚本中,可以使用" !??:表示最近一个在后台运行的进程的进程ID。在Shell脚本中,可以使用"!"来获取后台进程的PID。
  • $_:表示上一个命令的最后一个参数。在Shell脚本中,它表示之前执行的命令的最后一个参数。
  • __**KaTeX parse error: Expected group after '_' at position 1: _?_:表示所有命令行参数的字符串…"来获取所有命令行参数的字符串。
  • $IFS:表示内部字段分隔符(Internal Field Separator)。它定义了Shell如何将字符串分割成字段。默认情况下,IFS 的值包括空格、制表符和换行符。
  • $PWD:表示当前工作目录(当前所在的目录)的路径。
  • $LANG:表示当前系统的语言环境。
  • $SHELL:表示当前用户所使用的默认Shell的路径。
  • $RANDOM:表示一个随机数。
  • $EDITOR:表示默认的文本编辑器。
  • $PATH:表示系统用于查找可执行文件的路径列表。它是一个包含多个目录路径的字符串,当你输入一个命令时,系统会在这些路径中搜索对应的可执行文件。
  • $HOME:表示当前用户的主目录路径。它是用户的个人文件和配置的默认位置。例如,在Linux系统中,/home/username 是用户的主目录路径。
  • $USER:表示当前用户名。
  • $UID:表示当前用户的用户ID(User ID)。
  • $GID:表示当前用户的组ID(Group ID)。
  • $HOSTNAME:表示当前主机的主机名。
  • $PS1:表示命令行提示符(Prompt String)。它定义了Shell提示符的格式和内容。
  • $OLDPWD:表示之前的工作目录(上一个工作目录)的路径。
  • $SECONDS:表示Shell脚本或会话运行的秒数。它可以用于计时操作。
文章来源:https://blog.csdn.net/Raymend_Lee/article/details/135316494
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。