Linux常用命令练习流程

练习环境准备

在开始之前,请确保你有一台Linux环境(虚拟机、WSL、云服务器或本地Docker均可)。

复制代码
# 如果没有练习环境,可以用Docker快速启动一个CentOS容器
docker run -it --name linux-lab centos:7 /bin/bash

第一阶段:初来乍到 - 连接与基础探索

1.1 SSH连接(模拟)

说明:如果你的环境是本机Docker或虚拟机,可跳过此步。如果是远程服务器,使用此命令。

复制代码
# 连接到远程服务器(替换为实际IP和用户)
ssh root@192.168.1.100
# 退出连接
exit

1.2 文件与目录管理

复制代码
# 1. 查看当前位置
pwd          -全称 Print Working Directory 打印工作目录

# 2. 创建练习工作目录
mkdir -p ~/opt/java-lab/{logs,backup,config}
cd ~/opt/java-lab    -全称是 Change Directory,切换目录

命令拆解:

组成部分 全称 含义
mkdir Make Directory 创建目录(文件夹)。
-p Parents 递归创建。如果父目录不存在,会一并创建;如果目录已存在,也不会报错。
~ Home Directory 当前用户的家目录(例如 /home/username)。
{...} Brace Expansion 花括号扩展。这是 Shell 的一种语法,用于批量生成相似的路径或文件名。
复制代码
# 3. 查看目录内容
ls -la

命令拆解:

组成部分 英文全称 中文含义 作用
ls List 列出 基础命令,用于显示目录内容。
-l Long format 长格式 显示详细信息(权限、所有者、大小、时间等)。
-a All 所有 显示所有文件,包括以 . 开头的隐藏文件
复制代码
# 4. 创建、复制、移动、重命名文件
touch app.jar                    # 创建一个模拟的jar包文件
cp app.jar backup/app_backup.jar # 复制文件
mv app.jar old_app.jar           # 重命名
mv old_app.jar deploy/           # 移动到目录

# 5. 删除文件(注意:rm -rf 非常危险,练习时请确认路径)
mkdir test_dir && touch test_dir/dummy.txt
rm -rf test_dir                  # 递归强制删除

命令拆解:

组成部分 英文全称 中文含义 作用
rm Remove 删除 基础命令,用于删除文件或目录。
-r Recursive 递归的 告诉系统"层层深入",删除目录及其内部所有的子目录和文件。
-f Force 强制 告诉系统"强制执行",不询问确认,忽略不存在的文件。
test_dir (目标名称) 目标目录 你要删除的那个文件夹的名字。

第二阶段:编写配置 - vim编辑器练习

复制代码
# 1. 创建一个Spring Boot配置文件 application.yml
vim application.yml

# 2. 在vim中执行以下操作:
#    - 按 i 进入插入模式
#    - 输入以下内容:
#      server:
#        port: 8080
#      logging:
#        file: /var/log/app.log
#    - 按 Esc 退出插入模式
#    - 输入 :wq             -全称Write and Quit 保存并退出

# 3. 查看刚创建的文件
cat application.yml      - Concatenate,中文意思是连接

# 4. 练习不保存退出
vim application.yml
# 随意修改一些内容,然后按 Esc,输入 :q! 强制退出
复制代码

第三阶段:日志查看大练兵

复制代码
# 1. 创建一个大日志文件用于练习
for i in {1..500}; do echo "[$i] INFO - 这是第$i条日志" >> app.log; done
for i in {1..50}; do echo "[$i] ERROR - 模拟异常NullPointerException" >> app.log; done

命令拆解:

组成部分 含义 详细解释
for i in {1..500} 循环头 创建一个循环。变量 i 会从数字 1 开始,每次增加 1,直到 500 结束。
do ... done 循环体 包裹在中间的部分是每次循环都要执行的具体动作。
echo "..." 输出 汉语翻译为"回声",打印双引号内的字符串。
$i 变量引用 取出当前的数字。第一次是 1,第二次是 2... 最后一次是 500。
>> app.log 追加重定向 关键点!将输出的内容追加app.log 文件末尾。如果用 > 则会覆盖原文件。
复制代码
# 2. 查看全部内容(小文件可用)
cat app.log | head -20    # 看前20行

命令拆解:

部分 含义 作用
cat app.log 读取 app.log 文件内容 输出整个文件到屏幕
**` `(管道符)** 将左边命令的输出传递给右边命令
head -20 显示前20行 只输出前20行内容
复制代码
# 3. 查看尾部
tail -n 10 app.log        # 最后10行
tail -f app.log           # 实时追踪(按 Ctrl+C 退出)

