当前位置: 首页 > news >正文

Shell脚本编程基本认识

Shell脚本编程基本认识

一、脚本基础

1. Shell编程介绍与特性

Shell定义与作用

Shell是命令解释程序,同时也是命令语言解释器。用户与Shell交互时,输入的命令行需符合Shell语法与语义规范,才能被理解并执行。其使用的命令语言称为Shell语言,具备双重属性:

  • 交互式语言:支持用户实时输入命令并获取反馈,是Linux系统中用户与内核交互的核心桥梁。
  • 可编程语言:将多个Shell命令写入文本文件,构成Shell程序(Shell脚本) ,Shell会逐条解释执行。通过变量、参数、控制结构的组合,可自动化完成系统初启、配置、管理等复杂操作。

在Linux系统中,Shell脚本是自动化运维的关键工具,熟练掌握Shell语言能高效管理系统,深入理解系统运行机制。

Shell语言特点
特点分类详细说明优势与不足
解释性语言无需编译,Shell进程直接解释执行脚本代码优势:即编即用,开发效率高;不足:运行速度低于编译型语言目标程序
基于字符串的语言仅处理字符串数据,不支持复杂数据结构(如数组、链表)与复杂运算(如浮点运算),输出均为字符形式优势:处理文本、字符串任务(日志分析、数据筛选)简洁高效;不足:无法满足复杂数据处理场景
命令级语言脚本核心由Shell命令(如lscd)和系统可执行程序构成,支持通过管道(`)、重定向(>/<`)组合命令
Shell脚本构成

Shell脚本是文本文件,内容分为两类:

  • 简单脚本:仅包含有序排列的Shell命令,如cd /tmp && mkdir test,执行固定流程操作。
  • 高级脚本:除基础命令外,包含变量定义、参数传递、条件判断(if-else)、循环(for/while)等结构,应对动态复杂场景(如服务器负载监控脚本)。

2. 变量

变量本质

变量是程序中保存用户数据的内存空间,变量名是该内存空间的“地址标识”。程序执行时,内存中的数据(变量值)可动态变化,但变量名固定。例如age=25中,age是变量名(指向内存地址),25是变量值(内存中存储的数据)。

变量命名规则
  1. 字符组成:仅允许字母(A-Z、a-z)、数字(0-9)、下划线(_),且必须以字母或下划线开头(如123name为非法变量名)。
  2. 长度限制:Shell未明确限制变量名长度,为保证可读性,建议使用“简短且有意义”的名称(如user_count表示用户数量,而非uc)。
  3. 命名规范(建议)
    • 全局变量:大写字母(如SYSTEM_PATH)。
    • 局部变量(函数内):小写字母(如temp_file)。
    • 避免拼音或无意义字符(如mingzia1),通过变量名直观理解用途。
