shell脚本

Shell内容讲解

一、Shell 脚本基础概念

  1. 什么是 Shell 脚本?
    Shell 脚本是一个包含一系列 Shell 命令的文本文件,用于自动化执行任务(如文件操作、程序调用、系统管理等)。

  2. Shell 类型

    • bash(Bourne-Again Shell):Linux 系统默认 Shell。
    • sh(Bourne Shell):更早期的标准 Shell。
    • zshksh 等:其他变体,语法略有差异。
      推荐使用 bash,本教程以 bash 为例。

二、编写第一个 Shell 脚本

1. 创建脚本文件
# 创建文件并编辑
vim hello.sh
2. 编写脚本内容
#!/bin/bash          # Shebang 行:指定脚本解释器为 bash
echo "Hello World!"  # 输出文本
3. 赋予执行权限
chmod +x hello.sh    # 添加可执行权限
4. 运行脚本
./hello.sh           # 直接运行(需在脚本所在目录)
# 或
bash hello.sh        # 显式指定解释器

输出

Hello World!

三、Shell 脚本核心语法

以下是 Shell 脚本语法和使用的超详细指南,结合实用示例,涵盖从基础到进阶的核心内容:


一、Shell 脚本基础结构

1. Shebang 行

Shebang 行(又称 hashbang)是脚本文件的第一行,用于指定执行该脚本的解释器。当你在终端中直接运行脚本时,系统会根据 Shebang 行选择正确的解释器

  • 作用:指定脚本使用的解释器。
  • 语法
    #!/bin/bash  # 使用 bash 解释器
    #!/bin/sh   # 使用 sh 解释器
    
2. 注释
  • 单行注释:以 # 开头。
    # 这是一个注释
    
  • 多行注释(通过字符串技巧):
    : '
    这是
    多行注释
    '
    

二、变量与数据类型

1. 变量定义与使用
  • 定义变量(无数据类型,默认为字符串):
    name="Alice"      # 字符串
    count=10          # 整数
    files=$(ls)       # 命令执行结果赋值
    today=$(date +%F) # 日期格式化为字符串
    
  • 使用变量
    echo $name        # 直接引用
    echo "${name}"    # 推荐用 {} 包裹变量名
    
2. 变量作用域
  • 局部变量:默认仅在当前脚本或函数内有效。
  • 环境变量:通过 export 导出,子进程可继承。
    export PATH="/usr/local/bin:$PATH"
    
3. 特殊变量
变量含义
$HOME当前用户主目录的路径
$PATH可执行文件路径的列表
$0脚本名称
$1-$9第 1 到第 9 个参数
$#参数个数
$@所有参数(列表形式)
$*所有参数(字符串形式)
$?上一条命令的退出状态码,0通常表示没有错误,非0值表示有错误
$$当前脚本的进程 ID
$!最后一个后台命令的进程 ID
echo $PATH 

执行结果
在这里插入图片描述

三、条件判断

1. 基本语法
if [ 条件 ]; then# 命令
elif [ 条件 ]; then# 命令
else# 命令
fi
2. 条件测试类型
  • 数值比较

lt(less than):小于
le(less than or equal to):小于等于
gt(greater than):大于
ge(greater than or equal to):大于等于
eq(equal to):等于
ne(not equal to):不等于

[ $a -eq $b ]  # a == b
[ $a -ne $b ]  # a != b
[ $a -gt $b ]  # a > b
[ $a -lt $b ]  # a < b
  • 字符串比较

    [ "$str1" == "$str2" ]  # 字符串相等
    [ "$str1" != "$str2" ]  # 字符串不等
    [ -z "$str" ]           # 字符串为空
    [ -n "$str" ]           # 字符串非空
    
  • 文件/目录测试

    [ -f "file.txt" ]  # 文件存在且为普通文件
    [ -d "dir" ]       # 目录存在
    [ -e "path" ]      # 文件/目录存在
    [ -r "file" ]      # 文件可读
    [ -w "file" ]      # 文件可写
    [ -x "file" ]      # 文件可执行
    