命令拆解:

|-----------|-------------------------------------------------|
| tail | 尾巴 - 显示文件尾部内容 |
| -n | lines(行数)参数 |
| -f | follow (跟踪/跟随),文件有新内容写入 时,会自动显示在屏幕上 |
| app.log | 目标文件名 |

复制代码
# 4. 搜索过滤
grep "ERROR" app.log
grep -n "NullPointer" app.log   # 显示行号-n 是lines 是行的意思

拆解含义

部分 英文 中文含义
Global 全局 搜索整个文件,不局限于某一行
Regular 正则 支持正则表达式模式匹配
Expression 表达式 要搜索的文本模式
Print 打印 输出匹配的行

通俗理解

grep = 在文本中全局 搜索符合正则表达式 的内容,并打印出匹配的行

复制代码
# 5. 管道组合(关键技能)
cat app.log | grep "ERROR" | head -5

#6. 分页查看大文件
less app.log
# 在less中:按 Space 翻页,按 /ERROR 搜索,按 n 下一个,按 q 退出

命名哲学

命令 含义 特点
more 更多 早期的分页查看器,功能较少
less 更少 功能更强大的分页查看器,但名字叫"更少"

💡 著名的 Unix 格言:"Less is more, more or less"(少即是多,或多或少)

意思是:less 命令的功能比 more 更强大,但名字却叫"更少"

官方定义

less 的全称可以理解为:"与 more 相反,但功能更多" 的分页查看器

含义 :用 less 分页查看器打开 app.log 文件

为什么用 less?

  • 打开大文件时,不会一次性全部读入内存

  • 可以上下翻页(more 只能向下)

  • 支持搜索、跳转等多种功能

    7. 实时监控日志中的错误(模拟)

    新开一个终端窗口执行:echo "新的ERROR日志" >> app.log

    原窗口执行:

    tail -f app.log | grep --line-buffered "ERROR"

部分 全称/含义
grep Global Regular Expression Print - 全局正则表达式打印
--line-buffered 行缓冲模式 - 每收到一行就立即输出,不等待缓冲区满
"ERROR" 要搜索的字符串
隐含参数 标准输入读取(因为前面有管道)

第四阶段:部署真实Java项目

4.1 上传JAR包到服务器

复制代码
# 在你的本地电脑上执行(不是在服务器上)
# 上传JAR包到服务器的~/java-lab/目录
scp /path/to/your/my-app.jar root@192.168.1.100:~/java-lab/

# 如果还没有JAR包,可以先从网络下载一个Demo JAR包
# wget https://github.com/spring-projects/spring-boot/raw/main/spring-boot-project/spring-boot-docs/spring-boot-docs-modular/build/libs/demo.jar -O my-app.jar

4.2 部署并后台运行

复制代码
# 进入服务器上的工作目录
cd ~/java-lab

# 查看JAR包是否上传成功
ls -lh *.jar

# 后台运行真实Java应用
# - -Dserver.port=8081:指定端口(避免冲突)
# - -Xms256m -Xmx512m:设置JVM堆内存
# - 日志输出到 logs/app.log
nohup java -Dserver.port=8081 -Xms256m -Xmx512m -jar my-app.jar > logs/app.log 2>&1 &

# 保存进程ID,方便后续管理
echo $! > app.pid
echo "应用已启动,PID: $(cat app.pid)"

# 验证进程是否正常运行
ps -ef | grep java
# 或使用jps(需要JDK环境)
jps -l

4.3 验证应用是否可访问

复制代码
# 如果应用有HTTP接口,可以用curl测试
curl http://localhost:8081/actuator/health
# 或通用的端口监听检查
netstat -tulnp | grep 8081

4.4 查看真实应用日志

复制代码
# 查看启动日志
tail -50 logs/app.log

# 实时追踪日志
tail -f logs/app.log

# 搜索错误日志
grep -i "error" logs/app.log
grep -i "exception" logs/app.log

# 查看特定时间段的日志(假设日志格式包含时间)
grep "2025-05-04 10:" logs/app.log

4.5 进程管理

复制代码
# 查看Java进程
ps -ef | grep my-app.jar
ps aux | grep java

# 优雅停止(推荐)
kill -15 $(cat app.pid)

# 强制停止(慎用,可能导致数据丢失)
# kill -9 $(cat app.pid)

# 重新启动
nohup java -Dserver.port=8081 -Xms256m -Xmx512m -jar my-app.jar > logs/app.log 2>&1 &
echo $! > app.pid

第五阶段:权限与用户管理

复制代码
# 1. 查看文件权限
ls -l my-app.jar

