Bootstrap

Linux常用命令之set命令详解

set 命令在 Linux 和 Unix 系统中是一个非常强大且多功能的内置命令,主要用于设置 shell 的执行选项和控制脚本的行为。它不仅可以用来启用或禁用特定的 shell 特性,还可以用于显示所有 shell 变量及其值。

基本语法:

set [option] [argument...]

常见的用法说明:

  • 不带任何参数的 set:当不提供任何参数时,set 将打印当前 shell 环境中所有变量(包括环境变量)和函数的定义。

  • 设置或取消 shell 选项

    • 使用 - 开头的选项来启用某些行为。
    • 使用 + 开头的相同选项来禁用这些行为。

    例如:

    set -o option_name  # 启用某个选项
    set +o option_name  # 禁用某个选项
    
  • 指定位置参数

    • 可以直接跟一系列参数来设置位置参数 $1, $2, …。
    • 这对于脚本编写特别有用,可以模拟传递给脚本的参数。

    例如:

    set -- arg1 arg2 arg3
    echo $1  # 输出: arg1
    echo $2  # 输出: arg2
    
  • 显示选项状态

    • 使用 -o+o 来列出所有可用的选项及其当前状态。

    例如:

    set -o    # 显示所有选项及它们是否开启
    set +o    # 同上,但使用的是加号而不是减号
    
  • 设置内置命令路径查找

    • 使用 -h+h 来控制是否自动将命令名添加到哈希表中,以便快速查找。

    例如:

    set -h    # 开启命令哈希
    set +h    # 关闭命令哈希
    
  • 调试模式

    • 使用 -x 来启用调试模式,这会使 shell 在执行每个命令之前先打印出来。
    • 使用 +x 来关闭调试模式。

    例如:

    set -x    # 开启调试模式
    set +x    # 关闭调试模式
    

常用选项

set 命令可以通过添加不同的选项来改变 shell 的行为。每个选项前面可以加上连字符 - 表示开启该特性,或者加上加号 + 表示关闭该特性。

  • -a:自动导出所有新创建或修改过的变量到环境中。
  • -e:如果任何命令返回非零退出状态(即失败),则立即终止 shell 或脚本的执行。这对于确保脚本在遇到错误时不继续运行非常重要。
  • -f:禁止文件名扩展(通配符匹配)。这意味着像 *? 这样的字符将不会被解释为通配符。
  • -u:当尝试访问未定义的变量时产生错误信息并停止执行。这有助于捕获潜在的问题,避免因误用变量而导致意外行为。
  • -x:开启跟踪模式,在执行每一条命令之前先打印出来。这对调试特别有帮助,因为它可以让您清楚地看到实际发生了什么操作。
  • -C:防止重定向覆盖现有文件。
  • -H:启用历史扩展。
  • -m:开启作业控制,允许在后台运行多个任务,并能方便地管理这些任务。
  • -n:读取脚本但不执行它们,仅检查语法错误。
  • -t:执行一个命令后退出。
  • -v:在读入每一行之后立即将其打印出来。
  • -o:以长格式显示或设置某些选项。例如,set -o errexit 等同于 set -e

设置位置参数

除了配置 shell 行为外,set 命令还能够重新设置位置参数(positional parameters),即 $1, $2, …, $n。这对于编写更加灵活的脚本来说是非常有用的。例如:

set -- "first argument" "second argument" "third argument"
echo $1 # 输出: first argument
echo $2 # 输出: second argument

上述代码段中,set -- 后面跟着的是新的位置参数列表,这样就可以动态地改变传递给脚本或函数的位置参数。

清除所有函数定义

使用 set 命令还可以清除所有的函数定义,只需要指定 -- 作为参数即可。例如:

set --

这将清除所有已定义的函数,使它们不再可用。

定义新变量

需要注意的是,set 命令本身并不用于直接定义新的 shell 变量。相反,应该使用赋值语句(例如 VAR=value)或者 declare 命令来进行这项工作。一旦定义了变量,就可以使用 export 命令将其添加到环境变量列表中,使之对子进程可见。

例如,要定义一个名为 mylove 的新环境变量并将其值设为 “meinv”,您可以这样做:

declare mylove='meinv' # 定义新变量
export mylove           # 将其导出为环境变量

之后,可以通过 env | grep mylove 来验证是否成功添加了这个环境变量。

实际应用示例

场景:正在编写一个复杂的 shell 脚本,并希望其中一个步骤失败了,整个脚本不会继续执行下去,从而防止可能引发更严重后果的情况发生。在这种情况下,可以在脚本顶部加入以下行:

#!/bin/bash
set -euo pipefail

这里的 -e 确保了只要有任何命令失败就会立刻退出;-u 检查是否存在未初始化的变量引用;而 pipefail 则保证管道中的每一个命令都会影响最终的状态码,而不是仅仅依赖于最后一个命令的结果。

显示所有Shell变量和函数

  1. 显示所有当前shell中的变量和函数定义
    set
    

设置Shell选项

  1. 启用调试模式(打印每个命令之前执行)

    set -x
    
  2. 禁用调试模式

    set +x
    
  3. 使脚本在遇到未定义变量时退出

    set -u
    
  4. 当任何命令返回非零退出状态时立即退出

    set -e
    
  5. 如果命令扩展结果为空,则将之视为错误

    set -o pipefail
    
  6. 设置交互式模式(仅在交互式shell中有意义)

    set -i
    
  7. 启用job控制

    set -m
    
  8. 禁止文件名生成(通配符展开)

    set -f
    
  9. 禁止函数名继承

    set -n
    

设置位置参数

  1. 为位置参数赋值

    set -- arg1 arg2 arg3
    
  2. 使用命令替换的结果作为位置参数

    set -- $(echo one two three)
    

设置Shell变量

  1. 设置或重置Shell变量
    set VAR=value
    

使用set与数组

  1. 将数组元素设置为位置参数
    arr=("one" "two" "three")
    set -- "${arr[@]}"
    

从文件读取设置

  1. 从文件中读取命令并执行
    set -a
    source /path/to/file
    set +a
    

其他用途

  1. 显示简短的选项列表

    set -o
    
  2. 检查是否设置了某个选项

    shopt -q option_name
    
  3. 设置内置命令的查找路径

    set -o hashall
    
  4. 忽略不存在的命令而不报错

    set -o noclobber
    
  5. 设置历史记录相关选项

    set -o history
    

注意,上述命令的行为可能会根据所使用的具体 shell(如 bash, zsh, ksh 等)而有所不同。例如,在某些 shell 中,set -o 可以用来查看或设置特定的 shell 选项,而在其他 shell 中,可能需要使用不同的语法来达到同样的效果。此外,一些选项可能是特定于某些 shell 的。
在实际使用中,请参考对应 shell 的文档获取最准确的信息。对于 Bash 特定的功能,可以查阅 Bash 手册页 (man bash) 或者在线文档。

;