3. 逻辑运算符
[ 条件1 ] && [ 条件2 ]  # AND
[ 条件1 ] || [ 条件2 ]  # OR
! [ 条件 ]              # NOT
4. 示例:检查文件是否存在
#!/bin/bash
file="data.txt"
if [ -f "$file" ]; thenecho "$file 存在"
elseecho "$file 不存在"
fi

四、循环结构

1. for 循环
  • 遍历列表
    for i in 1 2 3; doecho "数字: $i"
    done
    
  • 遍历命令输出
    for file in $(ls *.txt); doecho "处理文件: $file"
    done
    
2. while 循环
count=1
while [ $count -le 5 ]; doecho "计数: $count"((count++))
done
3. until 循环
count=1
until [ $count -gt 5 ]; doecho "计数: $count"((count++))
done
4. 循环控制
  • break:退出循环。
  • continue:跳过当前迭代。

五、函数

1. 定义与调用
# 定义函数
greet() {echo "Hello, $1!"
}# 调用函数
greet "Alice"  # 输出:Hello, Alice!
2. 返回值
  • 通过 return 返回状态码(0-255)

    is_even() {if [ $(($1 % 2)) -eq 0 ]; thenreturn 0  # 偶数,成功elsereturn 1  # 奇数,失败fi
    }is_even 4
    echo $?  # 输出 0
    
  • 通过 echo 返回数据

    add() {echo $(($1 + $2))
    }result=$(add 3 5)
    echo $result  # 输出 8
    
    • 外层 $(( )):表示这是一个算术运算表达式,Shell 会计算括号内的内容并返回结果。

    • 内部的 1 :表示函数的第一个参数(位置参数), 1:表示函数的第一个参数(位置参数), 1:表示函数的第一个参数(位置参数), 符号用于引用参数的值。

六、参数处理

1. 位置参数
#!/bin/bash
echo "脚本名: $0"
echo "第一个参数: $1"
echo "所有参数: $@"
2. 参数解析(getopts
#!/bin/bash
while getopts ":u:p:" opt; do  # 静默模式(以 : 开头)case $opt inu) user="$OPTARG" ;;p) pass="$OPTARG" ;;:) echo "错误:选项 -$OPTARG 需要参数" >&2; exit 1 ;;  # 缺少参数\?) echo "错误:无效选项 -$OPTARG" >&2; exit 1 ;;      # 未知选项esac
done
shift $((OPTIND - 1))  # 移除已解析的选项,保留剩余参数

运行示例:

./script.sh -u alice -p 1234
代码功能
  1. 通过 getopts 解析命令行参数 -u-p,分别获取用户名和密码。
  2. 将参数值保存到变量 userpass 中。
  3. 输出用户和密码信息。

getopts 用法详解

getopts 是 Bash 中解析命令行选项的标准工具,适合处理短选项(如 -u-p)。

1. 基本语法
while getopts "选项字符串" opt; docase $opt in# 处理逻辑esac
done
  • 选项字符串:定义支持的选项和是否带参数。
    • 单个字母表示选项(如 u 对应 -u)。
    • 字母后加 : 表示该选项需要参数(如 u: 表示 -u value)。
    • 若选项字符串以 : 开头(如 ":u:p:"),则静默处理错误(需自行捕获)。
2. 内置变量
  • $OPTARG:当前选项的参数值(仅当选项需要参数时有效)。
  • $OPTIND:下一个待处理参数的索引,通常用于 shift 跳过已解析的参数。
3. 错误处理
  • 无效选项opt 会被赋值为 ?
  • 缺少参数:若选项字符串以 : 开头,opt 会被赋值为 :,否则为 ?

对上面示例代码的改进

  1. 对必选参数进行校验:在示例中,如果用户未提供 -u-p,变量 userpass 可能为空,但脚本不会报错。
  2. 清理已解析参数:使用 shift $((OPTIND - 1)),避免后续处理位置参数时包含已解析的选项。

改进后的代码

#!/bin/bash
# 添加错误处理和参数校验
while getopts ":u:p:" opt; docase $opt inu) user="$OPTARG" ;;p) pass="$OPTARG" ;;:) echo "错误:选项 -$OPTARG 需要参数" >&2; exit 1 ;;\?) echo "错误:无效选项 -$OPTARG" >&2; exit 1 ;;esac
done# 校验必须参数
if [[ -z "$user" || -z "$pass" ]]; thenecho "错误:必须提供 -u 和 -p 参数" >&2echo "用法: $0 -u <用户> -p <密码>" >&2exit 1
fishift $((OPTIND - 1))  # 清理已解析的选项
echo "用户: $user, 密码: $pass"
  • 使用 [[ ]] 更安全(避免变量未定义的错误)
    • [[ -z “$var” ]] # 推荐
    • [ -z “$var” ] # 也可用,但需注意变量未定义的情况

