Linux & Shell 实用干货

Linux 启动流程图

必须掌握的"灵魂三问"(面试/排错核心)

不管你是开发还是运维,下面这三个节点是你绝对要刻在脑子里的,因为它们是排查系统启动故障的"救命稻草":

终点(PID=1 的进程):图中最后调用的 /usr/lib/systemd/systemd。这是所有进程的"老祖宗"。面试考点:Linux 启动后第一个用户进程是什么?(答:systemd,PID 恒为 1)。

用户自定义入口(/etc/rc.d/rc.local):图中明确标出了"用户自定义的开机自启动服务"。这是你作为程序员最常用的!如果你写了个脚本想在机器开机时自动跑起来,就放在这里。实战意义:服务器重启后你的 Java/大数据服务没起来,你第一反应就是去检查这个文件有没有配好。

登录界面(/bin/login):输入用户名密码的地方。如果连这一步都到不了,说明系统底层(内核或 Systemd 核心目标)坏了,普通用户无解,需要进救援模式。

Linux 干货

这份干货涵盖了 Linux 日常开发、运维、面试中最核心的知识点,去掉了安装流程等入门内容,直接给你最硬核的部分

一、10 个高频命令(含生产级用法)

命令 核心用途 生产级示例
grep 文本搜索 `ps -ef
awk 文本分析处理 `ps -ef
sed 流式编辑 sed -i 's/旧/新/g' file 批量替换;sed -i '/^#/d' file 删除注释行
find 文件查找 find / -name "*.log" -mtime +7 -exec rm {} \; 删除7天前日志
netstat 网络端口查看 `netstat -lntp
tail 查看文件尾部 tail -f app.log 实时看日志;tail -n 100 app.log 看最后100行
scp/rsync 跨机传输 scp file root@ip:/pathrsync -avz --delete /src/ /dst/ 增量同步
systemctl 服务管理 systemctl start/stop/status/restart/enable nginx
tar 打包压缩 tar -zcvf archive.tar.gz /pathtar -zxvf archive.tar.gz -C /dst
kill 终止进程 kill -15 PID(优雅停止);kill -9 PID(强制杀死,谨慎使用)

二、文件权限(面试必问)

2.1 权限数字含义

复制代码
rwx = 7    rw- = 6    r-x = 5    r-- = 4

口诀:所有者 > 所属组 > 其他人,从高位到低位

2.2 常用权限

bash 复制代码
chmod 755 file   # 所有者rwx,其他人rx(目录常用)
chmod 644 file   # 所有者rw,其他人r(文件常用)
chown user:group file   # 修改所属用户和组

2.3 软链接 vs 硬链接(高频面试)

对比项 软链接(ln -s 硬链接(ln
本质 指向源文件的路径(快捷方式) 指向同一个 inode(同一份数据)
跨文件系统 ✅ 可以 ❌ 不可以
目录 ✅ 可以 ❌ 不可以
删除源文件 链接失效(红色闪烁) 硬链接仍然可用(数据还在)
inode 号 不同 相同(判断硬链接的标准)

三、网络配置(企业级必会)

3.1 三种网络模式一句话总结

  • 桥接(Bridged) :虚拟机独立 IP,和宿主机平级,局域网内其他机器可直连。
  • NAT :虚拟机共享宿主机 IP 上网,宿主机和虚拟机互通,外网无法直接访问虚拟机(最常用)。
  • Host-Only纯内网,只能与宿主机通信,不能上网(安全性高)。

3.2 配置文件(CentOS 7)

bash 复制代码
vi /etc/sysconfig/network-scripts/ifcfg-ens33

关键配置:

复制代码
BOOTPROTO=static          # dhcp 或 static
ONBOOT=yes                # 开机自启(最重要!)
IPADDR=192.168.100.100    # 静态 IP
NETMASK=255.255.255.0
GATEWAY=192.168.100.2
DNS1=114.114.114.114

3.3 防火墙快速命令

bash 复制代码
systemctl stop firewalld   # 本次关闭
systemctl disable firewalld # 永久关闭(开发/学习环境常用)
systemctl start firewalld   # 启动
firewall-cmd --add-port=8080/tcp --permanent  # 开放端口
firewall-cmd --reload       # 重新加载

四、用户与组(运维基础)

4.1 三张核心文件

  • /etc/passwd:用户信息(用户名:密码占位:UID:GID:描述:家目录:Shell)
  • /etc/shadow:加密密码(root 才能看)
  • /etc/group:组信息

4.2 用户操作

bash 复制代码
useradd zhangsan -g java -G bigdata   # 指定主组和附属组
passwd zhangsan                        # 设置密码
usermod -aG docker zhangsan            # 追加附属组(-a 必须加!否则覆盖)
userdel -r zhangsan                    # 删除用户及家目录
su - zhangsan                          # 切换用户(带 - 切换环境变量)

4.3 sudo 授权(重要)

bash 复制代码
visudo
# 添加一行:zhangsan ALL=(ALL) ALL   # 允许执行所有 sudo 命令

4.4 主组 vs 附属组

  • 主组(Primary Group,-g :每个用户有且只有一个,创建文件时的默认所属组
  • 附属组(Supplementary Group,-G :可有多个,用于共享权限
  • 修改主组用 usermod -g,修改附属组用 usermod -G

五、定时任务(Cron)

5.1 格式

复制代码
* * * * * command
- - - - -
分 时 日 月 周

5.2 常用示例

bash 复制代码
*/5 * * * * /script/check.sh      # 每5分钟
0 2 * * * /script/backup.sh       # 每天凌晨2点
0 2 * * 6 /script/backup.sh       # 每周六凌晨2点
0 8-18/2 * * * /script/task.sh    # 每天8-18点每2小时

5.3 关键命令

bash 复制代码
crontab -e   # 编辑(修改后自动生效)
crontab -l   # 查看
crontab -r   # 删除所有(危险!)

六、软件安装(三种方式对比)

方式 优点 缺点 场景
yum 自动解决依赖,最简单 版本可能不是最新 90% 场景用这个
rpm 离线可装 依赖需手动解决 下载好的 .rpm 包
源码编译 最灵活,可自定义参数 编译慢,需装 gcc Nginx/Redis 等特殊需求

七、Linux 三剑客(面试加分项)

7.1 grep(搜索)

bash 复制代码
grep -i "error" app.log        # 忽略大小写
grep -r "Exception" /logs/     # 递归搜索
grep -v "^#" /etc/nginx.conf   # 过滤掉注释行
grep -E "error|fatal" app.log  # 正则匹配多个

7.2 sed(替换编辑)

bash 复制代码
sed -i 's/old/new/g' file      # 全局替换(-i 直接改文件)
sed -i '/^$/d' file            # 删除空行
sed -n '10,20p' file           # 只显示10-20行

7.3 awk(取列/统计)

bash 复制代码
awk '{print $1}' file          # 取第一列
awk -F: '{print $1,$3}' /etc/passwd  # 以:分隔取第1、3列
awk '{sum+=$1} END {print sum}' file # 求和
ps -ef | awk '{print $2}'      # 取进程 PID

八、免密登录(集群必备)

8.1 三步走

bash 复制代码
# 1. 生成密钥对
ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa

# 2. 拷贝公钥到目标机器
ssh-copy-id root@node02

# 3. 测试
ssh node02   # 无需密码直接登录

8.2 原理(非对称加密)

  • 公钥放目标机 ~/.ssh/authorized_keys
  • 私钥留本地 ~/.ssh/id_rsa
  • 目标机用公钥加密随机字符串 → 本地用私钥解密 → 对比一致即免密

8.3 忽略首次连接提示(自动化脚本必配)

bash 复制代码
ssh -o StrictHostKeyChecking=no node02
# 或永久配置:/etc/ssh/ssh_config 添加 StrictHostKeyChecking no

九、systemd 服务管理(生产必会)

9.1 服务文件模板

ini 复制代码
[Unit]
Description=My Service
After=network.target

[Service]
Type=simple              # 或 forking
ExecStart=/opt/app/start.sh
ExecStop=/opt/app/stop.sh
Restart=on-failure
User=appuser
WorkingDirectory=/opt/app

[Install]
WantedBy=multi-user.target

9.2 常用命令

bash 复制代码
systemctl daemon-reload            # 修改 .service 后重载
systemctl start/stop/restart app   # 管理服务
systemctl enable app               # 设置开机自启
systemctl status app               # 查看状态
journalctl -u app -f               # 看服务日志

十、进程与系统状态(运维排查)

10.1 关键命令

bash 复制代码
ps -ef | grep java     # 查 Java 进程
top                    # 实时看 CPU/内存(按 P 按 CPU 排序,按 M 按内存排序)
free -h                # 看内存(-h 人类可读)
df -h                  # 看磁盘
du -sh *               # 看当前目录各文件大小
netstat -lntp          # 看所有监听的端口

10.2 kill 信号的差别(面试高频)

信号 命令 效果
SIGTERM kill -15 PID 优雅停止 ,可被捕获,程序可做清理(推荐
SIGKILL kill -9 PID 强制杀死,不可捕获,程序来不及清理(可能丢数据,谨慎!)

十一、环境变量(你的 PDF 讲得最全)

配置文件 生效范围 生效时机
/etc/profile 所有用户 登录时执行
/etc/profile.d/*.sh 所有用户(推荐放这里) 登录时自动加载
~/.bashrc 当前用户 每次打开 Shell 执行
~/.bash_profile 当前用户 登录时执行
export PATH=$PATH:/new/path 当前会话临时生效 关闭终端失效

十二、PDF 中隐藏的精华(你可能没注意到)

12.1 > vs >> vs 2>&1

bash 复制代码
>   # 覆盖写入
>>  # 追加写入
2>&1 # 错误输出重定向到标准输出(让错误和正常信息一起输出)
nohup command > app.log 2>&1 &  # 后台运行,所有日志写文件

12.2 /dev/null(黑洞)

bash 复制代码
command > /dev/null 2>&1   # 所有输出丢弃(静默运行)

12.3 source vs ./ 执行脚本

  • source script.sh当前 Shell 执行(环境变量会保留)
  • ./script.sh子 Shell 执行(环境变量不保留)

十三、一句话避坑指南(PDF 中的关键经验)

解决方案
改完网络配置连不上 检查 ONBOOT=yes + 防火墙是否关/端口是否开放
rm -rf 删错数据 永远用 rm -i 或用 mv/tmp 暂存,确认后再删
软链接失效 创建时用绝对路径,不要用相对路径
crontab -r 误删所有任务 备份习惯:crontab -l > cron.bak
免密不生效 检查 ~/.ssh/ 权限(700),authorized_keys 权限(600)
systemd 服务改了没生效 必须执行 systemctl daemon-reload

这 13 个模块覆盖了 PDF 中 90% 的生产实用内容,无论面试还是日常开发都够用了。建议把高频命令和配置模板收藏起来,用的时候直接查!

Shell 编程干货

这份 PDF 内容非常详实,我帮你把最核心、最常用、面试最爱问的部分提炼成一份速查干货,去掉冗长的解释,只留你在工作和面试中真正用得上的内容。

一、Shell 脚本执行方式(核心区别)

执行方式 命令 特点
bash/sh bash test.sh 新开子Shell执行,变量不共享
source / . source test.sh. test.sh 当前Shell执行,变量共享(环境变量必须用这种)
路径执行 ./test.sh chmod +x,本质也是新开子Shell
bash 复制代码
# 验证区别
export name=mrhelloworld   # 设置环境变量
bash test.sh               # ❌ 拿不到 $name(子Shell)
source test.sh             # ✅ 能拿到 $name(当前Shell)

💡 记住 :修改 /etc/profile 后必须 source /etc/profile 才能生效,就是因为需要用当前Shell加载。

二、变量(最常用语法)

2.1 定义与引用

bash 复制代码
name="zhangsan"            # 等号两边不能有空格!
echo $name                 # 输出 zhangsan
echo ${name}               # 推荐加花括号,便于识别边界
echo "My name is ${name}"  # 双引号会解析变量
echo 'My name is ${name}'  # 单引号原样输出

2.2 变量类型

类型 定义方式 作用范围
局部变量 name="zhangsan" 仅当前Shell
环境变量 export name="zhangsan" 当前Shell及子进程
只读变量 readonly name 不可修改、不可删除
位置参数 $1$2... 脚本接收的参数

2.3 特殊变量(面试必问)

变量 含义
$0 脚本文件名
$1~$9 第1~9个参数(10个以上用 ${10}
$# 参数个数
$* 所有参数(当成一个整体字符串)
$@ 所有参数(每个独立,推荐用这个)
$? 上一条命令的退出状态(0=成功,非0=失败)
$$ 当前Shell进程ID
bash 复制代码
# 使用示例
echo "参数个数: $#"
echo "所有参数: $@"
if [ $? -eq 0 ]; then echo "成功"; fi

2.4 命令结果赋值

bash 复制代码
# 两种方式等价,推荐第二种(更清晰)
info=`ls /usr`          # 反引号(容易看错)
info=$(ls /usr)         # 推荐!

三、字符串操作(高频)

3.1 拼接(最简单)

bash 复制代码
name="zhangsan"
age=18
str1=$name$age           # zhangsan18(无空格)
str2="$name $age"        # zhangsan 18(有空格)
str3="${name}同学${age}岁"  # 必须加花括号

3.2 获取长度

bash 复制代码
name="mrhelloworld"
echo ${#name}            # 12

3.3 截取(面试必考)

bash 复制代码
url="https://www.mrhelloworld.com"

# 从左边开始截取
echo ${url:8}            # www.mrhelloworld.com(从第8个开始)
echo ${url:8:11}         # www.mrhelloworld(取11个)

# 从右边开始截取(0- 表示从右数)
echo ${url:0-4}          # .com(右边取4个)
echo ${url:0-11:3}       # mrh(右边数11个,取3个)

# 从指定字符开始截取
echo ${url#*//}          # www.mrhelloworld.com(去掉 // 左边)
echo ${url##*.}          # com(去掉最后一个 . 左边)
echo ${url%.*}           # https://www.mrhelloworld(去掉 . 右边)

四、数值运算(别用 expr 了)

4.1 整数运算用 (( ))

bash 复制代码
a=10; b=20
echo $((a + b))          # 30
echo $((a * b))          # 200
echo $((a > b ? a : b))  # 20(三元运算)
((sum = a + b))
((i++))                  # 自增

4.2 小数运算用 bc

bash 复制代码
echo "scale=2; 10/3" | bc   # 3.33(scale控制小数位)
result=$(echo "scale=2; 10/3" | bc)

五、条件判断(面试必考)

5.1 三种写法对比

写法 说明 推荐度
[ condition ] 传统 test 命令 ⭐⭐
[[ condition ]] 增强版,支持正则和逻辑符 ⭐⭐⭐⭐⭐
(( condition )) 专门算数比较 ⭐⭐⭐⭐

5.2 常用判断

bash 复制代码
# 字符串
[[ "$a" == "$b" ]]        # 相等
[[ "$a" != "$b" ]]        # 不等
[[ -z "$a" ]]             # 是否为空
[[ -n "$a" ]]             # 是否非空

# 数值(用 (( )) 更优雅)
(( a == b ))
(( a > b ))
(( a >= b ))

# 文件
[[ -f "/path/file" ]]     # 是普通文件
[[ -d "/path/dir" ]]      # 是目录
[[ -e "/path/file" ]]     # 存在
[[ -r "/path/file" ]]     # 可读
[[ -w "/path/file" ]]     # 可写
[[ -x "/path/file" ]]     # 可执行
[[ -L "/path/file" ]]     # 是软链接

六、流程控制(模板直接抄)

6.1 if

bash 复制代码
if [[ condition ]]; then
    commands
elif [[ condition ]]; then
    commands
else
    commands
fi

6.2 case in(多分支)

bash 复制代码
case $num in
    1)
        echo "Monday"
        ;;
    2)
        echo "Tuesday"
        ;;
    *)
        echo "Error"
        ;;
esac

6.3 for(两种风格)

bash 复制代码
# C语言风格
for ((i=1; i<=10; i++)); do
    echo $i
done

# Python风格(遍历列表)
for n in {1..10}; do
    echo $n
done

# 遍历文件
for file in *.sh; do
    echo $file
done

# 遍历命令结果
for name in $(ls /usr); do
    echo $name
done

6.4 while

bash 复制代码
i=1
while ((i <= 100)); do
    sum=$((sum + i))
    ((i++))
done

七、数组(够用就行)

bash 复制代码
# 定义
arr=(10 20 30 "hello")

# 访问
echo ${arr[0]}          # 10(下标从0开始)
echo ${arr[*]}          # 全部元素
echo ${#arr[*]}         # 数组长度

# 追加
arr[4]=40

# 删除
unset arr[1]            # 删除一个元素
unset arr               # 删除整个数组

八、函数(重点掌握)

8.1 定义与调用

bash 复制代码
# 定义(三种写法)
function show() {
    echo "Hello"
}

# 调用(不加括号)
show

8.2 参数传递(最常用)

bash 复制代码
function getsum() {
    local sum=0          # local 声明局部变量
    for n in $@; do
        ((sum += n))
    done
    echo $sum            # 用 echo 返回结果(推荐)
}

result=$(getsum 10 20 30)
echo $result             # 60

8.3 ⚠️ return 的真面目(面试坑)

bash 复制代码
# ❌ 错误认知:return 返回值
function test() {
    return 100
}
test
echo $?          # 100(能输出,但只能0-255)

# ✅ 正确认知:return 表示退出状态
# 0=成功,非0=失败(和C语言相反!)
# 想返回计算结果,用 echo + $()

九、内置命令(生产必用)

9.1 read(交互输入)

bash 复制代码
read -p "请输入姓名: " name
read -sp "请输入密码: " pass    # -s 静默输入
read -t 10 value                # 10秒超时

9.2 test / [ ] / [[ ]]

bash 复制代码
# test 是命令,[ ] 是它的别名,[[ ]] 是升级版(推荐)
[[ -f /etc/passwd && -r /etc/passwd ]]  # 支持 && 和 ||

9.3 alias(起别名)

bash 复制代码
alias ll='ls -l --color=auto'   # 临时
# 永久:写入 ~/.bashrc
unalias ll                       # 删除

9.4 export(环境变量)

bash 复制代码
export JAVA_HOME=/usr/java/jdk
export PATH=$JAVA_HOME/bin:$PATH

十、实战脚本模板

10.1 集群启停脚本(你PDF里的)

bash 复制代码
#!/bin/bash
user=$(whoami)
case $1 in
    "start")
        for i in node01 node02 node03; do
            echo "===== $i 启动 ====="
            ssh $user@$i "/opt/app/bin/startup.sh"
        done
        ;;
    "stop")
        for i in node01 node02 node03; do
            echo "===== $i 停止 ====="
            ssh $user@$i "/opt/app/bin/shutdown.sh"
        done
        ;;
esac

10.2 JPS 查看脚本

bash 复制代码
#!/bin/bash
user=$(whoami)
for i in node01 node02 node03; do
    echo "===== $i ====="
    ssh $user@$i jps
done

10.3 文件分发脚本

bash 复制代码
#!/bin/bash
for file in $@; do
    for node in node01 node02 node03; do
        rsync -av $file $node:$PWD/
    done
done

十一、一句话避坑指南

解决方案
= 两边有空格 赋值时绝对不能 有空格:name="zhangsan"
[ 报错 command not found [] 内部和外部 都要有空格:[ "$a" == "$b" ]
变量含空格被拆分 必须加双引号"$var"
return 想返回大数字 echo + $() 代替
脚本执行变量不生效 source. 执行,不要用 bash
$*$@ 混淆 永远用 $@,它保留每个参数的独立性
crontab 脚本不执行 脚本里用绝对路径 ,环境变量要重新 source

十二、快速记忆口诀

复制代码
赋值等号不留空,引用变量加花括号
单引原样双引解,反引命令要替换
位置参数从1起,$# 个数 $@ 全
$? 成功为0,失败非0要注意
if 判断用 [[]],数值运算用 (())
函数结果用 echo,return 只表成功否
source 执行变量留,bash 执行开子壳

这 12 个模块覆盖了 PDF 中 95% 的生产实用场景。把这篇收藏好,写脚本的时候直接对照着用,很快就能形成肌肉记忆!

面试题自测

  1. 说 10 个常用的 Linux 命令
  2. Linux 系统中创建用户,用户组的命令
  3. Linux 修改文件所属的命令,修改文件权限的命令
  4. 用户目录在哪,环境变量有几种配置方式
  5. Linux 安装软件的方式有几种,分别什么区别
  6. 如何选择 Linux 操作系统版本
  7. Linux 服务器之间免密是如何实现的
  8. Shell 脚本第一行是什么,运行 Shell 脚本的方式有哪些,有什么区别
  9. Shell 脚本必须以 .sh 后缀结尾吗
  10. Linux 查看进程的命令以及杀死进程的命令
相关推荐
吴声子夜歌2 小时前
编写Shell脚本——自顶向下设计
linux·运维·shell
大牧师2 小时前
TypeORM 入门教程
后端·sql·mysql·orm·nest·typeorm
IT_陈寒2 小时前
Vite静态资源路径这个大坑害我调了一下午
前端·人工智能·后端
oliver_sys_log2 小时前
绕过 Yearning 查询体验限制:我做了一个 DataGrip 只读 SQL 代理
后端·mysql
水深火乐2 小时前
golang-jwt v5 入门
后端
M78佐菲2 小时前
HTML学习笔记
linux·笔记·学习·tcp/ip·html
carson9552 小时前
基于springboot和vue的文本文件上传下载在线编辑功能
后端
XR1234567882 小时前
医院无线整网高密覆盖选型深度解析
运维·网络
新时代牛马2 小时前
嵌入式 Linux 蓝牙框架完整篇:从 HCI、L2CAP 到BlueZ 用户态
linux·运维·服务器