变量类型与使用
变量类型定义与使用规则示例注意事项
整型(int)直接赋值数字,无需声明类型,支持整数运算age=10(表示年龄为10)不支持浮点型数据,若赋值salary=3.1,会被当作字符串处理
浮点型(float)Shell原生不支持浮点运算,需借助bcawk等工具实现计算浮点和:`echo “3.1+2.2”bc`
字符型(字符串)赋值时可加引号(单引号、双引号)或不加引号,包含空格时必须加引号- 无空格:msg=cy/msg="cy"/msg='cy'
- 有空格:msg="hello cy"(不加引号会将hellocy视为两个参数)
单引号(强引用):引号内特殊字符($#)均失效,如echo '${name} is good'输出${name} is good
双引号(弱引用):引号内特殊字符($)仍生效,如name="cy"后,echo "${name} is good"输出cy is good
布尔型(boolean)仅支持True(真)和False(假),主要用于条件判断is_ok=True(操作成功)、is_error=False(无错误)Shell中布尔值本质是字符串,需通过条件表达式判断“真假”,非原生布尔类型
变量引用方式

引用变量时,变量名前加$符号,格式为$变量名${变量名}(推荐后者,避免变量名与后续字符混淆),示例:

name="cy"
echo $name          # 输出cy
echo "${name}_test" # 输出cy_test(若用$name_test,Shell会误认为变量是name_test,导致输出空值)

3. 脚本执行方式

Shell脚本执行需先确保为文本格式(如.sh后缀),不同执行方式对“执行权限”要求不同,常用方式如下:

执行方式语法格式权限要求原理与说明
sh/bash命令执行sh 脚本名.shbash 脚本名.sh无需执行权限(chmod +x直接调用sh/bash解释器,读取脚本内容执行,适用于脚本未授权或临时测试
相对路径执行./脚本名.sh(如./test.sh必须添加执行权限:chmod +x 脚本名.sh以当前目录为基准定位脚本,“.”表示当前目录;直接输入test.sh会在PATH路径中查找,可能提示“命令未找到”
绝对路径执行/绝对路径/脚本名.sh(如/home/user/test.sh必须添加执行权限通过完整路径定位脚本,不受当前目录影响,适用于脚本固定存放场景(系统运维脚本)
.(点号)执行. 脚本名.sh(点号后有空格)无需执行权限在当前Shell进程中执行脚本,脚本中定义的变量、环境变量直接影响当前Shell(如配置文件生效);其他执行方式创建子Shell,变量不影响当前环境
source命令执行source 脚本名.sh无需执行权限与“点号执行”原理一致,更偏向“加载配置文件”场景(如source /etc/profile使环境变量生效),是.(空格)脚本名的别名
执行方式示例

假设当前目录有test.sh脚本(内容echo "Hello Shell"):

  1. sh test.sh:直接执行,无需授权,输出Hello Shell
  2. chmod +x test.sh && ./test.sh:先授权,再通过相对路径执行,输出Hello Shell
  3. source test.sh:在当前Shell执行,若脚本中定义VAR=123,执行后echo $VAR输出123(其他方式无此效果)。

4. Shebang机制

#!(Shebang/Hashbang)是脚本文件第一行特殊标记,用于告诉系统“使用哪个解释器执行脚本”,语法格式#!/路径/解释器,常见脚本对应的Shebang:

脚本类型Shebang格式说明
Bash脚本#!/bin/bash最常用,指定Bash解释器(Linux中/bin/bash是Bash默认路径)
Python脚本#!/usr/bin/python#!/usr/bin/env python前者指定固定路径Python解释器;后者通过env查找系统配置的Python路径,更灵活,避免路径不一致问题
Perl脚本#!/usr/bin/perl指定Perl解释器,用于Perl语言脚本
注意事项

执行python脚本的方法:

vim a.pypython a.py
  • Shebang必须在脚本第一行,前面有空白行或注释会导致解释器识别失败。
  • 未写Shebang时,执行需明确指定解释器(如sh test.sh),否则系统可能默认使用/bin/sh(部分系统中/bin/shdash,与Bash兼容性有差异,可能导致脚本报错)。

二、脚本的组成结构

1. 脚本核心组成部分

规范的Shell脚本由“Shebang、注释、命令行”三部分组成,结构清晰、易于维护:

组成部分作用示例规范要求
Shebang指定脚本解释器#!/bin/bash必须位于脚本第一行,无前置字符
注释说明脚本功能、作者、日期、关键步骤,提高可读性# 功能:自动备份MySQL数据库<br># 作者:xxx<br># 日期:2024-05-01#开头,单行注释;复杂逻辑前需添加注释,解释“为什么做”(而非“做了什么”)
命令行脚本核心执行代码,包含变量定义、条件判断、循环、系统命令等# 定义备份路径<br>BACKUP_PATH="/data/backup"<br># 创建备份目录(若不存在)<br>mkdir -p $BACKUP_PATH一行一条命令,同一行多条命令用分号(;)分隔(如cd /tmp; mkdir test);
长命令用反斜杠(\)换行(如echo "This is a long \ command"),增强可读性
规范脚本示例
#!/bin/bash
# 脚本名称:hello.sh
# 功能:输出欢迎信息并显示当前时间
# 作者:xxx
# 日期:2024-05-01# 定义欢迎信息变量
WELCOME_MSG="Hello, Shell Script!"
# 输出欢迎信息
echo $WELCOME_MSG
# 输出当前时间(使用date命令)
echo "Current Time: $(date +'%Y-%m-%d %H:%M:%S')"
##输出
Current Time: 2025-09-09 11:03:36

2. 程序返回值

Shell脚本执行后产生两类返回值,分别对应“执行结果”和“执行状态”:

(1)程序执行的结果

指脚本中命令的输出内容,如echo "Hello"Hellols /tmp/tmp目录文件列表。可通过重定向(>/>>)保存到文件,或通过管道(|)传递给其他命令,示例:

# 将ls /tmp结果保存到/tmp/file_list.txt
ls /tmp > /tmp/file_list.txt
# 将echo结果通过管道传递给grep,筛选含"test"的行
echo "test1 test2 abc" | grep "test"
(2)程序状态返回代码(退出码)

指脚本或命令执行后的“状态标识”,用0-255的整数表示执行是否成功:

  • 0:执行成功(如ls /tmp执行成功,退出码0)。
  • 1-255:执行失败(如ls /nonexistent(目录不存在)退出码2,grep未找到匹配内容退出码1)。
退出码的查看与使用
  • 查看上一条命令的退出码:用特殊变量$?,示例:
    ls /tmp
    echo $?  # 输出0(执行成功)
    ls /nonexistent
    echo $?  # 输出2(执行失败)
    
  • 脚本中自定义退出码:通过exit 数字告知调用者脚本执行状态,示例:有待考证!!!
    # 检查备份目录是否存在,不存在则退出并返回1
    if [ ! -d /data/backup ]; thenecho "Backup directory not found!"exit 1  # 自定义退出码1,表示目录不存在错误
    fi
    # 备份成功后,退出并返回0
    echo "Backup completed successfully!"
    exit 0
    

三、Shell脚本调试

脚本开发中需通过调试定位语法、逻辑错误,以下是调试核心内容:

1. 脚本执行的过程解析

Shell脚本执行流程为“环境加载→逐行执行→子脚本处理”:

(1)环境变量加载

通过./脚本.shsh 脚本.sh等方式执行脚本时,Shell先查找环境变量ENV(未定义则加载默认配置文件),加载顺序(不同Linux发行版略有差异):

  1. 系统级配置:/etc/profile(全局环境变量,所有用户生效)。
  2. 用户级配置:
    • 当前用户家目录.bash_profile(登录时加载,仅当前用户生效)。
    • 当前用户家目录.bashrc(非登录时加载,如打开终端)。
    • 系统级/etc/bashrc(所有用户Bash配置,补充.bashrc)。

环境加载完成后,脚本才能使用PATH(命令查找路径)、HOME(用户家目录)等变量。

(2)脚本逐行执行

加载环境后,Shell从Shebang后开始,从上至下、从左至右执行每条命令/语句:

  • 普通命令(lsmkdir):直接调用系统命令并等待结果。
  • 变量定义(VAR=123):在当前Shell(或子Shell)内存中创建变量。
  • 控制结构(if-elsefor):根据条件执行分支或循环命令块。
(3)子脚本(脚本嵌套)处理

脚本中调用其他脚本(子脚本,如./sub_script.sh)时:

  1. 暂停父脚本执行,创建子Shell进程。
  2. 在子Shell中执行子脚本(遵循“环境加载→逐行执行”流程)。
  3. 子脚本执行完成后,销毁子Shell,返回父脚本继续执行后续命令。

示例(父脚本parent.sh调用子脚本child.sh):

#child.sh  # 调用子脚本
echo "test2"#parent.sh
echo "test1"
./child.sh
echo "test3"

执行./parent.sh输出:

test1
test2
test3

2. 脚本执行的原理

Shell执行命令时不直接执行,而是创建子进程让子进程完成,核心目的是“隔离风险,保护Shell主进程”:

(1)子进程的创建与作用
  • Shell接收到命令(如lssh test.sh)时,通过fork()创建子进程(复制当前Shell内存空间,含环境变量、变量等)。
  • 子进程通过exec()加载并执行目标命令(命令路径由PATH查找)。
  • 父进程(Shell主进程)通过wait()等待子进程执行完成,回收资源(避免僵尸进程)。
(2)风险隔离的意义

Shell是用户与Linux内核交互的核心工具,若主进程因命令出错崩溃,用户无法输入命令,需重新登录。子进程执行命令可隔离风险,即使子进程崩溃,也不影响主进程,保障系统交互连续性。

(3)无subprocess执行的特殊场景

以下两种方式不创建子进程,命令直接在Shell主进程中执行:

  • . 脚本.sh(点号执行)。
  • source 脚本.sh(source执行)。

示例:执行source test.sh,脚本中定义的VAR=123会存入Shell主进程内存,执行后echo $VAR输出123;而sh test.sh执行时,变量仅存在于子进程,主进程中VAR为空。

3. 写脚本注意事项

遵循以下规范可减少错误,提高脚本可读性、可维护性:

注意事项详细说明示例
开头加Shebang第一行指定解释器(如#!/bin/bash),避免系统默认/bin/sh导致兼容性问题错误:无Shebang,直接echo "test"
正确:#!/bin/bash后写echo "test"
语法缩进与注释控制结构(if/for/while)代码块用4个空格缩进(不推荐Tab,避免编辑器显示异常);关键步骤、复杂逻辑前加注释
(2)执行过程调试:bash -x 脚本名
  • 功能:执行脚本并打印每步执行过程,每条命令前输出带+的命令内容(含变量替换后的实际命令),便于跟踪变量值和流程。
  • 适用场景:脚本能执行但结果不符合预期(逻辑错误、变量值异常)。
  • 示例:
    # 脚本test.sh(判断参数是否大于10)
    #!/bin/bash
    if [ $1 -gt 10 ]; thenecho "$1 is greater than 10"
    elseecho "$1 is less than or equal to 10"
    fi# 开启调试执行(传入参数5)
    bash -x test.sh 5
    # 输出调试过程:
    # + '[' 5 -gt 10 ']'(显示替换后的条件判断)
    # + echo '5 is less than or equal to 10'(显示执行的echo命令)
    # 5 is less than or equal to 10(脚本输出结果)
    
(3)特殊字符匹配:正则表达式辅助调试

处理文件、目录筛选时,Shell支持通过特殊字符类简化正则匹配:

字符类含义示例
[[:alpha:]]任意大小写字母(A-Z、a-z)匹配aB,不匹配1_
[[:digit:]]任意数字(0-9)匹配59,不匹配a#
(4)综合调试案例

需求:编写脚本完成以下操作,用调试工具验证正确性:

  1. 创建目录/tmp/chenyu
  2. 切换到/tmp/chenyu目录。
  3. 创建目录a1bb2c6cy
  4. 创建空文件xyx123y123
  5. 列出当前目录下以a6开头的文件/目录,导入到/tmp/file1
  6. 列出当前目录下以字母开头、后接1个任意数字、再后接任意长度字符的文件/目录,导入到/tmp/file2

实现脚本与调试过程:

#!/bin/bash
# 脚本名:file_operation.sh
# 功能:完成目录/文件创建与筛选
set -x  # 开启执行日志(调试用)
set -e  # 出错即退出# 步骤1:创建目录/tmp/chenyu
mkdir -p /tmp/chenyu
# 步骤2:切换到该目录
cd /tmp/chenyu
# 步骤3:创建3个目录
mkdir -p a1b b2c 6cy
# 步骤4:创建3个空文件
touch xy x123y 123
# 步骤5:筛选以a或6开头的文件/目录,写入/tmp/file1
# 正则:^a匹配以a开头,^6匹配以6开头,|表示“或”
ls -d * | grep -E '^a|^6' > /tmp/file1
ls -d * | grep "^[a|b]" > /tmp/file1
# 步骤6:筛选“字母开头]"个数字+任意字符”的文件/目录,写入/tmp/file2
# 正则:^[[:alpha:]]匹配字母开头,[[:digit:]]匹配1个数字,.*匹配任意长度字符
ls -d * | grep -E '^[[:alpha:]][[:digit:]].*' > /tmp/file2echo "Operation completed! Check /tmp/file1 and /tmp/file2."

调试执行:

  1. 语法检查:bash -n file_operation.sh,无输出表示语法正确。
  2. 过程调试:bash -x file_operation.sh,观察每步命令执行结果(如mkdir是否创建目录、grep是否正确筛选)。
  3. 结果验证:
    • cat /tmp/file1:输出a1b6cy(以a或6开头的目录)。
    • cat /tmp/file2:输出a1bb2c(字母开头+1个数字+任意字符的目录)、x123y(字母x开头+数字1+字符23y的文件)。

四、运算符

Shell原生不支持复杂运算,需通过工具或特定语法实现,主要分为“算术运算符”和“逻辑运算符”:

1. 算术运算符

用于整数运算(Shell原生不支持浮点运算),常见运算符及使用方式:

运算符功能语法格式(变量a、b为例)说明
+加法expr $a + $blet c=$a+$bc=$[a+b]c=$((a+b))expr中运算符两侧需加空格(如expr 1 + 2,非expr 1+2
-减法expr $a - $blet c=$a-$bc=$[a-b]c=$((a-b))同上,expr需加空格
*乘法expr $a \* $b*需转义)、let c=$a*$bc=$[a*b]c=$((a*b))expr*是通配符,需\转义;其他方式无需转义
/除法expr $b / $alet c=$b/$ac=$[b/a]c=$((b/a))仅支持整数除法(expr 5 / 2输出2,非2.5)
%取余(模运算)expr $b % $alet c=$b%$ac=$[b%a]c=$((b%a))结果为除法后的余数(expr 5 % 2输出1)
=赋值a=$blet a=$b将变量b的值赋给变量a
==相等判断[ $a == $b ](注意空格)用于条件判断,返回布尔值(真为0,假为非0),如if [ $a == $b ]; then echo "Equal"; fi
!=不相等判断[ $a != $b ](注意空格)==相反,如if [ $a != $b ]; then echo "Not Equal"; fi
算术运算示例
#!/bin/bash
# 定义两个整数变量
a=10
b=20# 1. 使用expr运算(需加空格,乘法转义)
sum_expr=`expr $a + $b`
mul_expr=`expr $a \* $b`
echo "expr sum: $sum_expr"  # 输出30
echo "expr multiply: $mul_expr"  # 输出200# 2. 使用let运算(无需空格,支持赋值)
let sum_let=$a+$b
let mul_let=$a*$b
echo "let sum: $sum_let"  # 输出30
echo "let multiply: $mul_let"  # 输出200# 3. 使用$[]运算(简洁,无需空格)
sum_bracket=$[a+b]
mul_bracket=$[a*b]
echo "$[] sum: $sum_bracket"  # 输出30
echo "$[] multiply: $mul_bracket"  # 输出200# 4. 使用$(( ))运算(推荐,兼容性好)
sum_double=$((a+b))
mul_double=$((a*b))
echo "$(( )) sum: $sum_double"  # 输出30
echo "$(( )) multiply: $mul_double"  # 输出200# 5. 相等判断
if [ $a == $b ]; thenecho "$a == $b"
elseecho "$a != $b"  # 输出10 != 20
fi
实战例题:编写脚本计算两个整数的四则运算

需求:传递两个整数作为脚本参数,计算并显示和、差、积、商。

#!/bin/bash
# 脚本名:calc.sh
# 功能:计算两个整数的四则运算
# 参数:$1(第一个整数)、$2(第二个整数)# 检查参数数量是否为2
if [ $# -ne 2 ]; thenecho "Usage: $0 <integer1> <integer2>"exit 1
fi# 检查参数是否为整数(正则匹配)
if ! [[ $1 =~ ^[0-9]+$ && $2 =~ ^[0-9]+$ ]]; thenecho "Error: Both parameters must be integers!"exit 1
fi# 定义两个整数变量
num1=$1
num2=$2# 计算四则运算
sum=$((num1 + num2))
diff=$((num1 - num2))
product=$((num1 * num2))# 处理除法(避免除数为0)
if [ $num2 -eq 0 ]; thenquotient="Error: Division by zero!"
elsequotient=$((num1 / num2))
fi# 输出结果
echo "Calculation Result:"
echo "Sum: $num1 + $num2 = $sum"
echo "Difference: $num1 - $num2 = $diff"
echo "Product: $num1 * $num2 = $product"
echo "Quotient: $num1 / $num2 = $quotient"

执行示例:

# 正常执行(参数10和5)
./calc.sh 10 5
# 输出:
# Calculation Result:
# Sum: 10 + 5 = 15
# Difference: 10 - 5 = 5
# Product: 10 * 5 = 50
# Quotient: 10 / 5 = 2# 除数为0
./calc.sh 10 0
# 输出:
# Calculation Result:
# Sum: 10 + 0 = 10
# Difference: 10 - 0 = 10
# Product: 10 * 0 = 0
# Quotient: 10 / 0 = Error: Division by zero!# 参数非整数
./calc.sh 10 abc
# 输出:Error: Both parameters must be integers!

2. 逻辑运算符

用于条件判断组合,实现“与”“或”逻辑,遵循“短路求值”规则(提前判断结果,避免不必要运算):

(1)逻辑与(&&):AND关系
  • 规则:两个条件都为真,结果为真;一个为假,结果为假
  • 短路特性:第一个条件为假,直接判定结果为假,不判断第二个条件。
  • 适用场景:需满足多个条件才执行命令(如“文件存在且有读写权限”)。

示例:

# 1. 两个条件都为真(文件存在且是普通文件)
file="/tmp/test.txt"
touch $file  # 创建文件
if [ -f $file ] && [ -r $file ]; thenecho "$file exists and is readable"  # 输出(文件存在且可读)
fi# 2. 第一个条件为假(文件不存在),第二个条件不判断
rm -f $file  # 删除文件
if [ -f $file ] && [ -r $file ]; thenecho "$file exists"  # 不输出(第一个条件为假,短路)
fi
(2)逻辑或(||):OR关系
  • 规则:一个条件为真,结果为真;两个都为假,结果为假
  • 短路特性:第一个条件为真,直接判定结果为真,不判断第二个条件。
  • 适用场景:满足任一条件即执行命令(如“文件不存在则创建,存在则输出提示”)。

示例:

file="/tmp/test.txt"# 1. 第一个条件为真(文件存在),第二个条件不判断
touch $file
if [ -f $file ] || [ mkdir -p /tmp/test ]; thenecho "$file exists or directory created"  # 输出(第一个条件为真,短路)
fi# 2. 两个条件都为假(文件不存在且目录创建失败,模拟无权限)
rm -f $file
chmod 000 /tmp  # 取消/tmp写权限
if [ -f $file ] || [ mkdir -p /tmp/test ]; thenecho "Condition met"  # 不输出(两个条件都为假)
elseecho "Both conditions failed"  # 输出
fi
chmod 1777 /tmp  # 恢复/tmp权限
逻辑运算符实际应用

脚本中常与命令退出码结合,实现“执行成功/失败后的分支处理”,示例:

# 备份MySQL数据库,成功输出提示,失败发送邮件告警
mysqldump -u root -p123456 dbname > /data/backup/db.sql && \
echo "MySQL backup completed successfully" || \
echo "MySQL backup failed! Please check." | mail -s "Backup Alert" admin@example.com
  • mysqldump执行成功(退出码0):执行&&echo(成功提示),||后命令不执行。
  • mysqldump执行失败(退出码非0):跳过&&后命令,执行||echomail(告警邮件)。

文章转载自:

http://krcfWqzJ.rzmzm.cn
http://zOn7TEKI.rzmzm.cn
http://tnknNqfj.rzmzm.cn
http://kCTu46vf.rzmzm.cn
http://ISX8rO4I.rzmzm.cn
http://pWqGh4nw.rzmzm.cn
http://HL4kA86V.rzmzm.cn
http://ELDU13GN.rzmzm.cn
http://LLDCMpcr.rzmzm.cn
http://xqy1tiPN.rzmzm.cn
http://EFodgONY.rzmzm.cn
http://cxybMOMn.rzmzm.cn
http://I0SxIpwi.rzmzm.cn
http://WE6Efw5z.rzmzm.cn
http://gyXEahsx.rzmzm.cn
http://hlIpGvkW.rzmzm.cn
http://vc1zVN5z.rzmzm.cn
http://BVIpj8jv.rzmzm.cn
http://8MAn7K0T.rzmzm.cn
http://t1Fv8lLx.rzmzm.cn
http://cIQlIGF1.rzmzm.cn
http://eVNuf46W.rzmzm.cn
http://GiekE6on.rzmzm.cn
http://DqztucPi.rzmzm.cn
http://kQJFIczh.rzmzm.cn
http://Fcy2re7n.rzmzm.cn
http://6SjVvCJk.rzmzm.cn
http://Kdy3ZZQF.rzmzm.cn
http://RaVUNYUD.rzmzm.cn
http://A9935XIg.rzmzm.cn
http://www.dtcms.com/a/375372.html

相关文章:

  • Redis 面试
  • 大学地理信息科学该如何学习才能好就业
  • 浅谈“SVMSPro视频切片”技术应用场景
  • OpenHarmony多模输入子系统全链路剖析:从HCS配置到HDI芯片驱动源码深度解读
  • 1. linux 下qt 应用开机自启,需要sudo时
  • QML中的Popup
  • Cursor Pro试用
  • shell介绍
  • vla 开源最强的模型是哪一个
  • FreeRTOS任务切换详解
  • 面试不会问题
  • 享元模式,用Qt/C++绘制森林
  • GO RPC 教学文档
  • Atlantis Word Processor:全方位的文字处理专家
  • [iOS] 单例模式的深究
  • 视频通话实现语音转文字
  • String-HashCode源码分析
  • 深入浅出C++继承机制:从入门到实战
  • 级联框的实现
  • android 性能优化—内存泄漏,内存溢出OOM
  • 从PyTorch到ONNX:模型部署性能提升
  • JAVA:实现快速排序算法的技术指南
  • SQL 触发器从入门到进阶:原理、时机、实战与避坑指南
  • 无标记点动捕技术:重塑展厅展馆的沉浸式数字交互新时代
  • 【Agent】DeerFlow Planner:执行流程与架构设计(基于真实 Trace 深度解析)
  • R语言读取excel文件数据-解决na问题
  • 在钉钉上长出的AI组织:森马的路径与启示
  • IntelliJ IDEA 中 JVM 配置参考
  • JVM(二)--- 类加载子系统
  • 9.ImGui-滑块