# 2. 修改权限(JAR包通常不需要执行权限,但可以练习)
chmod 755 my-app.jar   # rwxr-xr-x

# 3. 用户管理(需要root权限)
# 创建一个专门运行Java应用的用户
sudo useradd -m javauser
# 修改文件所有者
sudo chown javauser:javauser my-app.jar
sudo chown -R javauser:javauser logs/
ls -l

第六阶段:网络与磁盘排查

复制代码
# 1. 磁盘空间查看
df -h

# 2. 目录大小查看
du -sh ~/java-lab/
du -sh ~/java-lab/logs/

# 3. 检查端口占用(重点)
netstat -tulnp | grep 8081
# 查看哪个进程占用了端口
lsof -i:8081   # 需要先安装 lsof: yum install lsof

# 4. 测试网络连通性
ping -c 3 google.com
curl -I http://localhost:8081

第七阶段:远程传输与压缩打包

复制代码
# 1. 打包整个Java项目目录
tar -zcvf myapp-full.tar.gz ~/java-lab/
ls -lh myapp-full.tar.gz

# 2. 解压练习
mkdir extract_test
tar -zxvf myapp-full.tar.gz -C extract_test/

# 3. zip格式练习
zip -r myapp-backup.zip ~/java-lab/logs/
unzip -l myapp-backup.zip   # 查看压缩包内容
unzip myapp-backup.zip -d unzip_test/

# 4. 从服务器下载日志到本地(在本地机器执行)
scp root@192.168.1.100:~/java-lab/logs/app.log ./app.log

# 5. 直接从网络下载依赖(在服务器上执行)
wget https://repo1.maven.org/maven2/org/springframework/boot/spring-boot/2.7.18/spring-boot-2.7.18.jar

第八阶段:进阶故障排查(使用真实JVM工具)

前提:服务器上已安装JDK(不仅仅是JRE),且Java应用正在运行。

8.1 jps - 查看Java进程

复制代码
# 列出所有Java进程
jps -l
# 输出示例:
# 12345 my-app.jar
# 67890 sun.tools.jps.Jps

# 获取你应用的PID
APP_PID=$(jps -l | grep my-app | awk '{print $1}')
echo $APP_PID

8.2 jstat - 查看GC情况

复制代码
# 每1秒输出一次GC统计,共输出5次
jstat -gcutil $APP_PID 1000 5

# 重点关注:
# - YGC: Young GC次数
# - FGC: Full GC次数
# - FGCT: Full GC总耗时

# 持续监控(按Ctrl+C停止)
jstat -gcutil $APP_PID 2000

8.3 jstack - 查看线程堆栈

复制代码
# 生成线程快照(排查死锁、线程阻塞)
jstack $APP_PID > thread_dump_$(date +%Y%m%d_%H%M%S).txt

# 查看文件内容
less thread_dump_*.txt

# 快速检查是否有死锁
jstack $APP_PID | grep -A 10 "deadlock"

8.4 top + jstack 定位CPU飙升问题

复制代码
# 1. 用top查看哪个Java进程占用CPU高
top -c

# 2. 按 H 键显示线程(在top界面中)
# 找到CPU占用最高的线程ID(TID)

# 3. 假设TID=12345,转换为16进制
printf "%x\n" 12345
# 输出: 3039

# 4. 用jstack查看该线程的堆栈
jstack $APP_PID | grep -A 20 "0x3039"

8.5 jmap - 查看堆内存

警告jmap -dump:live 会触发Full GC,导致应用暂停,生产环境谨慎使用!

复制代码
# 查看堆内存概况
jmap -heap $APP_PID

# 查看堆中对象统计(不会STW,相对安全)
jmap -histo $APP_PID | head -30

# 生成堆转储文件(会触发Full GC,谨慎!)
jmap -dump:live,format=b,file=heap_$(date +%Y%m%d).hprof $APP_PID
# 生成的文件可以用MAT、VisualVM等工具分析

第九阶段:补充命令练习

9.1 软链接和环境变量

复制代码
# 1. 创建软链接(方便版本切换)
ln -s ~/java-lab/my-app.jar ~/current-app.jar
ls -la ~/ | grep current

# 2. 查看历史命令
history | tail -20

# 3. 搜索历史(Ctrl + R 交互式搜索)
# 按 Ctrl + R,然后输入 "grep"

# 4. 环境变量练习
export JAVA_OPTS="-Xms256m -Xmx512m"
echo $JAVA_OPTS

# 持久化配置(写入bashrc)
echo 'export JAPP_HOME=~/java-lab' >> ~/.bashrc
source ~/.bashrc
echo $JAPP_HOME

