# 查看系统版本$cat /etc/os-release NAME="CentOS Linux" VERSION="7 (Core)" # 查看内核$uname -r 3.10.0-1160.el7.x86_64 # 修改主机名(永久)$hostnamectl set-hostname cloudlab$hostname cloudlab
uname -r 只显内核版本,-a 显全部。hostnamectl 是CentOS7+命令,同时写入 /etc/hostname。$pwd # 显示当前目录 /root$cd / # 切换到根目录$ls bin boot dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var$cd ~ # 回家目录(等同 cd 或 cd $HOME)$cd - # 回到上次所在目录
/etc 配置 | /var 日志数据 | /home 用户家 | /opt 第三方软件 | /dev 设备 | /proc 内核虚拟文件 | /tmp 临时文件# 创建多级目录(-p 自动创建父级)$mkdir -p /opt/project/{src,bin,conf,logs}$ls /opt/project/ bin conf logs src # 创建文件 & 写入内容$touch /opt/project/src/app.py$echo "hello" > /opt/project/src/readme.txt # > 覆盖写入$echo "world" >> /opt/project/src/readme.txt # >> 追加写入 # 查看详情$ls -la /opt/project/src/ -rw-r--r-- 1 root root 12 ... readme.txt -rw-r--r-- 1 root root 0 ... app.py # 复制/移动/重命名$cp -r /opt/project/src /opt/project/src_bak # -r 递归复制目录$mv /opt/project/src/readme.txt /opt/project/src/README.md # 移动=重命名 # 删除(危险操作,先ls确认路径!)$rm -rf /opt/project/src_bak
rm -rf 没有回收站!删除不可恢复。永远不要 rm -rf /。养成习惯:先 ls 确认再删除。$cat /etc/hostname # 查看全部内容$head -10 /etc/passwd # 前10行$tail -f /var/log/messages # 实时跟踪日志(Ctrl+C退出)$less /etc/services # 分页看大文件(空格翻页 q退出) # 搜索文件$find /etc -name "*.conf" # 按名字找$find /var/log -size +10M # 找大于10M的$find /tmp -mtime +30 -delete # 删30天前的文件 # 在文件内容中搜索$grep "root" /etc/passwd root:x:0:0:root:/root:/bin/bash$grep -rn "error" /var/log/ # -r递归 -n行号
find 实时搜目录树(慢但准),locate 查数据库(快但可能不新,需先 updatedb)。grep 搜文件内容。$ls -la app.py -rw-r--r-- 1 root root 0 ... # 权限位解读:rw- | r-- | r-- # 属主 属组 其他 # 读写 只读 只读 # # 数字算法:r=4 w=2 x=1 # rw- = 4+2+0 = 6 # r-- = 4+0+0 = 4 # 所以 rw-r--r-- = 644 # # 常用权限速记: # 755 = rwxr-xr-x 可执行文件/目录 # 644 = rw-r--r-- 普通文件 # 700 = rwx------ 私密目录(如.ssh) # 600 = rw------- 私密文件(如密钥)
$chmod 755 script.sh # 数字方式$chmod +x script.sh # 符号方式(加执行权限)$chmod -R 755 /opt/project # -R 递归整个目录 # 创建组和用户$groupadd www$useradd -m -s /bin/bash -G www webadmin # -m创建家目录 -G附加组$passwd webadmin # 设置密码 # 验证$id webadmin uid=1001(webadmin) gid=1001(webadmin) groups=1001(webadmin),1002(www) # 改属主$chown webadmin:www /opt/project/logs$chmod 770 /opt/project/logs # 属主和组可读写执行,其他无权限
useradd 创建 | usermod -aG group user 加组 | userdel -r 删除含家目录 | 查用户 cat /etc/passwd | 查组 cat /etc/group# 打包压缩(c创建 z用gzip f文件名)$tar czf /tmp/backup.tar.gz /opt/project # 查看内容(不解压)$tar tzf /tmp/backup.tar.gz # 解压到指定目录$tar xzf /tmp/backup.tar.gz -C /tmp/restore
czf (Create Zip File),解压 xzf (eXtract Zip File)。.tar.bz2 用 cjf/xjf。# 打开文件$vim /etc/hosts # 命令模式(默认): # i 光标前插入 a 光标后插入 o 下方新行插入 # dd 删除行 yy 复制行 p 粘贴 u 撤销 # /word 搜索(n下一个 N上一个) # gg 到开头 G 到末尾 # 按 Esc 回到命令模式 # 末行模式(命令模式下按 : 进入): # :w 保存 # :q 退出 # :wq 保存退出 # :q! 强制退出不保存 # :set nu 显示行号 # :%s/old/new/g 全局替换
/etc/hosts → 按 G 到末尾 → 按 o 新行 → 输入 192.168.1.100 myserver → 按 Esc → 输入 :wq 保存退出 → cat /etc/hosts 验证。# 编辑 ~/.bashrc 添加别名$vim ~/.bashrc # 末尾加: alias ll='ls -la' alias grep='grep --color=auto'$source ~/.bashrc # 立即生效$ll # 测试 # 创建软链接(快捷方式)$ln -s /opt/project/src/app.py /usr/local/bin/myapp$ls -la /usr/local/bin/myapp lrwxrwxrwx ... myapp -> /opt/project/src/app.py # 创建硬链接(共享inode,删源文件链接仍有效)$ln /opt/project/src/README.md /tmp/hard_link$ls -li /opt/project/src/README.md /tmp/hard_link 262145 ... README.md 262145 ... hard_link # inode号相同=同一文件
$yum install -y epel-release && yum install -y nginx # systemctl 全流程$systemctl start nginx # 启动$systemctl status nginx # 查状态 → 看到 active (running)$systemctl enable nginx # 开机自启$systemctl stop nginx # 停止$systemctl restart nginx # 重启$systemctl reload nginx # 热加载配置(不断连接)$nginx -t # 检查配置语法 nginx: configuration file ... test is successful
reload 比 restart 优雅 — 不中断现有连接,只重新加载配置文件。生产环境优先用 reload。$ps aux | grep nginx # 搜索进程 root 1234 ... nginx: master process nginx 1235 ... nginx: worker process$top # 实时监控(q退出 M按内存排 P按CPU排) # 杀进程$kill 1234 # SIGTERM(优雅终止)$kill -9 1234 # SIGKILL(强制,最后手段)$killall nginx # 按名字杀 # 后台运行$nohup python3 server.py & # nohup 防止退终端后进程被杀
kill 默认发SIGTERM(15),程序可捕获优雅退出。kill -9 发SIGKILL(9)不可捕获。生产环境先 kill,无效再 kill -9。$lsblk # 查看块设备 sda 20G ├─sda1 20G / sdb 10G ← 新磁盘$fdisk /dev/sdb # 分区 # 交互:n → p → 1 → 回车 → 回车 → w$mkfs.xfs /dev/sdb1 # 格式化$mkdir /mnt/data$mount /dev/sdb1 /mnt/data # 挂载$df -h | grep sdb /dev/sdb1 10G 33M 10G 1% /mnt/data # 永久挂载(写入fstab)$echo '/dev/sdb1 /mnt/data xfs defaults 0 0' >> /etc/fstab$mount -a # 验证fstab配置
/etc/fstab 写错会导致系统无法启动!修改前 cp /etc/fstab /etc/fstab.bak 备份。写入后必须 mount -a 测试。[A]$ssh-keygen -t rsa -b 4096 # 生成密钥对(一路回车)[A]$ssh-copy-id root@192.168.1.102 # 把公钥复制到B[A]$ssh root@192.168.1.102 # 测试免密登录 → 不用输密码
ssh-keygen 生成私钥 ~/.ssh/id_rsa(保密)和公钥 ~/.ssh/id_rsa.pub(公开)。ssh-copy-id 把公钥追加到对方 ~/.ssh/authorized_keys。登录时用私钥证明身份。# scp 简单复制$scp /tmp/backup.tar.gz root@192.168.1.102:/tmp/ # 上传$scp root@192.168.1.102:/var/log/nginx.log /tmp/ # 下载$scp -r /opt/project root@192.168.1.102:/opt/ # 复制目录 # rsync 增量同步(只传变化的部分,比scp高效)$rsync -avz /opt/project/ root@192.168.1.102:/opt/project/ # -a 归档(保权限/时间) -v 显示过程 -z 压缩传输
scp,大量文件或定期同步用 rsync(增量传输+断点续传)。#!/bin/bash
BACKUP_DIR="/backup"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
tar czf ${BACKUP_DIR}/project_${DATE}.tar.gz /opt/project
echo "[$(date)] Backup done" >> /var/log/backup.log
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete$chmod +x /opt/backup.sh$/opt/backup.sh # 手动测试 # 设置cron定时任务$crontab -e 0 2 * * * /opt/backup.sh # 每天凌晨2点执行 # cron格式:分 时 日 月 周 命令 # ┌───── 分 (0-59) # │ ┌─── 时 (0-23) # │ │ ┌─ 日 (1-31) # │ │ │ ┌ 月 (1-12) # │ │ │ │ ┌ 周(0-7) # 0 2 * * * # # 更多示例: # */5 * * * * 每5分钟 # 0 */2 * * * 每2小时 # 0 9 * * 1-5 工作日9点$crontab -l # 查看任务列表
crontab -e 编辑,-l 列出,-r 删除全部。/opt/scripts/ 下集中存放脚本#!/bin/bash
echo "===== 系统信息 ====="
echo "主机名: $(hostname)"
echo "IP: $(hostname -I | awk '{print $1}')"
echo "内核: $(uname -r)"
echo "运行: $(uptime -p)"
echo "CPU: $(nproc) 核 | 负载: $(uptime | awk -F'load average:' '{print $2}')"
free -h | awk '/Mem/{printf "内存: %s/%s (%.0f%%)\n",$3,$2,$3/$2*100}'
df -h | grep '^/dev/' | awk '{printf "磁盘 %s: %s used (%s)\n",$6,$3,$5}'$(cmd) 命令替换,把命令输出嵌入字符串。awk 提取字段。nproc 显示CPU核数。free -h 显示内存。#!/bin/bash
# 用法: ./check_service.sh nginx
SERVICE=${1:-nginx}
LOG="/var/log/service_monitor.log"
if systemctl is-active --quiet $SERVICE; then
echo "[$(date)] $SERVICE OK" >> $LOG
else
echo "[$(date)] $SERVICE DOWN! Restarting..." >> $LOG
systemctl restart $SERVICE
sleep 2
if systemctl is-active --quiet $SERVICE; then
echo "[$(date)] $SERVICE restarted OK" >> $LOG
else
echo "[$(date)] CRITICAL: $SERVICE restart FAILED!" >> $LOG
fi
fi${1:-nginx} 表示取第1个参数,如果没传则默认值为nginx。systemctl is-active --quiet 安静检查,仅通过返回码判断(0=运行中)。建议加入cron每5分钟执行:*/5 * * * * /opt/scripts/check_service.sh nginx#!/bin/bash
USER_FILE=$1
[ -z "$USER_FILE" ] && echo "用法: $0 <用户名文件>" && exit 1
[ ! -f "$USER_FILE" ] && echo "文件不存在: $USER_FILE" && exit 1
while read -r name; do
[ -z "$name" ] && continue # 跳过空行
[[ "$name" =~ ^# ]] && continue # 跳过注释
if id "$name" &>/dev/null; then
echo "[跳过] $name 已存在"
else
useradd -m -s /bin/bash "$name"
echo "$name:Pass@2026" | chpasswd
echo "[创建] $name 成功"
fi
done < "$USER_FILE"$echo -e "alice\nbob\ncharlie" > /tmp/users.txt$bash /opt/scripts/create_users.sh /tmp/users.txt [创建] alice 成功 [创建] bob 成功 [创建] charlie 成功
while read line; do...done < file 逐行读文件标准写法。id user &>/dev/null 检查用户是否存在。chpasswd 批量设密码。$grep "root" /etc/passwd # 基本搜索$grep -i "error" /var/log/messages # -i 忽略大小写$grep -v "^#" /etc/nginx/nginx.conf # -v 反选(去掉注释行)$grep -c "Failed" /var/log/secure # -c 统计匹配行数$grep -rn "listen" /etc/nginx/ # -r递归 -n行号$grep -E "^root|^nginx" /etc/passwd # -E 扩展正则(多个模式用|)
$echo "hello world" | sed 's/hello/hi/g' # 替换 hi world$sed -i 's/192.168.1.100/10.0.0.100/g' conf # -i 直接改文件$sed -i '/^#/d' config.txt # 删注释行$sed -i '/^$/d' config.txt # 删空行$sed -n '5,10p' file.txt # 只打印第5-10行
sed -i 直接改源文件不可撤销!先不加 -i 预览,或用 sed -i.bak 自动备份。$awk -F: '{print $1}' /etc/passwd # -F: 以冒号分隔,取第1字段 root daemon webadmin$awk -F: '$3>=1000{print $1,$3}' /etc/passwd # 条件:UID>=1000 webadmin 1001 # 实战:Nginx日志TOP10 IP$awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10 523 192.168.1.50 312 10.0.0.15
$1 $2 $3...($0=整行)。支持条件、运算、BEGIN/END块。本身是一门小型编程语言。yum install -y yum-utils && yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo && yum install -y docker-ce && systemctl start docker && systemctl enable docker$docker pull nginx:latest # 拉镜像$docker run -d -p 8080:80 --name web nginx # 运行(-d后台 -p端口映射)$curl http://localhost:8080 # 验证$docker ps # 运行中的容器$docker ps -a # 所有容器(含已停止)$docker logs -f web # 实时日志$docker exec -it web bash # 进入容器$docker stop web && docker rm web # 停止并删除
-d=后台 | -p 8080:80=宿主机8080→容器80 | --name=命名 | exec -it=交互终端。容器删除后内部修改丢失,需数据卷持久化。# 绑定挂载$mkdir /myhtml && echo "<h1>Hello</h1>" > /myhtml/index.html$docker run -d -p 80:80 -v /myhtml:/usr/share/nginx/html nginx # 修改 /myhtml/index.html → 容器内网页实时变化 # 命名卷$docker volume create mydata$docker run -d -v mydata:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123 mysql:8
FROM python:3.9-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY app.py . EXPOSE 5000 CMD ["python", "app.py"]
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello(): return 'Hello from Docker!'
if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)$echo "flask" > requirements.txt$docker build -t myflask:v1 .$docker run -d -p 5000:5000 myflask:v1$curl localhost:5000 Hello from Docker!
CMD 定义启动命令。version: '3.8'
services:
web:
image: nginx
ports: ["80:80"]
depends_on: [app]
app:
build: .
expose: ["5000"]
redis:
image: redis:alpine$docker-compose up -d # 后台启动$docker-compose ps # 查看状态$docker-compose logs -f app # 看app日志$docker-compose down # 停止删除$docker-compose up -d --build # 重新构建启动
depends_on 控制启动顺序。同一Compose的容器自动在同一网络,可用服务名互访(如 http://app:5000)。expose 仅容器间,ports 映射到宿主机。pip install psutil paramiko pyyaml#!/usr/bin/env python3
import psutil, socket
from datetime import datetime
CPU_WARN, MEM_WARN, DISK_WARN = 80, 85, 90
cpu = psutil.cpu_percent(interval=1)
mem = psutil.virtual_memory()
print(f"=== {socket.gethostname()} [{datetime.now():%Y-%m-%d %H:%M}] ===")
print(f"CPU: {cpu}% 内存: {mem.percent}% ({mem.used//1024//1024}M/{mem.total//1024//1024}M)")
for p in psutil.disk_partitions():
u = psutil.disk_usage(p.mountpoint)
flag = " ⚠️" if u.percent > DISK_WARN else ""
print(f"磁盘 {p.mountpoint}: {u.percent}%{flag}")
if cpu > CPU_WARN: print(f"⚠️ CPU {cpu}% 超阈值!")
if mem.percent > MEM_WARN: print(f"⚠️ 内存 {mem.percent}% 超阈值!")psutil 跨平台系统监控库。cpu_percent(interval=1) 采样1秒。virtual_memory() 获取内存信息。生产中可把告警发邮件/钉钉。#!/usr/bin/env python3
import paramiko
SERVERS = [
{"host": "192.168.1.101", "user": "root", "key": "/root/.ssh/id_rsa"},
{"host": "192.168.1.102", "user": "root", "key": "/root/.ssh/id_rsa"},
]
def run_remote(host, user, key, cmd):
c = paramiko.SSHClient()
c.set_missing_host_key_policy(paramiko.AutoAddPolicy())
c.connect(host, username=user, key_filename=key, timeout=10)
_, stdout, _ = c.exec_command(cmd)
result = stdout.read().decode().strip()
c.close()
return result
for s in SERVERS:
print(f"\n{'='*40}\n{s['host']}\n{'='*40}")
for cmd in ["hostname", "uptime", "df -h|grep '/$'", "free -h|awk '/Mem/{print $3\"/\"$2}'"]:
print(f" {cmd} → {run_remote(s['host'], s['user'], s['key'], cmd)}")paramiko 是Python的SSH库。SSHClient.connect() 连接,exec_command() 执行远程命令返回stdout/stderr。前提:已配好SSH密钥免密。AutoAddPolicy 自动接受未知主机(生产环境应使用白名单)。yum install -y ansible[web] 192.168.1.101 192.168.1.102 [db] 192.168.1.103 [all:vars] ansible_user=root
$ansible all -m ping # 测试连通 192.168.1.101 | SUCCESS => {"ping": "pong"}$ansible web -m shell -a "df -h" # 查磁盘$ansible web -m yum -a "name=nginx state=present" # 安装nginx$ansible web -m service -a "name=nginx state=started enabled=yes"
-m 指定模块 -a 传参数。常用模块:ping shell yum copy service file template。---
- name: Deploy Nginx
hosts: web
become: yes # sudo提权
vars:
nginx_port: 80
tasks:
- name: Install EPEL
yum: name=epel-release state=present
- name: Install Nginx
yum: name=nginx state=latest
- name: Deploy config
template: src=nginx.conf.j2 dest=/etc/nginx/conf.d/mysite.conf
notify: Restart Nginx # 配置变了才触发handler
- name: Start Nginx
service: name=nginx state=started enabled=yes
handlers:
- name: Restart Nginx
service: name=nginx state=restarted$ansible-playbook deploy_nginx.yml PLAY RECAP *** 192.168.1.101: ok=5 changed=3 failed=0 192.168.1.102: ok=5 changed=3 failed=0
ok=已是期望状态 changed=做了修改。幂等性:再执行一次changed变为0。handler 仅在被notify且task changed时执行,避免不必要重启。template 模块支持Jinja2变量替换(如 {{ nginx_port }})。