backup materials and knowledge-base docs
This commit is contained in:
@@ -0,0 +1,236 @@
|
||||
# Bash/Zsh 脚本错误详解
|
||||
|
||||
## 常见错误类型
|
||||
|
||||
### 1. Command Not Found
|
||||
|
||||
**特征**:bash: command: command not found
|
||||
|
||||
**常见原因**:
|
||||
- 命令拼写错误
|
||||
- 命令未安装
|
||||
- PATH 环境变量不正确
|
||||
- 脚本 shebang 错误
|
||||
|
||||
**示例**:
|
||||
```bash
|
||||
# 拼写错误
|
||||
pyhon script.py # command not found
|
||||
|
||||
# 正确拼写
|
||||
python script.py
|
||||
|
||||
# PATH 问题
|
||||
/usr/local/bin/mycommand # 如果 PATH 不包含 /usr/local/bin
|
||||
|
||||
# 使用完整路径或添加到 PATH
|
||||
export PATH="/usr/local/bin:$PATH"
|
||||
mycommand
|
||||
```
|
||||
|
||||
### 2. Syntax Error
|
||||
|
||||
**特征**:syntax error near unexpected token
|
||||
|
||||
**常见原因**:
|
||||
- 缺少 then/fi/done/ esac
|
||||
- 括号不匹配
|
||||
- 操作符缺少空格
|
||||
|
||||
**示例**:
|
||||
```bash
|
||||
# 缺少 then
|
||||
if [ 1 -eq 1 ]
|
||||
echo "yes" # syntax error
|
||||
|
||||
# 正确
|
||||
if [ 1 -eq 1 ]; then
|
||||
echo "yes"
|
||||
fi
|
||||
```
|
||||
|
||||
### 3. Permission Denied
|
||||
|
||||
**特征**:bash: ./script.sh: Permission denied
|
||||
|
||||
**解决方案**:
|
||||
```bash
|
||||
# 添加执行权限
|
||||
chmod +x script.sh
|
||||
|
||||
# 或使用 bash 运行
|
||||
bash script.sh
|
||||
```
|
||||
|
||||
## 调试技巧
|
||||
|
||||
### 1. 使用 set -x 追踪执行
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -x # 启用命令追踪
|
||||
|
||||
name="John"
|
||||
echo "Hello $name"
|
||||
|
||||
# 输出:
|
||||
# + name=John
|
||||
# + echo 'Hello John'
|
||||
# Hello John
|
||||
```
|
||||
|
||||
### 2. 使用 set -e 遇错退出
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -e # 任何命令失败时退出
|
||||
|
||||
cd /nonexistent # 脚本在此处退出
|
||||
echo "This won't run"
|
||||
```
|
||||
|
||||
### 3. 使用 set -u 检测未定义变量
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -u # 未定义变量时报错
|
||||
|
||||
echo $undefined_var # 报错并退出
|
||||
```
|
||||
|
||||
### 4. 组合使用调试选项
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -xeuo pipefail # 严格模式
|
||||
|
||||
# -x: 打印每个命令
|
||||
# -e: 错误时退出
|
||||
# -u: 未定义变量报错
|
||||
# -o pipefail: 管道失败则失败
|
||||
```
|
||||
|
||||
### 5. 使用 trap 捕获错误
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# 在脚本退出时执行清理
|
||||
trap 'echo "Script exited with code $?"' EXIT
|
||||
|
||||
# 在错误时执行
|
||||
trap 'echo "Error on line $LINENO"' ERR
|
||||
|
||||
# 在中断时执行
|
||||
trap 'echo "Interrupted"; cleanup' INT
|
||||
```
|
||||
|
||||
## 错误处理模式
|
||||
|
||||
### 1. 检查命令退出码
|
||||
|
||||
```bash
|
||||
# 检查上一个命令是否成功
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "Success"
|
||||
else
|
||||
echo "Failed"
|
||||
fi
|
||||
|
||||
# 或使用 ||
|
||||
command || { echo "Failed"; exit 1; }
|
||||
|
||||
# 或使用 &&
|
||||
command && echo "Success" || echo "Failed"
|
||||
```
|
||||
|
||||
### 2. 使用函数封装错误处理
|
||||
|
||||
```bash
|
||||
# 定义错误处理函数
|
||||
die() {
|
||||
local message=$1
|
||||
echo "Error: $message" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# 使用
|
||||
[ -f "$file" ] || die "File not found: $file"
|
||||
```
|
||||
|
||||
### 3. 验证输入参数
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# 检查参数数量
|
||||
[ $# -ge 1 ] || die "Usage: $0 <arg1> [arg2]"
|
||||
|
||||
# 检查文件存在
|
||||
[ -f "$1" ] || die "File not found: $1"
|
||||
|
||||
# 检查目录存在
|
||||
[ -d "$2" ] || die "Directory not found: $2"
|
||||
```
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 1. 始终使用 shebang
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# 或
|
||||
#!/usr/bin/env bash
|
||||
```
|
||||
|
||||
### 2. 使用 set -euo pipefail
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
```
|
||||
|
||||
### 3. 引用所有变量
|
||||
|
||||
```bash
|
||||
# 除非确定变量不包含空格或通配符
|
||||
echo "$var"
|
||||
```
|
||||
|
||||
### 4. 使用 [[ ]] 而不是 [ ]
|
||||
|
||||
```bash
|
||||
# [[ 更强大且更安全
|
||||
if [[ $name == "John" ]]; then
|
||||
if [[ -f $file && $size -gt 100 ]]; then
|
||||
```
|
||||
|
||||
### 5. 使用 $(command) 而不是反引号
|
||||
|
||||
```bash
|
||||
# $() 更易读且可嵌套
|
||||
result=$(command1 $(command2))
|
||||
```
|
||||
|
||||
### 6. 使用函数组织代码
|
||||
|
||||
```bash
|
||||
my_function() {
|
||||
local arg1=$1
|
||||
local arg2=$2
|
||||
# 函数体
|
||||
}
|
||||
|
||||
my_function "value1" "value2"
|
||||
```
|
||||
|
||||
## ShellCheck 静态分析
|
||||
|
||||
ShellCheck 是一个 Shell 脚本静态分析工具:
|
||||
|
||||
```bash
|
||||
# 安装 ShellCheck
|
||||
brew install shellcheck # macOS
|
||||
apt install shellcheck # Ubuntu
|
||||
|
||||
# 使用
|
||||
shellcheck script.sh
|
||||
```
|
||||
Reference in New Issue
Block a user