9.2 定时任务 - 自动重启/清理日志

复制代码
# 1. 创建一个重启脚本
cat > scripts/restart_app.sh << 'EOF'
#!/bin/bash
APP_DIR=/root/java-lab
PID_FILE=$APP_DIR/app.pid
LOG_FILE=$APP_DIR/logs/app.log

# 优雅停止
if [ -f $PID_FILE ]; then
    kill -15 $(cat $PID_FILE)
    sleep 5
fi

# 启动新进程
cd $APP_DIR
nohup java -Dserver.port=8081 -Xms256m -Xmx512m -jar my-app.jar >> $LOG_FILE 2>&1 &
echo $! > $PID_FILE
echo "$(date): 应用已重启" >> $LOG_FILE
EOF
chmod +x scripts/restart_app.sh

# 2. 创建日志清理脚本(保留最近7天日志)
cat > scripts/cleanup_logs.sh << 'EOF'
#!/bin/bash
find /root/java-lab/logs -name "*.log" -mtime +7 -delete
find /root/java-lab -name "*.hprof" -mtime +3 -delete
EOF
chmod +x scripts/cleanup_logs.sh

# 3. 添加定时任务
crontab -e
# 在编辑器中输入:
# 每天凌晨2点重启应用
# 0 2 * * * /root/java-lab/scripts/restart_app.sh
# 每天凌晨3点清理旧日志
# 0 3 * * * /root/java-lab/scripts/cleanup_logs.sh

# 4. 查看定时任务
crontab -l

9.3 screen会话练习

复制代码
# 1. 创建新会话(适合长时间运行的监控任务)
screen -S app-monitor

# 2. 在会话中实时监控日志
cd ~/java-lab && tail -f logs/app.log

# 3. 分离会话:按 Ctrl + A,然后按 D

# 4. 列出所有会话
screen -ls

# 5. 重新连接
screen -r app-monitor

# 6. 在会话中执行Java应用(另一种运行方式,不用nohup)
screen -S java-app
java -jar my-app.jar
# 按 Ctrl+A+D 分离,应用继续运行

第十阶段:sed和awk练习(日志分析)

复制代码
# 1. 准备日志文件(从真实应用日志中提取部分行)
head -100 logs/app.log > sample.log

# 2. sed - 替换和删除
# 替换IP地址
sed -i 's/192.168.1.100/127.0.0.1/g' sample.log
# 删除空行
sed -i '/^$/d' sample.log

# 3. awk - 按列处理
# 假设日志格式:2025-05-04 10:00:00 INFO [com.demo] 消息内容
# 统计每种日志级别的数量
awk '{print $3}' logs/app.log | sort | uniq -c | sort -nr

# 统计每个小时的请求数(如果日志有对应格式)
awk '{print $2}' logs/app.log | cut -d: -f1 | sort | uniq -c

第十一阶段:应用下线与清理

复制代码
# 1. 优雅停止应用
kill -15 $(cat app.pid)

# 2. 确认进程已停止
ps -ef | grep my-app.jar

# 3. 清理定时任务
crontab -e
# 删除之前添加的任务行

# 4. 备份重要数据
tar -zcvf backup_$(date +%Y%m%d).tar.gz logs/ application.yml

# 5. 删除练习目录(慎用!)
# rm -rf ~/java-lab
相关推荐
前端之虎陈随易1 小时前
为什么今天还会有新语言?MoonBit 想解决什么问题?
大数据·linux·javascript·人工智能·算法·microsoft·typescript
身如柳絮随风扬2 小时前
Java对象在计算机中的执行原理:从JVM内存模型到对象创建全过程
java·开发语言·jvm
夕除2 小时前
spring boot
java·spring boot·后端
嵌入式×边缘AI:打怪升级日志2 小时前
Linux 驱动开发核心自测题库(面试官问答版)
linux·运维·驱动开发
想唱rap2 小时前
传输层协议之UDP
java·linux·网络·c++·网络协议·mysql·udp
春蕾夏荷_7282977252 小时前
2、c++ acl tcp服务器客户端简单实例-客户端(2)
服务器·c++·tcp/ip
野生技术架构师2 小时前
我总结了这份2026最新版Java面试题库(背完这一套就够了)
java·开发语言·面试
AIGC设计所2 小时前
网络安全8大就业领域和待遇对比!
运维·开发语言·网络·安全·web安全·php
网安薯条2 小时前
Kali Linux 虚拟机安装与基础配置保姆级图文教程
linux·运维·网络·安全·web安全·网络安全