Linux开发人员常用命令

常用查询命令

# 查看ip地址
ip addr show

hostname -I

# 查看当前目录路径
pwd

# 当前目录下模糊查找文件
find / -name "*.pdf"

查看运行中进程

ps -ef | grep test

ps aux | grep test

# 查询包含java字符的记录,且过滤掉包含grep字符的记录,查询行数(wc -l)
ps -ef | grep java | grep -v grep | wc -l

# 过滤掉包含root字符的记录
grep -v root

# jps是jdk提供的查看java进程的小工具
jps

# 遍历正在运行的进程pid
pidof java
pgrep java

# 终止所有名为xxx的进程
pkill xxx
# 终止所有包含xxx字样的进程
pkill -f xxx
ps -ef | grep xxx | grep -v grep | awk '{print $2}' | xargs kill -9

查看端口使用情况

# Windows ------------------------------------
netstat -qo
# 查看端口占用情况
netstat -ano |findstr "端口号"
# Linux --------------------------------------
ss -tnlp
ss -tnlp | grep 160 # 匹配包含160的信息
# 查看端口占用情况
ss -tnlp|grep 端口号 | sort -k 4

发送请求

# 发送get请求
curl http://example.com
# 发送get请求带参数
curl "http://example.com/api/users?id=123"
# 发送get请求带请求头
curl -H "Accept: application/json" http://example.com/api/data

# 发送post请求
curl -X POST -d "key1=value1&key2=value2" http://example.com/api
# 发送JSON格式的POST请求体
curl -X POST -H "Content-Type: application/json" -d '{"key1":"value1", "key2":"value2"}' http://example.com/api
# 使用文件作为POST请求体
curl -X POST -H "Content-Type: application/json" -d @data.json http://example.com/api

检查磁盘空间

# 检查系统中文件的使用情况
df -h -T

