Shell基础

1. 脚本基本结构

创建Shell脚本

创建一个简单的Shell脚本

#!/bin/bash
echo "Hello, World!"

2. 变量

定义变量

name="John"
age=25

使用变量

echo "My name is $name"
echo "I am ${age} years old"

3. 特殊变量

脚本名称

echo $0

第一个参数

echo $1

参数个数

echo $#

所有参数

echo $*

上一个命令的退出状态

echo $?

当前进程ID

echo $$

历史命令技巧

重复执行上条命令

echo !!

重复执行 history 历史中第 N 条命令,N 可以通过 history 查看;

echo !N

重复执行最近一次,以pw开头的历史命令,这个非常有用,小编使用非常高频;

echo !pw

表示最近一次命令的最后一个参数

echo !$
echo $_ #这个也是最后一个参数

猜测大部分同学没用过 !$,这里简单举个例子,让你感受一下它的高效用法

$ vim /root/sniffer/src/main.c
$ mv !$ !$.bak
# 相当于
$ mv /root/sniffer/src/main.c /root/sniffer/src/main.c.bak

当前工作目录是 root,想把 main.c 改为 main.c.bak。正常情况你可能需要敲 2 遍包含 main.c 的长参数,当然你也可能会选择直接复制粘贴。

而我通过使用 !$ 变量,可以很轻松优雅的实现改名,是不是很 hacker 呢?

记录你的命令行会话

如果你想记录你在shell上输入的内容,你可以使用脚本命令来保存你所有输入的内容到一个叫typescript的文件中。

script typescript
exit

一旦你输入exit,所有你输入的命令将会写入到那个文件,后面你可以重新查看它。

流程控制

1. 条件判断

if语句

if [ $age -gt 18 ]; then
    echo "成年人"
elif [ $age -eq 18 ]; then
    echo "刚好成年"
else
    echo "未成年"
fi

case语句

case $fruit in
    "apple")
        echo "这是苹果"
        ;;
    "banana")
        echo "这是香蕉"
        ;;
    *)
        echo "未知水果"
        ;;
esac

2. 循环

for循环

for i in 1 2 3 4 5; do
    echo "数字:$i"
done

while循环

count=1
while [ $count -le 5 ]; do
    echo "Count: $count"
    count=$((count + 1))
done

3. 函数

定义函数

greet() {
    echo "Hello, $1!"
    return 0
}

调用函数

greet "John"

字符串处理

1. 字符串操作

字符串长度

str="Hello"
echo ${#str}

字符串截取

str="Hello World"
echo ${str:0:5}  # 输出Hello

字符串替换

str="Hello World"
echo ${str/World/Shell}  # 替换World为Shell

2. 正则表达式

使用grep

echo "Hello World" | grep -E "^Hello"

使用sed

echo "Hello World" | sed 's/World/Shell/'

文件操作

1. 文件读写

读取文件

while read line; do
    echo "$line"
done < file.txt

写入文件

echo "新内容" > file.txt  # 覆盖
echo "追加内容" >> file.txt  # 追加

2. 文件判断

判断是否为文件

[ -f file.txt ]

判断是否为目录

[ -d dir ]

判断是否可读

[ -r file.txt ]

判断是否可写

[ -w file.txt ]

判断是否可执行

[ -x file.txt ]

实用示例

1. 备份脚本

#!/bin/bash

BACKUP_DIR="/backup"
SOURCE_DIR="/data"
DATE=$(date +%Y%m%d)

# 创建备份目录
mkdir -p "$BACKUP_DIR"

# 创建备份
tar -czf "$BACKUP_DIR/backup_$DATE.tar.gz" "$SOURCE_DIR"

# 删除7天前的备份
find "$BACKUP_DIR" -name "backup_*.tar.gz" -mtime +7 -delete

2. 系统监控脚本

#!/bin/bash

# 检查CPU使用率
cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}')

# 检查内存使用率
mem_usage=$(free | grep Mem | awk '{print $3/$2 * 100.0}')

# 检查磁盘使用率
disk_usage=$(df -h / | tail -1 | awk '{print $5}')

# 输出结果
echo "系统状态报告"
echo "CPU使用率: $cpu_usage%"
echo "内存使用率: $mem_usage%"
echo "磁盘使用率: $disk_usage"

调试技巧

1. 调试选项

set -x  # 启用调试模式
set -e  # 遇到错误时退出
set -u  # 使用未定义变量时报错

2. 错误处理

捕获错误

trap 'echo "发生错误,退出码: $?"' ERR

清理操作

trap 'rm -f temp_file' EXIT

最佳实践

  1. 始终在脚本开头添加shebang行(#!/bin/bash)
  2. 使用有意义的变量名和函数名
  3. 添加适当的注释和文档
  4. 处理错误和异常情况
  5. 使用合适的退出码
  6. 注意脚本的安全性和权限设置