正确执行
$ ./script.sh -u alice -p 1234
用户: alice, 密码: 1234
错误情况
  1. 无效选项

    $ ./script.sh -a
    错误:无效选项 -a
    
  2. 缺少参数

    $ ./script.sh -u
    错误:选项 -u 需要参数
    
  3. 未提供必选参数

    $ ./script.sh -u alice
    错误:必须提供 -u-p 参数
    用法: ./script.sh -u <用户> -p <密码>
    

  • getopts 是解析命令行选项的标准工具,需结合 case 和内置变量使用。
  • 通过选项字符串定义选项是否需要参数(如 u:)。
  • 错误处理需区分“无效选项”和“缺少参数”,并校验必要参数。
  • 使用 shift $((OPTIND - 1)) 清理已解析的参数。

七、错误处理

1. 错误退出
if [ ! -f "file.txt" ]; thenecho "错误:文件不存在" >&2  # 输出到标准错误exit 1
fi
2. 捕获信号
trap "echo '脚本被中断!'; exit" SIGINT
3. 调试模式
set -x   # 打印执行的命令
set -e   # 遇到错误立即退出
set -o pipefail  # 管道命令失败时退出

八、高级技巧

1. 数组操作
# 定义数组
fruits=("apple" "banana" "cherry")# 访问元素
echo ${fruits[0]}  # apple# 遍历数组
for fruit in "${fruits[@]}"; doecho "$fruit"
done# 数组长度
echo ${#fruits[@]}  # 3

在 Bash 脚本中,${fruits[@]} 中的 @ 符号用于 展开数组的所有元素,并确保每个元素被视为独立的字符串(即使元素包含空格或特殊字符)。以下是详细解释:


1.${num[@]}
安全展开数组所有元素,保留每个元素的独立性,是遍历数组的推荐方式。
2.@ 符号
代表数组的全部元素,配合双引号使用时,确保数据完整性和可靠性。
1. 数组定义与 @ 的作用
假设数组 fruits 定义如下:

fruits=("apple" "banana" "orange with spaces" "grape")
  • ${fruits[@]}
    展开数组的所有元素,每个元素保持独立。
    结果"apple" "banana" "orange with spaces" "grape"

  • 对比 ${fruits[*]}
    展开数组的所有元素,合并成一个字符串(默认用空格分隔)。
    结果"apple banana orange with spaces grape"


2. 关键区别
语法行为适用场景
"${fruits[@]}"每个元素保持独立,即使包含空格也会正确分割遍历数组元素,保留原始数据
"${fruits[*]}"所有元素合并成一个字符串,用 IFS 的第一个字符(默认空格)分隔需要整体输出数组内容时
${fruits[@]}(无引号)元素可能被二次分词(若元素含空格或通配符,会被拆分成多个部分)不推荐,可能导致意外行为
${fruits[*]}(无引号)同上,合并后的字符串可能被二次分词不推荐

3. 示例演示

场景 1:遍历数组元素(正确方式)
for fruit in "${fruits[@]}"; doecho "Fruit: $fruit"
done

输出

Fruit: apple
Fruit: banana
Fruit: orange with spaces
Fruit: grape
  • 即使元素包含空格(如 "orange with spaces"),也会被当作一个整体处理。
场景 2:错误用法(无引号)
for fruit in ${fruits[@]}; doecho "Fruit: $fruit"
done

输出

Fruit: apple
Fruit: banana
Fruit: orange
Fruit: with
Fruit: spaces
Fruit: grape
  • "orange with spaces" 被拆分成 3 个“虚假”元素,导致逻辑错误!

4. 技术细节
  • 引号的重要性
    使用 "${fruits[@]}" 时,双引号包裹是必须的,确保元素中的空格和特殊字符被保留。

  • 下标访问

    • fruits[0] 表示第一个元素(Bash 数组默认从 0 开始)。
    • fruits[-1] 表示最后一个元素。
  • 数组长度
    ${#fruits[@]} 返回数组元素个数。


5. 其他相关用法
  • 遍历索引

    for i in "${!fruits[@]}"; doecho "索引 $i: ${fruits[i]}"
    done
    
  • 数组拼接

    new_fruits=("${fruits[@]}" "kiwi" "mango")
    
  • 函数参数传递

    print_args() {for arg in "$@"; do  # "$@" 和 "${array[@]}" 行为一致echo "$arg"done
    }
    print_args "${fruits[@]}"
    
2. 关联数组
declare -A user
user["name"]="Alice"
user["age"]=30
echo "${user["name"]}"  # Alice
3. 子 Shell 和命令替换
# 子 Shell 中执行命令
(cd /tmp && ls)  # 不影响当前目录# 命令替换
files=$(ls)

九、实战示例

1. 备份日志文件
#!/bin/bash
backup_dir="/backup/logs"
log_dir="/var/log"
timestamp=$(date +%Y%m%d)mkdir -p "$backup_dir"
tar -czf "$backup_dir/logs_$timestamp.tar.gz" "$log_dir"
echo "备份完成: $backup_dir/logs_$timestamp.tar.gz"
2. 监控 CPU 使用率
#!/bin/bash
threshold=80
cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}')if (( $(echo "$cpu_usage > $threshold" | bc -l) )); thenecho "警告:CPU 使用率 ${cpu_usage}% 超过阈值 ${threshold}%!" | mail -s "CPU 警报" admin@example.com
fi
3. 批量重命名文件
#!/bin/bash
prefix="photo"
counter=1for file in *.jpg; donew_name="${prefix}_$(printf "%03d" $counter).jpg"mv "$file" "$new_name"((counter++))
done
4.自启动脚本

思路分析:
首先,配置文件列出需要启动的程序及其路径和参数。这样只需编辑配置文件,而不必修改脚本本身,提高灵活性和可维护性。

然后,脚本需要读取配置文件中的每个条目,并依次启动这些程序。需要考虑每个程序是否已经在运行,避免重复启动。这可以通过检查进程ID(PID)文件或者使用pgrep命令来实现。

另外,需要处理程序的启动顺序和依赖关系。如果某些程序需要先于其他程序启动,或者需要等待某个条件满足,脚本需要能够处理这些情况。

还需要考虑日志记录,记录每个程序的启动状态,方便后续排查问题。可以输出到系统日志或者自定义的日志文件中。

安全性也是一个方面。需要确保脚本和配置文件有适当的权限,防止未经授权的修改。特别是当脚本以root权限运行时,需要小心处理。
实现步骤:

  1. 创建一个配置文件,例如programs.conf,每行定义一个程序,包含名称、路径、参数等。

  2. 脚本读取该配置文件,逐行处理。

  3. 对于每个程序,检查是否已经在运行,如果未运行,则启动它。

  4. 记录启动结果到日志文件。

  5. 提供命令行参数,例如start、stop、restart等,以控制程序的行为。

#!/bin/bash# 配置文件路径
CONFIG_FILE="$(dirname "$0")/programs.conf"
# 日志文件路径
LOG_FILE="/var/log/auto_start.log"
# PID目录存放进程ID文件
PID_DIR="/var/run/auto_start"# 创建PID目录
mkdir -p "$PID_DIR"# 日志记录函数
log() {echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}# 读取配置文件并启动程序
start_programs() {while read -r line; do# 忽略注释和空行[[ "$line" =~ ^#.*$ || -z "$line" ]] && continue# 解析配置行: 名称, 命令, 参数name=$(echo "$line" | cut -d'|' -f1 | xargs)command=$(echo "$line" | cut -d'|' -f2 | xargs)args=$(echo "$line" | cut -d'|' -f3 | xargs)pid_file="${PID_DIR}/${name}.pid"# 检查进程是否已在运行if [ -f "$pid_file" ]; thenpid=$(cat "$pid_file")if ps -p "$pid" > /dev/null 2>&1; thenlog "程序 $name 已在运行 (PID: $pid)"continuefifi# 启动程序并记录PIDeval "$command $args" >> "${PID_DIR}/${name}.log" 2>&1 &pid=$!echo $pid > "$pid_file"log "启动 $name 成功 (PID: $pid)"done < "$CONFIG_FILE"
}# 停止所有程序
stop_programs() {for pid_file in "$PID_DIR"/*.pid; do[ -f "$pid_file" ] || continuename=$(basename "$pid_file" .pid)pid=$(cat "$pid_file")if kill -0 "$pid" > /dev/null 2>&1; thenkill "$pid"log "已停止 $name (PID: $pid)"elselog "程序 $name 未运行"firm -f "$pid_file"done
}# 查看程序状态
status_programs() {for pid_file in "$PID_DIR"/*.pid; do[ -f "$pid_file" ] || continuename=$(basename "$pid_file" .pid)pid=$(cat "$pid_file")if ps -p "$pid" > /dev/null 2>&1; thenecho "$name 正在运行 (PID: $pid)"elseecho "$name 未运行"fidone
}# 主程序逻辑
case "$1" instart)start_programs;;stop)stop_programs;;restart)stop_programssleep 2start_programs;;status)status_programs;;*)echo "用法: $0 {start|stop|restart|status}"exit 1
esac

📁 配套配置文件示例 (programs.conf)

# 格式: 名称 | 执行命令 | 参数
web_server | /usr/bin/python3 | -m http.server 8080
logger | /usr/bin/logger | --tag auto_start
monitor | /usr/bin/nmon | -f -s 5

📜 脚本功能说明

  1. 配置文件管理

    • 使用programs.conf文件定义需要自启动的程序
    • 支持注释(以#开头的行)
    • 格式:程序名称 | 执行命令 | 参数
  2. 进程管理

    • 自动生成PID文件(存放于/var/run/auto_start
    • 启动前检查进程是否已存在
    • 支持停止所有程序
  3. 日志记录

    • 操作日志记录到/var/log/auto_start.log
    • 每个程序单独记录输出到/var/run/auto_start/<程序名>.log
  4. 操作命令

    # 启动所有程序
    sudo ./auto_start.sh start# 停止所有程序
    sudo ./auto_start.sh stop# 重启所有程序
    sudo ./auto_start.sh restart# 查看运行状态
    sudo ./auto_start.sh status
    

🔧 部署说明

  1. 将脚本保存为/usr/local/bin/auto_start.sh
  2. 创建配置文件/etc/auto_start.conf
  3. 设置可执行权限:
    chmod +x /usr/local/bin/auto_start.sh
    
  4. 配置systemd服务(实现开机自启):
    # /etc/systemd/system/auto-start.service
    [Unit]
    Description=Auto Start Programs
    After=network.target[Service]
    Type=oneshot
    ExecStart=/usr/local/bin/auto_start.sh start
    RemainAfterExit=yes[Install]
    WantedBy=multi-user.target
    
  5. 启用服务:
    systemctl enable auto-start.service
    

⚠️ 注意事项

  1. 需要使用root权限运行(建议通过systemd管理)
  2. 程序参数包含特殊字符时需正确转义
  3. PID文件可能需要在系统重启后清理
  4. 建议对敏感命令进行权限控制

十、Shell 脚本最佳实践

  1. 代码规范

    • 使用 shellcheck 检查语法。
    • 变量名使用小写,常量用大写。
    • 添加清晰的注释。
  2. 安全性

    • 避免 eval 和未过滤的用户输入。
    • 使用 set -euo pipefail 增强错误处理。
  3. 性能优化

    • 减少子 Shell 使用。
    • 避免在循环中调用外部命令。

/etc/shells文件解析

/etc/shells 是 Linux 和类 Unix 系统中一个重要的配置文件,它列出了系统认可的合法 Shell 路径。以下是关于该文件的详细讲解:

1. 文件作用

  • 定义合法 Shell
    /etc/shells 记录了系统允许用户使用的 Shell 程序路径。用户登录或切换 Shell 时,系统会检查其 Shell 是否在此列表中。
  • 安全限制
    某些服务(如 FTP、SSH)会验证用户的 Shell 是否在 /etc/shells 中。如果不在,可能拒绝登录(例如 FTP 用户若使用未列出的 Shell,会报错 This account is not available)。

2. 文件格式

  • 每行一个路径
    文件中的每一行都是一个 Shell 的绝对路径,例如:
    /bin/sh
    /bin/bash
    /usr/bin/zsh
    /usr/bin/fish
    

3. 查看文件内容

使用以下命令查看当前系统认可的 Shell:

cat /etc/shells

输出示例:

/bin/sh
/bin/bash
/usr/bin/bash
/bin/dash
/usr/bin/zsh

4. 与用户账户的关系

  • 用户默认 Shell
    用户的默认 Shell 定义在 /etc/passwd 文件的最后一个字段。例如:

    alice:x:1001:1001:Alice:/home/alice:/bin/bash
    

    这里用户 alice 的 Shell 是 /bin/bash

  • 切换 Shell
    使用 chsh 命令切换用户 Shell 时,系统会检查目标 Shell 是否在 /etc/shells 中:

    chsh -s /usr/bin/zsh  # 需确保 /usr/bin/zsh 已添加到 /etc/shells
    

修改完后要注销后才能生效

5. 如何添加新的 Shell

如果安装了新的 Shell(如 fishzsh),需手动将其路径添加到 /etc/shells

  1. 编辑文件(需 root 权限):

    sudo nano /etc/shells
    
  2. 添加路径

    # 添加新安装的 Shell 路径
    /usr/bin/fish
    
  3. 验证

    cat /etc/shells | grep fish
    

6. 常见问题与解决

  • 问题 1:用户无法登录
    原因:用户的 Shell 不在 /etc/shells 中。
    解决

    1. 通过恢复模式或单用户模式进入系统。
    2. 将缺失的 Shell 路径添加到 /etc/shells
  • 问题 2:chsh 报错 invalid shell
    原因:目标 Shell 未在 /etc/shells 中注册。
    解决
    按上述步骤添加 Shell 路径。


7. 实际应用场景

  • 限制 FTP 用户
    若 FTP 服务(如 vsftpd)配置为仅允许使用 /usr/sbin/nologin,需确保该路径存在于 /etc/shells
  • 容器环境
    在 Docker 容器中,若用户 Shell 被设置为 /bin/false,需确认该路径已添加到 /etc/shells

总结

  • /etc/shells 是系统合法 Shell 的白名单,直接影响用户登录和 Shell 切换。
  • 维护此文件时需谨慎,避免误删默认 Shell 路径导致登录问题。
  • 添加新 Shell 后,用户需通过 chsh 切换才能生效。

此生谁料,心在天山,身老沧洲。 —陆游

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/9757.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python:斐索实验(Fizeau experiment)

斐索实验&#xff08;Fizeau experiment&#xff09;是在1851年由法国物理学家阿曼德斐索&#xff08;Armand Fizeau&#xff09;进行的一项重要实验&#xff0c;旨在测量光在移动介质中的传播速度。这项实验的结果对当时的物理理论产生了深远的影响&#xff0c;并且在后来的相…

16.Word:石油化工设备技术❗【28】

目录 题目 NO1.2 NO3 NO4 题目 NO1.2 F12&#xff1a;另存为将“Word素材.docx”文件另存为“Word. docx”&#xff08;“docx”为文件扩展名&#xff09; 光标来到表格上方→插入→形状→新建画布→单击选中→格式→高度/宽度&#xff08;格式→大小对话框→取消勾选✔锁定…

计算机毕业设计Python+CNN卷积神经网络高考推荐系统 高考分数线预测 高考爬虫 协同过滤推荐算法 Vue.js Django Hadoop 大数据毕设

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

DeepSeek-R1本地部署笔记

文章目录 效果概要下载 ollama终端下载模型【可选】浏览器插件 UIQ: 内存占用高&#xff0c;显存占用不高&#xff0c;正常吗 效果 我的配置如下 E5 2666 V3 AMD 590Gme 可以说是慢的一批了&#xff0c;内存和显卡都太垃圾了&#xff0c;回去用我的新设备再试试 概要 安装…

zyNo.19

哈希&#xff08;md5&#xff09;绕过问题 本质上是弱类型问题的延申 题型 登录的哈希验证 $a ! $b Md5($a) md5($b) 解决办法Md5绕过 var_dump ("0e123456" "0e4456789"); //true 0e545993274517709034328855841020//true 参考资料0e开头的哈希…

爬虫基础(一)HTTP协议 :请求与响应

前言 爬虫需要基础知识&#xff0c;HTTP协议只是个开始&#xff0c;除此之外还有很多&#xff0c;我们慢慢来记录。 今天的HTTP协议&#xff0c;会有助于我们更好的了解网络。 一、什么是HTTP协议 &#xff08;1&#xff09;定义 HTTP&#xff08;超文本传输协议&#xff…

XCTF - IllIntentions wp

做 ctf 每天都是踩坑的一天 文章目录 题目概述我的做法frida hook 题目概述 这道题本身逻辑不复杂&#xff0c;有一个 MainActivity 和三个二级 Activity IsThisTheRealOne, ThisIsTheRealOne, DefinitelyNotThis。主 activity 是空白页面&#xff0c;注册了一个 Receiver Sen…

LNMP架构

一、概述 LNMP架构是一种常用于搭建动态网站的服务器架构组合&#xff0c;其名称由以下四个组件的首字母缩写组成&#xff1a; Linux&#xff1a;操作系统。Linux具有开源、稳定、安全、高性能等特点&#xff0c;是服务器领域广泛使用的操作系统。它为其他组件提供了运行环境和…

【Unity3D】实现2D角色/怪物死亡消散粒子效果

核心&#xff1a;这是一个Unity粒子系统自带的一种功能&#xff0c;可将粒子生成控制在一个Texture图片网格范围内&#xff0c;并且粒子颜色会自动采样图片的像素点颜色&#xff0c;之后则是粒子编辑出消散效果。 Particle System1物体&#xff08;爆发式随机速度扩散10000个粒…

芯片AI深度实战:基础篇之langchain

基于ollama, langchain,可以构建一个自己的知识库&#xff0c;比如这个 Build Your Own RAG App: A Step-by-Step Guide to Setup LLM locally using Ollama, Python, and ChromaDB | HackerNoon 这是因为&#xff1a; 以上范例就实现了这样一个流程&#xff1a; 系列文章&…

mybatis(134/134)完结

一级缓存&#xff08;默认情况下开启&#xff09;同一个sqlsession中执行相同的查询语句走一级缓存 二级缓存 &#xff1a;同一个sqlsessionfactory&#xff0c;sqlsession关闭了才会将一级缓存提交到二级缓存中 外部编写的缓存 PageHelper插件&#xff1a;方便进行分页&#x…

C++,STL 简介:历史、组成、优势

文章目录 引言一、STL 的历史STL 的核心组成三、STL 的核心优势四、结语进一步学习资源&#xff1a; 引言 C 是一门强大且灵活的编程语言&#xff0c;但其真正的魅力之一在于其标准库——尤其是标准模板库&#xff08;Standard Template Library, STL&#xff09;。STL 提供了…

不背单词快捷键(不背单词键盘快捷键)

文章目录 不背单词快捷键 不背单词快捷键 ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ        ‌‍ᅟᅠ    …

EasyExcel写入和读取多个sheet

最近在工作中&#xff0c;作者频频接触到Excel处理&#xff0c;因此也对EasyExcel进行了一定的研究和学习&#xff0c;也曾困扰过如何处理多个sheet&#xff0c;因此此处分享给大家&#xff0c;希望能有所帮助 目录 1.依赖 2. Excel类 3.处理Excel读取和写入多个sheet 4. 执…

JavaScript函数中this的指向

总结&#xff1a;谁调用我&#xff0c;我就指向谁&#xff08;es6箭头函数不算&#xff09; 一、ES6之前 每一个函数内部都有一个关键字是 this &#xff0c;可以直接使用 重点&#xff1a; 函数内部的 this 只和函数的调用方式有关系&#xff0c;和函数的定义方式没有关系 …

【C语言】内存函数

一、前言 在C语言中有着常见的内存函数&#xff0c;他们可以对内存进行操作&#xff0c;即可以修改内存的内容等&#xff0c;下面我们来简略地学习一下 二、memcpy(内存复制) cpy是复制的意思&#xff0c;顾名思义&#xff0c;就是将一块指定大小的内存的字节逐一赋值到新的内…

fscan全家桶更新:fscan免杀版,可过360、火绒、微步云沙箱,其他的自行测试

前言 fscan全家桶更新&#xff1a;fscan免杀版&#xff0c;可过360、火绒、微步云沙箱&#xff0c;其他的自行测试 其他版本 FscanPlus&#xff1a;fscan的plus版本 fs&#xff1a;有免杀效果 fscan低版本&#xff1a;自己重新编译的适合低版本系统的fscan FscanParser&a…

中间件安全

一.中间件概述 1.中间件定义 介绍&#xff1a;中间件&#xff08;Middleware&#xff09;作为一种软件组件&#xff0c;在不同系统、应用程序或服务间扮演着数据与消息传递的关键角色。它常处于应用程序和操作系统之间&#xff0c;就像一座桥梁&#xff0c;负责不同应用程序间…

微服务入门(go)

微服务入门&#xff08;go&#xff09; 和单体服务对比&#xff1a;里面的服务仅仅用于某个特定的业务 一、领域驱动设计&#xff08;DDD&#xff09; 基本概念 领域和子域 领域&#xff1a;有范围的界限&#xff08;边界&#xff09; 子域&#xff1a;划分的小范围 核心域…

js小游戏---2048(附源代码)

一、游戏页面展示 开始游戏&#xff1a; 游戏结束&#xff1a; 二、游戏如何操作 通过监听键盘的操作&#xff0c;进行移动变化 键盘上下左右键控制页面中所有模块同时向键入的方向移动&#xff0c;如果有两块一样的方块&#xff0c;就进行合并&#xff0c;并且在键盘每操作…