# 显示磁盘已满但实际有空间的问题解决办法,重启服务器也行
# 查找所有被标记为 "deleted" 但仍被进程占用的文件
find /proc/*/fd -ls 2>/dev/null | grep '(deleted)'

# 查找大于 1GB 的文件(当前目录及子目录)
find . -type f -size +1G

# 按文件大小排序(从大到小)
find . -type f -size +100M -exec du -sh {} + | sort -rh

# 仅显示前 10 个最大文件
find . -type f -exec du -sh {} + | sort -rh | head -n 10

# 清空文件内容
truncate -s 0 文件名

# 查看当前目录下各个文件及目录占用空间大小
du -sh *

# 统计当前目录下各子目录的总大小(按大小排序)
du -sh * | sort -rh

# 查找占用空间最大的 5 个目录
du -hd 1 | sort -rh | head -n 5

# 查看指定文件大小
du -h test.txt

# 查看CPU信息
lscpu
cat /proc/cpuinfo

top命令

top 命令是 Linux 中常用的实时系统监控工具,能够动态显示进程的资源占用情况。

顶部系统统计信息

top - 15:30:45 up 2 days,  3:45,  2 users,  load average: 0.65, 0.42, 0.38
Tasks: 230 total,   1 running, 229 sleeping,   0 stopped,   0 zombie
%Cpu(s):  5.2 us,  2.1 sy,  0.0 ni, 92.5 id,  0.2 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :  15917.9 total,   8958.1 free,   3245.6 used,   3714.2 buff/cache
MiB Swap:   2048.0 total,   2048.0 free,      0.0 used.  11895.7 avail Mem
- - - - - - - - - -
第一行:系统整体状态 15:30:45:当前系统时间 up 2 days, 3:45:系统运行时间 2 users:当前登录用户数 load average: 0.65, 0.42, 0.38:系统负载(1 分钟、5 分钟、15 分钟内的平均进程数,通常不超过 CPU 核心数)
第二行:任务统计 230 total:总进程数 1 running:正在运行的进程数 229 sleeping:休眠进程数 0 stopped:停止的进程数 0 zombie:僵尸进程数(需关注,非 0 可能有问题)
第三行:CPU 使用率(% Cpu (s)) us:用户态进程占用 CPU 百分比(如应用程序) sy:内核态进程占用 CPU 百分比(如系统调用) ni:优先级调整过的进程占用 CPU 百分比 id:CPU 空闲百分比(越低表示负载越高) wa:CPU 等待 I/O 的时间百分比(过高可能是磁盘 / 网络瓶颈) hi:硬件中断占用 CPU 百分比 si:软件中断占用 CPU 百分比 st:被虚拟机窃取的 CPU 百分比(仅在虚拟机中有效)
第四/五行:内存 / 交换分区(MiB 为单位) total:总容量 free:完全空闲的容量 used:已使用的容量 buff/cache:用于缓存和缓冲区的容量(可释放给应用程序) avail Mem:实际可用于新进程的内存容量

进程列表参数(默认列)

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND
 1234 root      20   0  123456  78900  45600 S   5.0   0.5  12:34.56 java
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
进程 ID 进程所属用户 进程优先级(值越小优先级越高,范围 0-39,实时进程为负数) nice 值(调整优先级,范围 -20~19,越大优先级越低,不影响实时进程) 虚拟内存使用量 实际使用的物理内存 共享内存大小 进程状态(S)
R:运行中(正在使用 CPU 或等待调度)
S:休眠中(等待事件完成,如 I/O)
D:不可中断休眠(通常是等待磁盘 I/O,无法被杀死)
Z:僵尸进程(已终止但未被父进程回收)
T:停止状态(被 kill -STOP 暂停)
t:追踪状态(被调试器追踪)
进程占用 CPU 的百分比 进程占用物理内存的百分比 进程累计占用的 CPU 时间(精确到 0.01 秒) 进程对应的命令或程序路径

排查CPU过高问题

# 按内存排序
top -o %MEM
# 查询java进程或使用 jps -l
top -p $(pgrep -d',' -f java)

# 步骤1:定位高CPU线程
top              # 找到最耗CPU的进程 pid
top -Hp [pid]    # 定位应用进程对应的线程 tid

# 步骤2:线程ID转换为十六进制
printf "%x\n" [tid]

# 步骤3:分析线程栈
/usr/local/jdk/bin/jstack [pid] | grep -A 10 [tid 的十六进制]      # 打印堆栈信息

常见高CPU原因分析

// 1. 死循环示例
while (true) {
    // 业务逻辑
}

// 2. 频繁GC
System.gc(); // 手动调用GC

// 3. 复杂计算
for (int i = 0; i < Integer.MAX_VALUE; i++) {
    heavyCalculation();
}

CPU问题排查脚本: find_high_cpu_thread.sh

#!/bin/bash

JAVA_PID=$1

if [ -z "$JAVA_PID" ]; then
    echo "Usage: $0 <java_pid>"
    exit 1
fi

echo "=== 检查Java进程 $JAVA_PID ==="
top -p $JAVA_PID -n 1 -b | grep $JAVA_PID

echo -e "\n=== 高CPU线程TOP 10 ==="
top -H -p $JAVA_PID -n 1 -b | head -15

echo -e "\n=== 生成线程dump ==="
/usr/local/jdk/bin/jstack $JAVA_PID > thread_dump_$(date +%Y%m%d_%H%M%S).txt

echo -e "\n=== 建议 ==="
echo "1. 使用 top -H -p $JAVA_PID 实时监控线程"
echo "2. 将高CPU线程ID转为16进制: printf '%x\n' <thread_id>"
echo "3. 在thread_dump文件中搜索对应的nid"

排查内存问题

# 步骤1:监控内存增长(持续监控内存变化)
watch -n 1 'top -p $(pgrep -d',' -f java) -o %MEM -b -n 1 | head -20'
# 只显示关键信息
watch -n 1 'ps -p $(pgrep -d"," -f java) -o pid,ppid,%cpu,%mem,rss,vsz,comm --sort=-%mem'

# 步骤2:生成堆转储(查看堆内存概况)
# 生成heap dump
/usr/local/jdk/bin/jmap -dump:live,format=b,file=heap.hprof <java_pid>
# 查看堆内存概况
/usr/local/jdk/bin/jmap -heap <java_pid>

# 步骤3:分析内存泄漏(查看对象数量排名)
/usr/local/jdk/bin/jmap -histo <java_pid> | head -20

理解 jmap -histo <java_pid> 输出格式
image
各列含义:

  • instances: 类的实例数量
  • bytes: 这些实例占用的总字节数
  • class name: 类名([C=char[], [B=byte[], [I=int[])

重点关注指标

  • 实例数量异常多的业务类
  • 占用内存异常大的类
  • 持续增长的类和对象

常见内存泄漏模式分析

模式1:char[] 和 String 过多

// 可能原因:字符串拼接、日志记录、缓存不当
public class MemoryLeak {
    private static List<String> cache = new ArrayList<>();
    public void processData(String data) {
        // 错误:不断向静态集合添加数据
        cache.add(data + System.currentTimeMillis());
    }
}

分析:如果 [C 和 String 长期占据前几位且持续增长,可能存在字符串不当缓存。

模式2:业务对象堆积

// 用户对象泄漏示例
public class UserService {
    private Map<Long, User> userCache = new HashMap<>();
    public User getUser(Long id) {
        // 错误:缓存没有清理机制
        return userCache.computeIfAbsent(id, k -> loadUserFromDB(k));
    }
}

分析:如果 com.example.User 实例数量异常多,检查缓存策略。

模式3:集合类占用过大

public class DataProcessor {
    private List<byte[]> dataChunks = new ArrayList<>();
    public void process(byte[] data) {
        // 错误:持有大数据块引用
        dataChunks.add(data);
    }
}

分析:如果 ArrayList、HashMap$Node 等集合类占用大,检查集合管理。

内存监控脚本: monitor_memory.sh

#!/bin/bash

JAVA_PID=$1
INTERVAL=${2:-5}

while true; do
    clear
    echo "=== 内存监控 - Java进程 $JAVA_PID - $(date) ==="

    # 进程内存信息
    echo -e "\n--- 进程内存状态 ---"
    top -p $JAVA_PID -n 1 -b | grep $JAVA_PID

    # JVM内存信息
    echo -e "\n--- JVM内存统计 ---"
    /usr/local/jdk/bin/jstat -gc $JAVA_PID 1 1 2>/dev/null || echo "无法获取GC信息"

    # 对象统计
    echo -e "\n--- 对象数量TOP 10 ---"
    /usr/local/jdk/bin/jmap -histo $JAVA_PID | head -15 2>/dev/null || echo "无法获取对象统计"

    sleep $INTERVAL
done

常用交互指令

在 top 界面按以下键可快速操作:

P:按 %CPU 排序(默认)
M:按 %MEM 排序
T:按 TIME+ 排序
k:输入 PID 杀死进程
q:退出 top
1:显示所有 CPU 核心的使用率(多核环境)
H:显示线程详情(将进程拆分为线程)

# 查看名为"app.py"的Python程序内存占用
ps aux | grep "python.*app.py" | awk '{print $2, $4, $6, $11}'
# 输出(PID 内存使用率(%) 物理内存(KB) 命令)

# 查看所有Python进程的内存占用(按内存使用率排序)
ps -eo %mem,rss,vsize,pid,cmd | grep python | sort -k1nr
# 字段说明(rss: 实际物理内存占用(KB),vsize: 虚拟内存占用(KB))

# 按CPU使用率降序,取前3个最耗CPU的进程(w:宽输出模式)
ps auxw --sort=-%cpu | head -n 4

# 按内存使用率降序,取前5个最耗内存的Python进程 [-k4nr 表示按第 4 列(内存占用)降序排列(n 表示按数字排序,r 表示反向)]
ps aux | grep python | grep -v grep | sort -k4nr | head -n 5

查看主机名

hostname
hostnamectl
uname -a | awk '{print $2}'

# 查看发行版信息
cat /etc/os-release

查看历史命令

history 10  # 列出最近的10条命令
history -c  # 清除历史命令
history|grep ls  # 模糊搜索历史命令

测试IP端口是否连通

# 方式一:
telnet ip port
# 方式二:
curl ip:port
# 方式三:
wget ip:port
# 方式四:
ssh -v -p port username@ip

# 跳转进入指定服务器
ssh ip地址
# 复制文件到指定服务器目录
scp test.txt root@ip地址:/home/data

控制命令

Ctrl + L # 清屏(或clear)
Ctrl + C # 终止命令
Ctrl + S # 阻止屏幕输出
Ctrl + Q # 允许屏幕输出
Tab      # 补全命令

基本操作

cd -  # 返回上次的工作目录
cd ~  # 进入当前用户
cd /  # 进入根目录

./    # 指在当前目录
../   # 指返回上一级目录

# 复制
cp    # 只能移动文件
cp -r # 包括文件夹一块移动

# 重命名
mv ex3 new1 # 将文件ex3改名为new1

# 移动
mv /lianxi/kkk/* /lianxi/jjjj/  # 移动文件
mv * ../                        # 移动当前目录所有文件到上级目录

# 以时间戳方式备份文件夹,先修改文件夹名称,再把文件夹移动到当前目录的bak目录中
mv file01 file01_bak_"$(date +%Y%m%d%H%M%S)" && mv file01_bak_* ./bak

# 删除
rm *   # 删除当前目录下所有文件
rm -r  # 可以删除文件夹
rm -rf # 强制删除

# 删除文件但排除个别文件
shopt -s extglob             # 打开extglob模式
rm -fr !(file1)              # 排除一个
rm -rf !(file1|file2|file3)  # 排除多个
shopt -u extglob             # 关闭extglob模式

# 批量移动
find test/ -name "*.jpg" -exec cp {} train \;

# 批量删除
find test/ -name "*.jpg" | xargs -i rm {}

# 新建文件夹
mkdir file_2022 #新建文件夹
rmdir file_2022 #删除文件夹
mkdir -p test1/test2/test3  #递归新建多层目录

# 新建文件
touch filename.txt

根据时间删除文件或者目录

命令 说明
-mtime +3 按照天数 +3 指查找3天前的文件,-3指查询3天内的文件
-mmin +30 按照分钟 +30指查找三十分钟前的文件,同上
-name ".csv" ".csv"表示查找扩展名为csv的所有文件,""表示查找所有文件
-exec 固定写法
rm -rf 强制递归删除,包括文件和目录
{} \; 固定写法
find 对应的目录 -mtime +3 -name "文件名" -exec rm -rf {} \;
find 对应的目录 -mmin +30 -name "文件名" -exec rm -rf {} \;

find ./ -mtime +2 -exec rm -rf {} \;
find /data/www/ -mtime +2 -exec rm -rf {} \;
find /data/www/ -mtime +3  -name "*.csv" -exec rm -rf {} \;
------------------------------------------------------------------------
# 删除7天前修改的文件
find /path/to/directory -type f -mtime +7 -delete
# 删除30天前创建的文件
find /path/to/directory -type f -ctime +30 -delete
# 删除所有超过一年未被访问的文件
find /path/to/directory -type f -atime +365 -delete

显示目录

ls     # 显示目录
ls -a  # 显示隐藏
ls -l  # 单列格式输出详细信息,简写:ll
tree   # 树形结构显示目录,需要安装tree包

# 时间倒序
ll -t
# 时间正序
ll -t | tac
# 时间倒序 只展示前5个
ll -t | head -n 5

一次性执行多条命令

1、使用 “;” 符号运行多条指令

$ cmd1 ; cmd2 ; cmd3
# 就算有指令执行失败也会继续执行后面的指令。

2、使用 “&&” 符号运行多条指令

$ cmd1 && cmd2 && cmd3
# 前一条指令执行失败,则后面的指令都不会执行。

3、使用 “||” 符号运行多条指令

$ cmd1 || cmd2 || cmd3
# 前一条指令执行成功,则后面的指令都不会执行。

压缩/解压

tar在Linux上是常用的打包、压缩、加压缩工具。

[参数]:
-c : # create 建立压缩档案的参数;
-x : # 解压缩压缩档案的参数;
-z : # 是否需要用gzip压缩,--gzip, --gunzip, --ungzip   通过 gzip 过滤归档
-v : # 压缩的过程中显示档案;
-f : # 置顶文档名,在f后面立即接文件名,不能再加参数
-J : # --xz 通过 xz 过滤归档
-C :  # --directory=DIR 改变至目录 DIR

# 1、gzip格式:
tar -czvf test.tar.gz file1 file2     # 压缩(一般压缩包包名以 .tar.gz作为后缀名)
tar -czvf test.tgz file1              # tgz缩写方式

tar -xzvf test.tar.gz                 # 解压到当前目录
tar -xzvf test.tar.gz -C /home/file   # 解压到指定目录

# 2、bz2格式:
tar jcvf test.tar.bz2 file1 file2     # 压缩(一般压缩包包名以 .tar.bz2作为后缀名)

tar -jxvf test.tar.bz2                # 解压到当前目录
tar -jxvf test.tar.bz2 -C /home/file  # 解压到指定目录

开机自启动

/etc/rc.d/init.d/     # 存放着自启动脚本,优先级比下面的高
/lib/systemd/system/  # 存放着自启动脚本
/etc/rc.local         # 直接加入即可

# 设置脚本的可执行权限
chmod +x /etc/init.d/xxxx.sh

JPS命令及参数介绍

jps [options ] [ hostid ]  # 其中[options]和[hostid]都是可选参数
# 查询Linux系统当前所有java进程pid的命令,jps是jdk提供的一个查看当前java进程的小工具。
[options]选项:
-q # 仅输出VM标识符,不包括classname,jar name,arguments in main method
-m # 输出main method的参数
-l # 输出完全的包名,应用主类名,jar的完全路径名
-v # 输出jvm参数
-V # 输出通过flag文件传递到JVM中的参数(.hotspotrc文件或-XX:Flags=所指定的文件
-Joption # 传递参数到vm,例如:-J-Xms512m

[hostid]参数:[protocol:][[//]hostname][:port][/servername]
1)jps
2)jps –l # 输出主类或者jar的完全路径名
3)jps –v # 输出jvm启动参数
4)jps –q # 仅仅显示java进程号
5) jps -mlv 192.168.2.11

vi编辑文件内容

# 编辑模式:使用vi进入文本后,按i开始编辑文本
vi /etc/hosts

# 撤销操作
u
# 按下 'Ctrl + r' 重做之前撤销的操作
Ctrl + r

# 光标跳转到最后一行
G

# 光标跳转到第一行
gg

# 退出编辑:按ESC键
# 然后输入:
:q!  # 不保存文件,强制退出vi命令
:w   # 保存文件,不退出vi命令
:wq  # 保存文件,退出vi命令

# vi编辑器只能运行于unix中,而vim不仅可以运行于unix,还可用于windows、mac等多操作平台。

# 因为Linux无法识别Windows的DOS格式,此时需要将文件格式转换成unix即可。
:set ff #(查看文件格式)
:set ff = unix # (修改格式)

# 编辑状态显示行数
:set number #(显示)
:set nonumber #(关闭)

# 跳到最后一行
方式1、shift + G
方式2、按下冒号(:)键,然后输入$,再按回车键

按下End键,光标会移动到当前行的末尾

# 删除单行
dd #(删除光标定位行)

# 删除多行
:10,20d #(删除行号10-20行)

# 删除全部内容
输入 ggVGd(跳转到首行→进入可视行模式→跳转到末尾→删除选中内容)
或输入 :%d(%表示所有行)

# 批量替换字符
:%s/原字符串/新字符串/g

查看vi和vim的区别

查看文件内容

cat /etc/hosts        # 查看文件内容的全部
tail/head             # 查看指定的行
tail /etc/hosts       # 显示文件最后10行
tail -n 2 /etc/hosts  # 显示文件最后两行,同-2
head /etc/hosts       # 显示文件前10行
head -2 /etc/hosts    # 显示文件前2行,同-n 2

wc /etc/hsots         # 统计文本中行数、字数、字符数

查看日志内容

tail -f temp.log      # 不断刷新读取新内容

tail web.2016-06-06.log -n 300 -f         # 查看底部即最新300条日志记录,并实时刷新

grep 'nick' -C 10 | tail run.log -n 1000  # 从最近1000行日志内查找,匹配字符‘nick’前后10条日志记录
grep 'nick' -C 10 run.log | head -n 1000  # 效果同上

cat -n test.log |grep "地形" |more        # more 分页查询

grep常见用法

grep 'nick' -C 10 run.log  # 查询字符‘nick’前后10条日志记录, 前10行(-A 10),后10行(-B 10)
grep -n "root" /etc/passwd # 过滤出来加行数
grep -c "root" /etc/passwd # 过滤出来的行号
grep -v "root" /etc/passwd # 取反
grep -q "root" /etc/passwd # 过滤出来的不显示
grep -w "root" /etc/passwd # 过滤出来有单词root的行
grep -o "root" /etc/passwd # 过滤出来root单词
grep -ro "root" 目录       # 过滤出来目录中文件里的有root的行
grep -i "root" /etc/passwd # 忽略大小写
grep -E "root" /etc/passwd # 启用扩展正则
grep -f file file1    # 过滤出file和file1中共同拥有的行
grep -f file file1 -v # 过滤出file有file1没有的行
grep -x "root" file   # 过滤file中只含有root的的行

文件搜索

whereis           # 搜索系统命令所在的位置,不能查询文件
whereis hadoop    # 搜索程序名称
whereis -b hadoop # 搜索可执行的文件
whereis -m hadoop # 搜索说明文件
whereis -s hadoop # 搜索源代码

which             # 能搜索命令所在位置,以及如果有些命令有别名,则会查出别名
which python

find .                        # 列出当前目录及子目录下所有文件和文件夹
find . -name test.txt         # 按特定名称搜索文件
find / -name "*.pdf"          # 在根目录下搜索后缀为.pdf的文件
find / -type f -name "*.pdf"  # 指定(-type f)搜索会使所有内容更清晰
find . -type d -name "yang*"  # 查找不同类型的文件
find . -type l -name "yang*"  # 查找不同类型的文件
find . -name '.r.*' -exec rm {}   # 匹配删除文件

查看更多find的用法

sed进行数据操作

# 删除文件中第一行
sed -i '1d' file.txt

# 删除文件中最后一行
sed -i '$d' file.txt

# 删除文件中的指定一行
sed -i '3d' file.txt

# 删除第M到N行
sed -i 'M,Nd' file.txt

# 删除第M行到最后一行
sed -i 'M,$d' file.txt

# 删除文件中包含某个关键字开头的所有行
sed -i '/^keyword/d' file.txt

# 删除文件中包含某个关键字的所有行
sed -i '/keyword/d' file.txt

# 替换字符串
sed -i 's/abc/ABC/' file.txt # 替换file.txt每一行的第一个abc为ABC
sed -i 's/abc/ABC/g' file.txt # 使用后缀g,替换file.txt每一行的所有abc为ABC

# 追加字符串
sed -i 's/^/ABC/' file.txt # 在file.txt每一行的行首追加字符串ABC
sed -i 's/$/ABC/' file.txt # 在file.txt每一行的行尾追加字符串ABC

# 追加或插入一行
sed -i 'Na hello_world' file.txt # 在file.txt第N行后面追加一行"hello_world",a表示追加
sed -i 'Ni hello_world' file.txt # 在file.txt第N行前面插入一行"hello_world",i表示插入
sed -i '/hello/a hello_world' file.txt # 在file.txt包含"hello"的所有行后面追加一行"hello_world"

字符串的提取和替换

判断读取字符串值

表达式 含义
${var} 读取变量var的值, 与$var相同
${var-DEFAULT} 如果var没有被声明, 那么就以$DEFAULT作为其值 *
${var=DEFAULT} 如果var没有被声明, 那么就以$DEFAULT作为其值 *
${var:-DEFAULT} 如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值 *
${var:=DEFAULT} 如果var没有被声明, 或者其值为空, 那么就以$DEFAULT作为其值 *
${var+OTHER} 如果var声明了, 那么其值就是$OTHER, 否则就为null字符串
${var:+OTHER} 如果var被设置了, 那么其值就是$OTHER, 否则就为null字符串
${var?ERR_MSG} 如果var没被声明, 那么就打印$ERR_MSG *
${var:?ERR_MSG} 如果var没被设置, 那么就打印$ERR_MSG *
${!varprefix*} 匹配之前所有以varprefix开头进行声明的变量
${!varprefix@} 匹配之前所有以varprefix开头进行声明的变量

操作字符串(长度/截取/替换/删除)

表达式 含义
${#string} 读取$string的长度
${string:position} 在$string中, 从位置$position开始提取子串
${string:position:length} 在$string中, 从位置$position开始提取长度为$length的子串
${string#substring} 从变量$string的开头, 删除最短匹配$substring的子串
${string##substring} 从变量$string的开头, 删除最长匹配$substring的子串
${string%substring} 从变量$string的结尾, 删除最短匹配$substring的子串
${string%%substring} 从变量$string的结尾, 删除最长匹配$substring的子串
${string/substring/replacement} 使用$replacement, 来代替第一个匹配的$substring
${string//substring/replacement} 使用$replacement, 代替所有匹配的$substring
${string/#substring/replacement} 如果$string的前缀匹配$substring, 那么就用$replacement来代替匹配到的$substring
${string/%substring/replacement} 如果$string的后缀匹配$substring, 那么就用$replacement来代替匹配到的$substring

echo进行数据操作

# 在终端打印输出
echo "hello world"

# 向文件中写入内容
echo "hello world" > test.txt    # 原先的内容会被覆盖掉

# 向文件中追加内容
echo "add content" >> test.txt

# 执行脚本同时追加多行文本命令
CMD echo "192.168.1.1 test1.com.cn" >> /etc/hosts;\
echo "192.168.1.2 test2.com.cn" >> /etc/hosts;\
echo "192.168.1.3 test3.com.cn" >> /etc/hosts;\
echo "192.168.1.4 test4.com.cn" >> /etc/hosts;\
java -jar -Dfile.encoding=utf-8 /java/test.jar --spring.profiles.active=test

echo输出时的转义字符

echo [-neE] [arg …]
-n: # 表示输出字符串不换行
-e: # 表示对于转义字符按对应的方式进行处理(若不加-e ,那么在输出时转义字符会按照普通字符进行处理,并不会达到自己想要达到的目的。)
-E: # 禁用转义解释

\b # 表示删除前一个字符
\e # 表示删除后一个字符
\n # 表示换行
\t # 表示水平制表符
\v # 表示垂直制表符
\c # \c后面的字符将不会输出,同时,输出完成后也不会换行
\r # 输出回车符(但是你会发现\r前面的字符没有了)
\a # 表示输出一个警告声音

chmod -R 777 授权命令

chmod :# 是改变权限的命令(change mode)
-R :# 当前目录及目录下所有文件
777 :# 可读、可写、可执行
# 整个命令的作用是:对当前目录及目录下所有的文件赋予可读可写可执行权限

# 命令格式:
chmod [-cfvR] [--help] [--version] mode file
# 命令参数:
-c #当发生改变时,报告处理信息
-f #错误信息不输出
-R #处理指定目录以及其子目录下的所有文件
-v #运行时显示详细处理信息

# 权限范围:
u #目录或者文件的当前的用户
g #目录或者文件的当前的群组
o #除了目录或者文件的当前用户或群组之外的用户或者群组
a #所有的用户及群组

# 为文件f01设置自己可以执行,组员可以写入的权限
chmod u+x,g+w f01
chmod u=rwx,g=rw,o=r f01
chmod 764 f01

chmod +x f01  # 对文件f01添加执行权限
chmod -x f01  # 对文件f01删除执行权限
chmod a+x f0l # 对文件f01的u,g,o 都添加可执行权限

# 权限代号:
r #读权限,用数字4表示(Read)
w #写权限,用数字2表示(Write)
x #执行权限,用数字1表示(eXecute)
- #删除权限,用数字0表示
s #特殊权限

# 权限分为三种:读(r=4),写(w=2),执行(x=1)
可读可执行5(rx=4+1)、可读可写6(rw=4+2)、可读可写可执行7(rwx=4+2+1)。

777就是:rwxrwxrwx
755就是:rwxrxrx

755
# 第一个数字表示文件所有者的权限
# 第二个数字表示与文件所有者同属一个用户组的其他用户的权限
# 第三个数字表示其它用户组的权限。

# chmod 755 设置用户的权限为:
1.文件所有者可读可写可执行                     --7
2.与文件所有者同属一个用户组的其他用户可读可执行 --5
3.其它用户组可读可执行                         --5

IF判断比较运算符

代码示例

#!/bin/bash

name="John Doe"

# 不安全的方式
if [ $name = "John Doe" ]; then    # 错误:参数过多
    echo "匹配"
fi

# 安全的方式
if [ "$name" = "John Doe" ]; then  # 正确
    echo "匹配"
fi

# 更好的方式,推荐使用 [[ ]]
if [[ $name = "John Doe" ]]; then  # [[ ]] 更安全
    echo "匹配"
fi

三种等号用法对比

操作符 用途 示例 使用上下文
= 字符串相等 [ "$a" = "$b" ] [ ][[ ]]
== 字符串相等 [[ "$a" == "$b" ]] 主要在 [[ ]]
-eq 数值相等 [ "$a" -eq "$b" ] [ ][[ ]]

算术比较操作符

算术 运算符 代码示例
等于 -eq if [ $a -eq $b ]
不等于 -ne if [ $a -ne $b ]
大于 -gt if [ $a -gt $b ]
大于等于 -ge if [ $a -ge $b ]
小于 -lt if [ $a -lt $b ]
小于等于 -le if [ $a -le $b ]

使用算术比较操作符时,确保比较的变量值是数字。
如果需要进行复杂的数学计算,可以使用 expr 命令或者双括号 ((...)) 来执行。

逻辑运算符

逻辑 运算符 代码示例
或(or) -o if [ $a -eq 5 -o $b -eq 10 ]
与(and) -a if [ $a -eq 5 -a $b -eq 10 ]

文件比较运算符

检查文件 运算符 代码示例
检查文件是否存在 -e if [ -e $filename ]
检查文件是否存在且可读 -r if [ -r $filename ]
检查文件是否存在且可写 -w if [ -w $filename ]
检查文件是否存在且可执行 -x if [ -x $filename ]
检查文件是否存在且其大小大于零 -s if [ -s $filename ]
检查路径是否存在且为一个目录 -d if [ -d $dirname ]

字符串比较

字符串 运算符 代码示例
检查两个字符串是否相等 == if [[ $str1 == $str2 ]]
检查两个字符串是否不相等 == if [[ $str1 != $str2 ]]
检查字符串是否为空(长度为零) -z if [[ -z $str1 ]]
检查字符串是否非空(长度大于零) -n if [[ -n $str1 ]]
检查字符串是否匹配 s*a,其中 * 表示任意字符 * if [[ $str1 = s*a ]]

尽量使用[[ ... ]]条件判断结构,而不是[ ... ],能够防止脚本中的许多逻辑错误。

比如 &&、||、<、> 操作符能够正常存在于[[ ]]条件判断结构中,但是如果出现在[ ]结构中的话会报错。

比如使用if [[ $a != 1 && $a != 2 ]], 如果不适用双括号, 则为if [ $a -ne 1] && [ $a != 2 ]或者if [ $a -ne 1 -a $a != 2 ]

数学计算工具

注意:重定向符号(‌<、‌>、‌|)‌,通配符号(?、*):‌在某些情况下,‌这些特殊符号需要进行转义。

((...))双括号

双括号((...))主要用于算术扩展和条件表达式。这种扩展计算是整数型的计算,不支持浮点型。

# 算术运算
((1+1)) echo $?

((sum=5+8)) echo "sum is: $sum"

# 比较运算
((3 > 2)) && echo "True" || echo "False"

# 逻辑运算
((3 > 2 && 3 < 4)) && echo "True" || echo "False"

# 在if判断中使用
if (($num1 > $num2)); then echo "True"

# 在for循环中使用
for ((i=1; i<=5; i++)); do
  echo "Counter: $i"
done

# 在while循环中使用
((counter=1))
while ((counter<=5)); do
  echo "Counter: $counter"
  ((counter++))
done

expr命令

expr命令是一个用于执行基本数学运算的实用工具。它可以进行加法、减法、乘法和除法等基本操作。

运算符 代码示例
加法 expr 10 + 5
减法 expr 10 – 5
乘法 expr 10 \* 5
除法 expr 10 / 5
取余 expr 10 % 3
表达式计算 expr \(10 + 5\) \* 2

result=$(expr $a + 1)

bc命令

bc命令是一个高精度计算器,可以进行更复杂的数学计算。

运算符 代码示例
加法 echo "10 + 5" | bc
减法 echo "10 – 5" | bc
乘法 echo "10 * 5" | bc
除法 echo "scale=2; 10 / 5" | bc
平方根 echo "sqrt(25)" | bc
自然对数 echo "l(10)" | bc

等号后面的数字和运算符之间需要留有空格,而除法需要使用scale参数来指定小数位数。

awk命令

awk是一种文本处理工具,也可以用于计算。

运算符 代码示例
加法 echo "10 5" | awk ‘{print $1 + $2}’
减法 echo "10 5" | awk ‘{print $1 – $2}’
乘法 echo "10 5" | awk ‘{print $1 * $2}’
除法 echo "10 5" | awk ‘{print $1 / $2}’
平均值计算 echo "10 5 8" | awk '{sum=0; for(i=1; i<=NF; i++) sum+=$i; print sum/NF}'

在awk命令中,使用{}括起来的部分定义了要执行的操作。$1表示第一个字段,$2表示第二个字段,NF表示字段的总数。

expr、bc和awk命令的组合:还可以将这些命令组合在一起使用,实现更复杂的计算。

例如:可以通过将expr命令的输出传递给bc命令来进行更高级的计算。

echo "5 * 2" | expr | bc

posted @ 2021-05-07 17:19  盗梦笔记  阅读(116)  评论(0)    收藏  举报