楼主: Irene6986
176 0

[作业] shell编程规范与变量 [推广有奖]

  • 0关注
  • 0粉丝

等待验证会员

小学生

42%

还不是VIP/贵宾

-

威望
0
论坛币
1000 个
通用积分
0
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
50 点
帖子
4
精华
0
在线时间
0 小时
注册时间
2018-9-11
最后登录
2018-9-11

楼主
Irene6986 发表于 2025-11-21 19:19:04 |AI写论文

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币

1.1 Shell 脚本简介

1.1.1 Shell 的功能与角色

Shell 是 Linux 和 Unix 系统中的命令行解释器,作为用户与操作系统内核之间的交互桥梁。其主要职责包括:
  • 接收用户输入的指令,解析后提交给系统内核执行;
  • 将内核处理的结果通过 Shell 反馈至用户界面;
  • 支持脚本编写和批量命令运行,广泛应用于自动化运维、定时任务管理及系统部署等场景。
常见的 Shell 类型有:
/bin/bash
:目前大多数 Linux 发行版默认使用的 Shell,具备强大功能且兼容性良好;
/bin/sh
:轻量级 Shell,某些系统中为 bash 的符号链接; 此外还有
zsh
csh
等,它们在语法或功能上有所扩展或差异。

1.1.2 编写首个 Shell 脚本

Shell 脚本本质上是一个包含多条命令的纯文本文件,需遵循特定结构规范: - 文件首行应声明所用解释器,例如:
#!/bin/bash

此语句指示系统使用 bash 解释器运行该脚本。 - 注释以
#
开头,仅支持单行注释;若需多行注释,可通过块注释方式模拟(如结合 : ' 和
: '注释内容'
)。 - 脚本文件必须赋予执行权限,否则无法直接运行,设置方法为:
chmod +x 脚本名
- 命令按顺序逐行书写,后续章节将介绍逻辑控制结构的应用。 示例:hello.sh 脚本内容
#!/bin/bash
# 这是我的第一个Shell脚本(单行注释)
: '
以下是多行注释内容:
功能:输出欢迎信息和系统时间
作者:XXX
日期:2025-11-20
'

echo "Hello, Shell!"  # 输出字符串
echo "当前系统时间:$(date)"  # 嵌入命令执行结果($() 或 `` 都可)
执行方式如下:
  1. 直接执行(需事先添加执行权限):
    chmod +x hello.sh  # 添加执行权限(仅需一次)
    ./hello.sh         # 必须加 ./(当前目录),否则系统会在PATH中查找
  2. 通过解释器调用执行(无需执行权限):
    bash hello.sh  # 或 sh hello.sh(若脚本兼容sh)
  3. source 方式执行(命令在当前 Shell 环境中运行,而非子进程):
    source hello.sh  # 或 . hello.sh(注意点后有空格)

1.1.3 输入输出重定向与管道机制

在默认情况下,每个命令都关联三个标准数据流:
  • 标准输入(stdin):通常来自键盘,文件描述符为 0;
  • 标准输出(stdout):输出至屏幕,文件描述符为
    1
  • 标准错误输出(stderr):错误信息也显示在屏幕上,文件描述符为
    2
通过重定向和管道操作,可以改变这些数据流的方向,实现更灵活的数据处理与命令协作。

1. 重定向操作详解

操作符 作用说明 示例
>
将标准输出重定向并覆盖指定文件(若文件不存在则创建)
ls > file.txt

(将 ls 结果写入 file.txt,原内容被覆盖)
>>
将标准输出追加到文件末尾
echo "new line" >> file.txt
2>
将标准错误输出重定向并覆盖文件
find / -name "test" 2> error.log

(忽略权限不足产生的错误提示)
2>>
将标准错误输出追加至文件
command 2>> error.log
&>
/
>&
同时重定向标准输出和标准错误输出(覆盖模式)
./script.sh &> result.log
&>>
同时追加重定向 stdout 与 stderr
./script.sh &>> result.log
<
从文件读取标准输入,代替键盘输入
wc -l < file.txt

(统计文件行数,等效于 wc -l file.txt)
<< EOF
Here Document:嵌入多行文本输入,EOF 可自定义结束标记
cat > test.txt << EOF

(输入多行内容,以 EOF 为终止符)
Here Document 使用示例:
# 向file.txt写入多行内容
cat > file.txt << EOF
第一行内容
第二行内容
第三行:$(date)  # 支持嵌入命令
EOF

