Shell 基础复习笔记:执行方式 · 变量 · 运算符
复习原因:旧教程写法过时(sh / 反引号 / $[ ] / expr)+ 基础不熟
日期:2026-10-15 · 定位:所有脚本知识的"地基"
一、脚本执行方式(本质区别:子进程 vs 当前 shell)
| 方式 | 命令 | 特点 | 适用 |
|---|---|---|---|
| ① 显式解释 | bash p1.sh |
免执行权限;子进程,变量改动不保留 | 日常最保险 |
| ② 直接执行 | ./p1.sh |
需 chmod +x + 首行 #!/bin/bash;子进程 |
发布/安装脚本 |
| ③ 当前 shell | source p1.sh(或 . p1.sh) |
不建子进程,变量/函数改动保留 | 加载配置(.bashrc) |
⚠️ 易错点:
- 绝对路径执行(/home/u/s.sh)= 方式②,是子进程,不是当前 shell!
- 老教程的 sh s.sh 在 Debian 是 dash(更严格),[[ ]] 等特性会报错 → 统一用 bash
- 记忆:"执行"= 子进程,"source"= 当前 shell
二、变量(最容易出错的模块)
1. 定义:等号两边不能有空格
name=value # ✅
name = value # ❌ 被解析成"执行命令 name,参数 = value"
2. 引用规则
echo $name # 取变量值
echo ${name} # 取变量值,花括号标边界 → 推荐
echo "$name" # 双引号:展开,整体当一个词 → 生产必须加引号
echo '$name' # 单引号:字面量,输出 $name
a=world
echo "$a" # world
echo '$a' # $a(不展开)
3. 命令替换
today=$(date +%Y%m%d) # ✅ 现代
today=`date +%Y%m%d` # ❌ 老式(嵌套难、转义地狱)
4. 位置参数与特殊变量
# bash t.sh apple banana
$0 → t.sh $1 → apple $2 → banana
$# → 2(个数) $@ → 全部参数 $? → 上条命令退出码(0=成功)
$$ → 当前 PID
经典坑:$@ vs "$@"
# 传参 "hello world" 和 "bob"
for x in $@; do echo "$x"; done # 拆成 hello / world / bob
for x in "$@"; do echo "$x"; done # hello world / bob ✅
三、运算符
1. 算术(只支持整数)
x=5; y=2
echo $((x + y)) # 7
echo $((x / y)) # 2 —— 整除向下取整,没有小数!
echo $((x % y)) # 1
((x++)) # 自增
老写法 $[ ] / expr 全部淘汰。
2. 比较三分类
# 数值:[ ] 和 [[ ]] 通用
[ $x -eq 5 ] # -eq -ne -gt -ge -lt -le
# 字符串(= 是一个,不是 ==)
[ "$s" = "abc" ] # 相等(引号必须,防空变量)
[ -z "$s" ] # 为空
[ -n "$s" ] # 非空
[[ "abc" =~ ^a ]] # 正则(仅 [[ ]] 支持)
# 文件
[ -e 文件 ] 存在 [ -f ] 普通文件 [ -d ] 目录
[ -r ] [ -w ] [ -x ] 读/写/执行权限
3. [ ] vs [[ ]](老教程最大的坑)
[ ](test 命令) |
[[ ]](bash 关键字) |
|
|---|---|---|
| 空变量 | [ $s = a ] 报错 |
[[ $s == a ]] 安全 |
| 逻辑组合 | -a / -o |
直接 && / \|\| |
| 正则 | 不支持 | =~ 支持 |
| 比较符 | = |
= 或 == |
[[ $a == x && $b == y ]] # 现代标准
[ "$a" = x -a "$b" = y ] # 老式,能跑但坑多
四、老教程 4 大过时写法速查
| 场景 | 老教程 ❌ | 现代 ✅ |
|---|---|---|
| 命令替换 | `cmd` |
$(cmd) |
| 算术 | $[x+1] / expr |
$((x+1)) |
| 测试 | test / [ ] |
[[ ]] |
| 逻辑组合 | [ a -a b ] |
[[ a && b ]] |
五、自测批改记录(2026-10-15)
Q1 执行方式:bash 免权限子进程 ✅ / ./ 需权限子进程 ✅ / source 当前 shell ✅
- ❌ 我答错点:绝对路径执行也是子进程(= 方式②),不是当前 shell
Q2 单双引号:'$a' → $a(字面),"$a" → world(展开)✅
Q3 位置参数:参数 "hello world" bob → $#=2、$1="hello world"、"$@" 保持两个独立参数、$@ 拆成 3 词 ✅
Q4 整除:$((7/2)) → 3(bash 算术只支持整数,除法向下取整)✅
Q5 老→新改写(我错的 3 处):
b=$((a + 1) # ❌ 括号不配对 → $((a + 1)) 双括号成对
&& &b -lt 2030 # ❌ &b → $b(& 是逻辑与,不是变量引用)
2030]] # ❌ [[ ]] 内每词必须空格 → -lt 2030 ]]
六、语法三查习惯(每次写完脚本必做)
① 数括号:$(( → 后面一定有两个 ))
② 数美元:每个变量前都有 $,且 $ 后一定是变量名
③ 查空格:[[ 内容 ]] 首尾都有空格;[ 内容 ] 同样
病根提醒:思想对 + 书写精度不够 = 语法错误。三查习惯能把错误消灭在运行前。
评论