最近在学learn-claude-code,需要Bash命令知识故deepseek+写作skill之
Bash 是什么
简单说,Bash 是一个「壳」------你敲命令,它帮你跟操作系统对话。你用鼠标点击文件夹、创建文件、复制粘贴,这些操作全部可以用 Bash 命令完成,而且更快、更精确。
打开终端的方式:
- macOS :按
Cmd + 空格,搜「终端」或「Terminal」 - Windows:装一个 Git Bash(安装 Git 时会带上),或者用 WSL
- Linux:你大概率已经知道怎么打开了
打开之后,你看到的大概率就是 Bash。
查阅文档
你不需要背命令。你需要的是知道怎么查命令。
方法一:看内置说明书
bash
man 命令名 # 比如 man ls,按 q 退出
命令名 --help # 大部分命令支持,更简短
方法二:反向搜索
bash
history | grep 关键词
history 列出你敲过的所有命令,配合 grep 搜关键词。找到一两周前用过的那个命令,比从头敲快得多。
方法三:Ctrl+R
按 Ctrl + R,然后开始打字,Bash 会实时搜索你的历史命令。再按一次 Ctrl + R 跳到下一个匹配。
文件操作 + 路径导航
目标:不用鼠标也能在文件系统里自由移动。
pwd --- 我在哪
bash
pwd
# 输出:/home/你的用户名
pwd = print working directory。告诉你当前在哪个文件夹。每次打开终端第一件事可能就是敲这个。
ls --- 这里有什么
bash
ls # 列出当前目录下的文件和文件夹
ls -l # 详细信息:权限、大小、修改时间
ls -a # 包括隐藏文件(以 . 开头的文件)
ls -la # 详细信息 + 隐藏文件,最常用的组合
ls -lh # 文件大小显示为人类可读的格式(K、M、G)
ls *.txt # 只列出 .txt 结尾的文件
cd --- 到处走
bash
cd 文件夹名 # 进入某个文件夹
cd .. # 回到上一级
cd ../.. # 回到上两级
cd ~ # 回到主目录(home)
cd - # 回到刚才待的目录
cd / # 去根目录
cd = change directory。Tab 键可以自动补全路径------打前几个字母按 Tab,省掉一半敲键盘时间。
绝对路径 vs 相对路径:
bash
cd /home/用户名/文档 # 绝对路径:从根目录开始写
cd 文档 # 相对路径:从当前位置开始写
cd ./文档 # ./ 表示当前目录,和上面等价
touch --- 创建空文件
bash
touch readme.txt # 创建一个空文件
touch a.txt b.txt c.txt # 一次创建多个文件
文件原本不存在就创建,已经存在就更新修改时间(内容不变)。
mkdir --- 创建文件夹
bash
mkdir 项目 # 创建一个文件夹
mkdir -p a/b/c # 递归创建多层文件夹,即使 a 和 b 不存在
-p 很实用:你想创建 项目/代码/src,但前面的目录还不存在,加 -p 一步到位。
cp --- 复制
bash
cp 源文件 目标 # 复制文件
cp a.txt b.txt 备份/ # 复制多个文件到文件夹
cp -r 源文件夹 目标 # 复制文件夹(-r 表示递归)
复制文件夹时必须加 -r,否则会报错。
mv --- 移动 / 重命名
bash
mv 旧名 新名 # 重命名
mv 文件 目标文件夹/ # 移入文件夹
mv a.txt ../ # 移到上一级目录
Bash 里没有单独的「重命名」命令,mv 干了这两件事。
rm --- 删除
bash
rm 文件名 # 删除文件
rm -r 文件夹名 # 删除文件夹及其内容
rm -i *.txt # 每个文件删除前确认
rm 没有回收站。删了就没了。 养成习惯:删之前先用 ls 看一眼要删什么。不确定时把 rm 换成 echo 预览:
bash
echo rm -rf 某个模糊匹配*
# 看看输出是你想删的东西吗?确认了再把 echo 去掉
管道和查看内容
目标:能查看文件、筛选内容、组合简单命令。
cat --- 输出文件内容
bash
cat 文件名 # 把整个文件内容打印到屏幕
cat a.txt b.txt # 拼接多个文件一起输出
cat -n 文件名 # 带行号输出
适合小文件。大文件用下面的。
head / tail --- 看头看尾
bash
head 文件名 # 默认显示前 10 行
head -n 20 文件名 # 显示前 20 行
tail 文件名 # 默认显示后 10 行
tail -n 20 文件名 # 显示后 20 行
tail -f 日志文件 # 实时追踪文件末尾新增内容(看日志专用,Ctrl+C 退出)
tail -f 是排查问题的利器。服务在跑,日志在写,你用 tail -f 盯着,出了错立刻看到。
less --- 分页浏览
bash
less 文件名 # 上下翻页浏览,按 q 退出
cat 对大文件不友好------刷屏几千行什么都看不清。less 让你一页一页看。空格翻页,/关键词 搜索,n 跳到下一个匹配。
wc --- 计数
bash
wc 文件名 # 输出:行数 单词数 字节数
wc -l 文件名 # 只看行数
wc -w 文件名 # 只看单词数
常见用法:grep "ERROR" log.txt | wc -l------数一下日志里有多少行错误。
grep --- 搜索文本
bash
grep "关键词" 文件名 # 搜索文件,输出包含关键词的行
grep -i "error" log.txt # 忽略大小写
grep -n "error" log.txt # 显示行号
grep -r "TODO" ./src/ # 递归搜索整个目录
grep -v "DEBUG" log.txt # 反向:排除包含 DEBUG 的行
grep -c "error" log.txt # 只输出匹配行数
grep 是你以后使用频率最高的命令之一。它不止搜文件------通常配合管道,对任意命令的输出做筛选。
管道 --- 把命令串起来
管道符号 | 把左边命令的输出,变成右边命令的输入:
bash
ls -l | grep ".txt" # 列出文件 → 筛出 .txt
cat log.txt | grep "ERROR" | wc -l # 读日志 → 筛错误 → 数行数
history | grep "git" # 查历史 → 找 git 相关命令
ps aux | grep "node" # 查进程 → 找 node 进程
每一步都是独立的小命令,组合起来能力远大于各部分之和。这是 Unix 的设计哲学:做一件事,把它做好,然后跟其他工具组合。
重定向 --- 把输出存下来
bash
echo "hello" > file.txt # 覆盖写入(文件原来内容会丢失)
echo "world" >> file.txt # 追加写入(保留原来内容)
> 和 >> 的区别是使用频率最高的「踩坑点」之一。单个 > 会清空原文件再写,>> 不会。保存重要数据前先确认用的是 >> 还是 >。
bash
command > output.txt # 标准输出写到文件
command 2> error.txt # 错误输出写到文件
command > all.txt 2>&1 # 标准输出和错误输出合并到一个文件
command > /dev/null # 丢弃所有输出(不想看输出时用)
/dev/null 像一个黑洞,扔进去的东西永远消失。跑脚本不想看满屏输出时常用。
变量、循环、脚本
目标:能写 20 行以内的自动化脚本。
变量
bash
# 定义变量(等号两边不能有空格)
name="world"
num=42
# 使用变量(用 $ 引用)
echo "hello $name" # hello world
echo "num is $num" # num is 42
# 花括号明确变量边界
echo "${name}ly" # worldly
# 命令结果赋值给变量
files=$(ls | wc -l) # 把 ls | wc -l 的输出赋给 files
echo "当前目录有 $files 个文件"
# 或者用反引号(老式写法,不推荐)
files=`ls | wc -l`
等号两边不能有空格------name = "world" 会报错,name="world" 才对。这是新手最容易踩的坑之一。
双引号 vs 单引号:
bash
name="world"
echo "hello $name" # hello world (双引号里变量会展开)
echo 'hello $name' # hello $name (单引号里原样输出)
简单记:需要变量展开就用双引号,想原封不动输出就用单引号。
特殊变量:
bash
echo $0 # 脚本自身的名字
echo $1 # 第一个参数
echo $2 # 第二个参数
echo $# # 参数个数
echo $@ # 所有参数(作为列表)
echo $? # 上一条命令的退出码(0 = 成功,非 0 = 失败)
$? 很实用:跑完一条命令想知道它成功没有,echo $? 看一眼。
条件判断
bash
# if 基本结构
if [ 条件 ]; then
命令
elif [ 条件 ]; then
命令
else
命令
fi
注意:[ 和 ] 两边必须有空格。 [条件] 是错的,[ 条件 ] 才对。
常用条件:
bash
# 文件判断
[ -f 文件 ] # 文件存在且是普通文件
[ -d 目录 ] # 目录存在
[ -e 路径 ] # 文件或目录存在
[ -s 文件 ] # 文件存在且非空
# 字符串判断
[ "$a" = "$b" ] # 相等
[ "$a" != "$b" ] # 不等
[ -z "$a" ] # 字符串为空
[ -n "$a" ] # 字符串非空
# 数字判断
[ $a -eq $b ] # 等于(equal)
[ $a -ne $b ] # 不等于(not equal)
[ $a -gt $b ] # 大于(greater than)
[ $a -lt $b ] # 小于(less than)
[ $a -ge $b ] # 大于等于
[ $a -le $b ] # 小于等于
实用例子:
bash
# 检查文件是否存在
if [ -f "config.json" ]; then
echo "找到配置文件"
else
echo "配置文件不存在,请先创建"
fi
# 检查命令是否执行成功
if grep -q "error" log.txt; then
echo "日志中有错误"
fi
循环
bash
# for 循环 --- 对列表中的每一项执行操作
for file in *.txt; do
echo "处理:$file"
wc -l "$file"
done
# 数字范围
for i in {1..5}; do
echo "第 $i 次"
done
# 带步长
for i in {0..100..10}; do
echo "$i"
done
# while 循环 --- 条件为真就一直跑
count=1
while [ $count -le 5 ]; do
echo "$count"
count=$((count + 1))
done
for 循环用在你知道要遍历什么东西的时候;while 用在等某个条件满足的时候(比如等文件出现、等进程结束)。
脚本文件
把上面学的东西写进文件,让它们自动执行:
bash
#!/bin/bash
# 脚本的第一行必须是这个(shebang),告诉系统用 Bash 执行
set -euo pipefail # 严格模式:任何错误就退出(强烈推荐)
# --- 一个实用例子:备份脚本 ---
backup_dir="$HOME/backups/$(date +%Y-%m-%d)"
mkdir -p "$backup_dir"
for file in "$HOME"/文档/*.txt; do
if [ -f "$file" ]; then
cp "$file" "$backup_dir/"
echo "已备份:$file"
fi
done
echo "备份完成,文件保存在:$backup_dir"
set -euo pipefail 的三个作用:
-e:任何命令失败就退出,不继续执行-u:引用未定义变量时报错退出-o pipefail:管道中任何一个命令失败,整个管道算失败
执行脚本:
bash
chmod +x 脚本名.sh # 给执行权限(只需一次)
./脚本名.sh # 运行
bash 脚本名.sh # 或者这样运行(不需要 chmod)
函数
bash
# 定义函数
say_hello() {
local name="$1" # local 让变量只在这个函数里有效
echo "你好,$name"
}
# 调用函数
say_hello "小明"
say_hello "小红"
函数适合把重复的逻辑封装起来。$1 是第一个参数,$2 第二个,和脚本参数一样。
综合练习:日志分析脚本
bash
#!/bin/bash
set -euo pipefail
log_file="${1:-/var/log/syslog}" # 第一个参数,没有则用默认值
if [ ! -f "$log_file" ]; then
echo "错误:$log_file 不存在"
exit 1
fi
echo "=== 日志分析:$log_file ==="
echo ""
echo "总行数:$(wc -l < "$log_file")"
echo ""
echo "错误数:$(grep -ci "error" "$log_file")"
echo ""
echo "最近 5 条错误:"
grep -i "error" "$log_file" | tail -n 5
跑法:./analyze.sh /var/log/nginx/error.log
按需学习
前面的三个阶段覆盖了日常 80% 的需求。以下工具不需要一次性学完,遇到了再查。
find --- 查找文件
bash
find . -name "*.log" # 按文件名找(当前目录及子目录)
find . -type d -name "node_modules" # 找目录
find . -type f -size +10M # 找大于 10MB 的文件
find . -name "*.tmp" -delete # 找到并删除(小心使用)
find . -name "*.log" -mtime -7 # 最近 7 天修改过的 .log 文件
find . -name "*.sh" -exec chmod +x {} \; # 找到并执行操作
比 ls 强大在可以递归搜索、按各种条件筛选、对找到的文件批量操作。
sed --- 流编辑器,做文本替换
bash
sed 's/旧/新/' 文件 # 每行替换第一个匹配
sed 's/旧/新/g' 文件 # 每行替换所有匹配(g = global)
sed -i 's/旧/新/g' 文件 # 直接修改文件(-i = in-place)
sed '3,5s/旧/新/g' 文件 # 只在第 3 到第 5 行替换
sed '/pattern/d' 文件 # 删除匹配的行
最常见的场景:批量替换配置文件里的 IP 地址、端口号。注意 -i 会直接改文件,建议先用不带 -i 的版本预览效果。
awk --- 按列处理文本
bash
awk '{print $1}' 文件 # 打印第一列
awk '{print $1, $3}' 文件 # 打印第一列和第三列
awk -F':' '{print $1}' /etc/passwd # 指定分隔符为冒号
awk '$3 > 100 {print $1}' 文件 # 第三列大于 100 才打印
awk '{sum+=$3} END {print sum}' 文件 # 第三列求和
awk 擅长处理结构化的文本------日志、CSV、ps 输出等。默认按空白字符分列。
xargs --- 把标准输入转成命令行参数
bash
find . -name "*.log" | xargs rm # 删除所有 .log 文件
find . -name "*.txt" | xargs wc -l # 统计所有 .txt 文件的行数
echo "a.txt b.txt c.txt" | xargs touch # 一次创建多个文件
find . -name "*.jpg" | xargs -I {} cp {} backup/ # 复制找到的文件
xargs 解决了一个问题:很多命令不接受管道输入作为操作对象。pipe | rm 不行,但 pipe | xargs rm 可以。
curl --- 发 HTTP 请求
bash
curl https://api.example.com # GET 请求,输出响应体
curl -o 文件名 URL # 下载文件
curl -O URL # 下载文件(用原名)
curl -I URL # 只看响应头
curl -X POST -d "key=value" URL # POST 请求
curl -H "Authorization: Bearer token" URL # 带请求头
调接口、下载文件、测试 API,curl 一把梭。
jq --- 处理 JSON
bash
curl -s API地址 | jq '.' # 格式化 JSON
curl -s API地址 | jq '.name' # 取一个字段
curl -s API地址 | jq '.items[] | .id' # 取数组中每个元素的 id
curl -s API地址 | jq '.[] | select(.status=="active")' # 按条件筛选
API 返回的 JSON 经常是一大坨挤在一起的文本,jq 把它格式化并帮你提取想要的数据。
注意事项
rm不可逆 。没有回收站。删之前先用ls或echo预览,确认了再动手。- 空格很关键 。
rm -rf /和rm -rf /某个文件夹差了一个空格,后果完全不同。不要手打路径,用 Tab 补全。 - Ctrl+C 是逃生按钮 。程序跑飞了、卡住了,按
Ctrl + C终止它。 - 别怕敲错。Bash 只是个工具,和 Word、浏览器没有本质区别。大部分错误只会给你一行报错,不会有任何破坏。
- 双引号包裹变量 。写脚本时用
"$var"而不是$var,防止变量值为空或含空格时出 bug。 - ShellCheck 是好朋友 。装一个 ShellCheck,它会帮你发现脚本里的常见错误。