2. 管道操作(
|

管道用于将前一个命令的标准输出作为下一个命令的标准输入,从而实现多个命令的串联处理。需要注意的是,管道仅传递 stdout,stderr 不会自动传递,如需转发需显式使用
2>&1
基本语法:
command1 | command2 | command3 ...
常见应用场景:
  • 统计当前目录下文件数量:
    ls -l | wc -l  # ls -l输出文件列表,wc -l统计行数(含目录总行数)
  • 筛选包含 “error” 关键字的日志行:
    cat app.log | grep "error"  # grep 过滤关键字
  • 对输出结果排序并去除重复项:
    cat numbers.txt | sort | uniq -c  # sort排序,uniq -c 统计重复次数
  • 将错误信息也送入管道进行处理:
    find / -name "test" 2>&1 | grep "Permission"  # 过滤权限错误信息

1.2 Shell 变量的概念与分类

变量是 Shell 中用于存储数据的基本单元,可用于保存字符串、数值等信息,在脚本中实现动态赋值与重复引用。

1.2.1 用户自定义变量

这类变量由用户自行创建、修改和使用,默认作用范围限于当前脚本或 Shell 会话。

1. 定义新变量

语法格式为:
变量名=值

注意:等号两侧不能留空格。 命名规则:
  • 只能由字母、数字和下划线组成,且不能以数字开头;
  • 区分大小写,例如
    NAME
    name
    视为两个不同变量;
  • 建议采用全大写字母命名,以符合通用规范,并避免与系统预设变量冲突。
示例:
NAME="Zhang San"  # 字符串值可加引号(推荐,避免空格等特殊字符问题)
AGE=25            # 数值型变量无需加引号
SCORE=95.5        # 支持浮点数(但Shell默认不支持浮点运算,需借助bc)
FILE_PATH="/home/user/file.txt"  # 路径变量

2. 查看与引用变量值

查看变量内容可使用:
echo $变量名
echo ${变量名}

其中
{}
可明确界定变量边界,防止解析歧义。 引用变量时使用:
$变量名
${变量名}

可在双引号字符串中直接嵌入变量值。 示例:
NAME="Li Hua"
echo $NAME          # 输出:Li Hua
echo "姓名:${NAME}" # 输出:姓名:Li Hua(推荐用{},边界清晰)

# 避免歧义示例
echo "Hello${NAME}World"  # 正确:HelloLi HuaWorld
echo "Hello$NAMEWorld"    # 错误:Shell会认为变量是NAMEWorld(未定义,输出Hello)

3. 特殊赋值方式

赋值方式 功能说明 示例
空值赋值 将变量设为空字符串
EMPTY=
EMPTY=""
取消变量 使用 unset 命令删除已定义的变量
unset NAME

(执行后 $NAME 不再有输出)
从命令输出赋值 利用 $() 或 `` 捕获命令执行结果(推荐使用 $(),更具可读性和嵌套兼容性)
DATE=$(date +"%Y-%m-%d")

(获取当前日期时间)
从文件内容赋值 通过 $(cat 文件名) 读取整个文件内容
CONTENT=$(cat file.txt)
条件赋值(${} 扩展语法) 当变量未定义或为空时,提供默认值(不影响原变量)
${VAR:-默认值}

(仅在访问时使用默认值,VAR 本身不变)

变量不存在或为空时的默认值设置与修改

当变量未定义或其值为空时,可通过特定语法为其赋予默认值,并实现对变量 VAR 的更新操作。

${VAR:=默认值}

(永久性修改 VAR)

示例:条件赋值操作

# 场景:若未定义USER,默认使用"guest"
echo ${USER:-guest}  # 若USER已定义(如root),输出root;否则输出guest

# 场景:若未定义AGE,设置AGE=18并使用
echo ${AGE:=18}      # 若AGE未定义,输出18且AGE变量被设为18;已定义则输出原值

变量作用域的配置方法

在默认情况下,用户自定义的变量仅在当前 Shell 环境或脚本中有效。这意味着子 Shell(例如由脚本启动的子进程、管道符后的命令等)无法访问这些变量。

通过使用以下方式,可将普通变量升级为环境变量,使其能够在子进程中被继承和使用:

export
  • 临时生效(限于当前会话):
    • export 变量名
    • export 变量名=值
  • 永久生效:
    • 全局范围(所有用户): 修改系统级配置文件
      /etc/profile
      /etc/environment
      ,并在其中添加
      export 变量名=值
    • 当前用户专用: 编辑用户级配置文件
      ~/.bashrc
      ~/.bash_profile
      ,并加入
      export 变量名=值
  • 使配置立即生效:
    • 执行
      source /etc/profile
      source ~/.bashrc
      ,无需重启当前 Shell 即可加载新设置。
  • 示例:环境变量的实际设置过程

    # 临时设置环境变量(当前Shell及子Shell生效)
    export JAVA_HOME="/usr/local/jdk"
    export PATH="$PATH:$JAVA_HOME/bin"  # 追加PATH路径
    
    # 永久设置(当前用户)
    echo 'export JAVA_HOME="/usr/local/jdk"' >> ~/.bashrc
    echo 'export PATH="$PATH:$JAVA_HOME/bin"' >> ~/.bashrc
    source ~/.bashrc  # 立即生效

    数值计算处理(借助 bc 工具)

    Shell 原生仅支持整数运算,通常通过

    $((...))
    expr
    实现。对于浮点数运算或更复杂的数学操作(如四则混合运算、三角函数等),需要依赖外部工具
    bc
    (该工具为 Linux 系统自带,若缺失需通过
    yum install bc
    安装)。

    (1)整数运算的两种方式

    方式一:

    $(( 表达式 ))

    推荐使用此法,语法简洁清晰。

    a=10
    b=5
    echo $((a + b))  # 15
    echo $((a - b))  # 5
    echo $((a * b))  # 50(注意:* 无需转义)
    echo $((a / b))  # 2(整数除法,舍去小数)
    echo $((a % b))  # 0(取余)
    echo $((a++))    # 10(先使用后自增)
    echo $((++a))    # 12(先自增后使用)

    方式二:

    expr 表达式

    注意:运算符前后必须有空格,且乘号 * 需进行转义处理。

    expr 10 + 5  # 15
    expr 10 \* 5 # 50(* 必须转义)

    (2)浮点数及复杂运算(使用 bc 工具)

    基本语法格式为:

    echo "表达式" | bc

    常用参数说明:

    • -l
      :启用数学库,支持浮点运算、三角函数、对数等高级功能;
    • scale=N
      :设定小数点后保留位数(默认为 0,即只输出整数部分)。

    示例:

    # 浮点数加法(保留2位小数)
    echo "scale=2; 3.14 + 2.86" | bc  # 6.00
    
    # 浮点数乘法
    echo "1.2 * 3.4" | bc  # 4.08(未加-l,仍支持基础浮点)
    
    # 三角函数(需加-l加载数学库,弧度制)
    echo "scale=4; sin(3.1416/2)" | bc -l  # 1.0000(sin(π/2)=1)
    
    # 变量参与计算
    x=5.5
    y=2.2
    echo "scale=1; $x / $y" | bc  # 2.5

    1.2.2 特殊 Shell 变量类型

    这类变量由 Shell 内部预先定义,无需手动创建,主要用于获取系统状态、脚本输入参数、命令执行结果等关键信息。

    1. 环境变量

    系统预设的一类变量,用于控制 Shell 行为和程序运行环境,命名通常采用全大写形式。可通过

    env
    printenv
    查看全部环境变量列表。

    变量名 作用说明 示例
    PATH
    指定命令搜索路径(即可执行程序所在的目录列表)
    echo $PATH
    (输出示例:/usr/bin:/bin:...)
    HOME
    表示当前用户的主目录路径
    echo $HOME
    (输出示例:/home/user)
    USER
    记录当前登录系统的用户名
    echo $USER
    (输出:root 或 user)
    UID
    当前用户的 UID(用户标识号,root 用户为 0)
    echo $UID
    (输出:0 或 1000)
    PWD
    当前工作目录的完整路径
    echo $PWD
    (输出:/home/user/work)
    SHELL
    正在使用的 Shell 解释器路径
    echo $SHELL
    (输出:/bin/bash)
    LANG
    系统语言与字符编码设置
    echo $LANG
    (输出:zh_CN.UTF-8)
    $?
    上一条命令的退出状态码(0 表示成功,非 0 表示失败)
    ls /tmp; echo $?
    (输出 0 表示执行成功)

    示例:环境变量的应用场景

    echo "当前用户:$USER,主目录:$HOME"
    echo "命令搜索路径:$PATH"
    echo "上一条命令执行结果:$?"  # 0表示成功,非0表示失败(如127=命令未找到)

    2. 位置变量

    用于接收脚本运行时传入的命令行参数,格式为

    $n
    (n 为正整数,取值范围 1–9;当 n ≥ 10 时需写作
    ${10}
    )。

    变量名 作用说明
    $0
    脚本文件自身的名称(包含执行路径,若指定了路径运行)
    $1~$9
    分别代表第 1 至第 9 个命令行参数
    ${10}
    用于获取第 10 个及以后的参数(必须配合 {} 使用)
    $#
    统计传入的所有命令行参数的数量
    $*
    将所有参数作为一个整体字符串输出
    $@
    将所有参数以独立字符串数组的形式传递

    示例:编写一个使用位置变量的脚本(param.sh)

    #!/bin/bash
    echo "脚本名:$0"
    echo "第1个参数:$1"
    echo "第2个参数:$2"
    echo "第10个参数:${10}"  # 注意{}
    echo "参数总个数:$#"
    echo "所有参数($*):$*"
    echo "所有参数($@):$@"
    
    # 遍历所有参数($@更适合循环)
    echo "遍历参数($@):"
    for arg in "$@"; do
      echo "- $arg"
    done

    执行脚本并传参:

    chmod +x param.sh
    ./param.sh a b c d e f g h i j k  # 传入11个参数

    预期输出结果:

    脚本名:./param.sh
    第1个参数:a
    第2个参数:b
    第10个参数:j
    参数总个数:11
    所有参数($*):a b c d e f g h i j k
    所有参数($@):a b c d e f g h i j k
    遍历参数($@):
    - a
    - b
    - ...(省略中间参数)
    - k

    3. 预定义变量

    这些是 Shell 内建的特殊变量,用于提取命令执行状态、进程 ID 等核心运行时信息,用户不可手动修改。

    变量名 作用说明 示例
    $?
    上一条命令的退出状态码(0 表示成功,非 0 表示失败)
    ls /nonexistent; echo $?
    (输出 2,表示失败)
    $$
    当前 Shell 进程的 PID(进程标识号)
    echo $$
    (输出示例:12345)
    $!
    最近一个后台任务的进程 ID
    sleep 100 &; echo $!
    (显示后台运行的进程编号)
    $?
    再次强调:上一条命令的退出状态——最常使用的判断依据
    ./script.sh; echo $?
    (0 表示脚本成功执行)
    $-
    当前 Shell 启动时所使用的选项标志(如 h=hashall, i=interactive)
    echo $-
    (输出:himBH)
    $_
    上一条命令使用的最后一个参数内容
    ls /home /tmp; echo $_
    (输出:/tmp)

    示例:预定义变量的实际应用演示

    # 1. $?:判断命令是否执行成功
    ping -c 1 www.baidu.com &> /dev/null
    if [ $? -eq 0 ]; then
      echo "百度可通"
    else
      echo "百度不可通"
    fi
    
    # 2. $$:获取当前脚本PID(可用于生成唯一文件名)
    echo "当前脚本PID:$$"
    temp_file="temp_$$.txt"  # 生成唯一临时文件名
    echo "临时文件:$temp_file"
    
    # 3. $!:获取后台进程PID
    sleep 30 &  # 后台运行sleep命令
    echo "后台进程PID:$!"
    kill $!     # 终止后台进程

    总结

    Shell 脚本编写中的核心规范之一是使用 shebang 声明:

    #!/bin/bash

    变量主要分为两类:自定义变量和特殊变量。自定义变量由用户自行定义,而特殊变量则包括环境变量、位置变量以及预定义变量,它们在脚本运行过程中起到关键作用。

    在数值运算方面,整数计算通常使用特定命令实现,相关示例如下:

    $((...))

    对于浮点数或更复杂的数学运算,则需借助专门的工具进行处理,示例如下:

    bc

    位置变量是脚本参数传递的重要手段,能够灵活接收外部输入,其用法参考:

    $1~$n

    此外,另一个脚本自动化中不可或缺的元素是预定义变量中的执行状态码,用于获取上一条命令的执行结果,标记如下:

    $?

    关于权限控制、代码注释与命令执行顺序的规范也至关重要,应确保脚本具备清晰的注释、正确的执行权限设置;
    重定向机制可用于调整输入输出的数据流向,而管道则常用于多个命令之间的协作处理。

    二维码

    扫码加我 拉你入群

    请注明:姓名-公司-职位

    以便审核进群资格,未注明则拒绝

    关键词:Shell Shel SHE environment Interactive

    您需要登录后才可以回帖 登录 | 我要注册

    本版微信群
    jg-xs1
    拉您进交流群
    GMT+8, 2025-12-6 02:31