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> 输出格式
各列含义:
- 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
查看文件内容
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 {} # 匹配删除文件
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


浙公网安备 33010602011771号