最近要下的专辑(5.22~XXX)

1.Dave Matthews

2.莫文蔚的全集

#!/bin/bash #================================================== # 🔧 通用磁盘性能测试脚本(增强版 | 带预热 + TXT报告 | 原始值提取) # # 🚀 使用方法: # ./disk_test.sh sda rw=read --time=300 # ./disk_test.sh nvme0n1 rw=randwrite runtime=600 # ./disk_test.sh -nowarmup sda rw=randread # 跳过预热 # ./disk_test.sh sda runtime=300 rw=randread bs=4k size=100% iodepth=64 ioengine=libaio numjobs=8 # # ✅ 特性: # - 不做任何单位换算,直接提取原始 IOPS/BW/延迟 字符串 # - 支持 /dev/sda, /dev/nvme0n1 等所有块设备 # - 所有结果保存至以时间戳命名的独立子目录 # - 自动提取第6行 IOPS/BW,第9行 avg 延迟(保持原格式) # - 纯 Bash + awk/sed 解析文本,不依赖 bc/jq #================================================== # 默认参数 DEFAULT_BS="4k" DEFAULT_IODEPTH=8 DEFAULT_NUMJOBS=1 DEFAULT_RW="read" DEFAULT_RUNTIME=60 DEFAULT_RAMP_TIME=5 DEFAULT_IOENGINE="libaio" DEFAULT_DIRECT=1 DEFAULT_SIZE="100%" # 输出根目录 OUTPUT_DIR="./fio_results" mkdir -p "$OUTPUT_DIR" # 全局 CSV 表头 CSV_FILE="$OUTPUT_DIR/fio_summary.csv" if [ ! -f "$CSV_FILE" ]; then echo "timestamp,test_type,devices,rw,bs,iodepth,numjobs,size,ioengine,runtime_sec,iops_str,bw_str,latency_str" > "$CSV_FILE" fi #-------------------------------------------------- # 显示帮助信息 show_help() { awk '/^#.*🚀.*使用方法/,/^#.*💡.*提示/' "$0" | sed 's/^# //' exit 0 } for arg in "$@"; do [[ "$arg" == "-h" || "$arg" == "--help" ]] && show_help; done #-------------------------------------------------- # 参数解析 #-------------------------------------------------- WARMUP_MODE="" DEVICE_LIST_STR="" SIZE="$DEFAULT_SIZE" IOENGINE="$DEFAULT_IOENGINE" RUNTIME="$DEFAULT_RUNTIME" RAMP_TIME="$DEFAULT_RAMP_TIME" DIRECT="$DEFAULT_DIRECT" CUSTOM_JOBNAME="" BS="" NUMJOBS="" IODEPTH="" RW="" while [ $# -gt 0 ]; do arg="$1"; shift case "$arg" in -warmup) WARMUP_MODE="force" ;; -nowarmup) WARMUP_MODE="skip" ;; bs=*) BS="${arg#*=}" ;; iodepth=*) IODEPTH="${arg#*=}" ;; numjobs=*) NUMJOBS="${arg#*=}" ;; rw=*) RW="${arg#*=}" ;; runtime=*) RUNTIME="${arg#*=}" ;; --time=*|time=*) RUNTIME="${arg#*=}" ;; ramp_time=*) RAMP_TIME="${arg#*=}" ;; --ioengine=*|ioengine=*) IOENGINE="${arg#*=}" ;; direct=*) DIRECT="${arg#*=}" ;; jobname=*) CUSTOM_JOBNAME="${arg#*=}" ;; size=*) SIZE="${arg#*=}" ;; *) if [ -z "$DEVICE_LIST_STR" ]; then DEVICE_LIST_STR="$arg" else echo "⚠️ 忽略未知参数: $arg" fi ;; esac done # 设置默认值 BS="${BS:-$DEFAULT_BS}" IODEPTH="${IODEPTH:-$DEFAULT_IODEPTH}" NUMJOBS="${NUMJOBS:-$DEFAULT_NUMJOBS}" RW="${RW:-$DEFAULT_RW}" RUNTIME="${RUNTIME:-$DEFAULT_RUNTIME}" RAMP_TIME="${RAMP_TIME:-$DEFAULT_RAMP_TIME}" IOENGINE="${IOENGINE:-$DEFAULT_IOENGINE}" DIRECT="${DIRECT:-$DEFAULT_DIRECT}" SIZE="${SIZE:-$DEFAULT_SIZE}" # 检查设备 if [ -z "$DEVICE_LIST_STR" ]; then echo "❌ 错误:未指定任何设备!" show_help fi is_valid_device_short() { [[ "$1" =~ ^sd[a-z]+$ ]] || [[ "$1" =~ ^nvme[0-9]+n[0-9]+$ ]] } IFS=',' read -ra DEVICES_INPUT <<< "$DEVICE_LIST_STR" DEVICE_ARRAY=() for dev in "${DEVICES_INPUT[@]}"; do dev=$(echo "$dev" | xargs) full_dev="${dev#/dev/}"; full_dev="/dev/$full_dev" [[ "$dev" == /dev/* ]] && full_dev="$dev" if ! is_valid_device_short "$(basename "$full_dev")" && [[ ! -b "$full_dev" ]]; then echo "❌ 设备无效或不存在: $full_dev" exit 1 fi DEVICE_ARRAY+=("$full_dev") done # 检查 fio if ! command -v fio &> /dev/null; then echo "❌ 错误:fio 未安装,请运行 sudo apt install fio" exit 1 fi # 创建运行目录 TIMESTAMP_FULL="$(date '+%Y%m%d_%H%M%S')" DATE_STAMP="$(date '+%Y-%m-%d %H:%M:%S')" RUN_DIR="$OUTPUT_DIR/$TIMESTAMP_FULL" mkdir -p "$RUN_DIR" JOBNAME="${CUSTOM_JOBNAME:-${RW}_bs${BS}_iod${IODEPTH}_nj${NUMJOBS}_sz${SIZE}_eng_${IOENGINE##*/}_t${RUNTIME}s_${TIMESTAMP_FULL}}" TXT_OUT="$RUN_DIR/${JOBNAME}.txt" LOG_FILE="$RUN_DIR/summary.log" ERROR_LOG="$RUN_DIR/error.log" > "$LOG_FILE" [[ ! -f "$ERROR_LOG" ]] && echo "# FIO Error Log - $DATE_STAMP" > "$ERROR_LOG" TEST_TYPE="single_disk" (( ${#DEVICE_ARRAY[@]} > 1 )) && TEST_TYPE="concurrent_multi_disk" # 打印配置摘要 echo "🔧 主测试配置" printf " %-12s : %s\n" "Devices" "$(IFS=','; echo "${DEVICE_ARRAY[*]}")" printf " %-12s : %s\n" "RW Mode" "$RW" printf " %-12s : %s\n" "Block Size" "$BS" printf " %-12s : %s\n" "I/O Depth" "$IODEPTH" printf " %-12s : %s\n" "Num Jobs" "$NUMJOBS" printf " %-12s : %ss\n" "Runtime" "$RUNTIME" printf " %-12s : %s\n" "Test Range" "$SIZE" printf " %-12s : %s\n" "I/O Engine" "$IOENGINE" printf " %-12s : %s\n" "Test Type" "$TEST_TYPE" #-------------------------------------------------- # 预热逻辑 #-------------------------------------------------- prompt_warmup() { if [[ "$WARMUP_MODE" == "skip" ]]; then return 1; fi if [[ "$WARMUP_MODE" == "force" ]]; then return 0; fi echo "" echo "🔥 是否预热?" echo " 1) 是(推荐)" echo " 2) 否" while true; do read -p "选择 [1/2] > " ch case "$ch" in 1) return 0 ;; 2) return 1 ;; esac done } run_warmup() { local err="/tmp/fio_warmup_err_$$.log" > "$err" echo "🔄 预热中..." fio --name=warmup --rw=mixrandrw --rwmixread=70 --bs=4k --iodepth=16 --direct=1 \ --ioengine="$IOENGINE" --size="$SIZE" --output-format=normal \ $(printf -- '--filename=%s ' "${DEVICE_ARRAY[@]}") \ $( (( ${#DEVICE_ARRAY[@]} > 1 )) && echo "--group_reporting" ) \ > /dev/null 2>"$err" || echo "⚠️ 预热失败(详情见日志)" rm -f "$err" } prompt_warmup && run_warmup #-------------------------------------------------- # 执行主测试 #-------------------------------------------------- ERROR_CAPTURE="/tmp/fio_err_$$.log" > "$ERROR_CAPTURE" FIO_CMD=( fio --rw="$RW" --bs="$BS" --direct="$DIRECT" --ioengine="$IOENGINE" --iodepth="$IODEPTH" --numjobs="$NUMJOBS" --runtime="$RUNTIME" --ramp_time="$RAMP_TIME" --size="$SIZE" --time_based --output-format=normal --output="$TXT_OUT" ) for dev in "${DEVICE_ARRAY[@]}"; do FIO_CMD+=(--filename="$dev") done if (( ${#DEVICE_ARRAY[@]} > 1 )); then FIO_CMD+=(--group_reporting --name=multi_device_test) else FIO_CMD+=(--name="$JOBNAME") fi echo "" echo "🚀 正在运行主测试: $JOBNAME ..." echo "⏱️ 开始时间: $DATE_STAMP" if "${FIO_CMD[@]}" > /dev/null 2>"$ERROR_CAPTURE"; then echo "✅ 主测试完成" else echo "❌ fio 测试失败!返回码: $?" { echo "=======================================" echo "Timestamp: $DATE_STAMP" echo "Test Name: $JOBNAME" echo "Command: ${FIO_CMD[*]}" echo "--- Error Output ---" cat "$ERROR_CAPTURE" echo "" } >> "$ERROR_LOG" echo "📝 错误已记录到: $ERROR_LOG" rm -f "$ERROR_CAPTURE" exit 1 fi rm -f "$ERROR_CAPTURE" #-------------------------------------------------- # ✅ 统一提取函数:所有字段使用相同高可靠正则 #-------------------------------------------------- parse_fio_result_stable() { local file="$1" # 查找包含吞吐信息的行(读/写行 或 group_report) local throughput_line throughput_line=$(grep -i "\(iops\|bw\)" "$file" | grep -E "(^[[:space:]]*[rw].*:)|(group_report)" | head -1) # ✅ 统一使用 grep -oiE 提取字段(不区分大小写,精确匹配到分隔符前) local iops_raw=$(echo "$throughput_line" | grep -oiE "iops=[^,]*[^,[:space:]]" | cut -d= -f2 | xargs || echo "N/A") local bw_raw=$(echo "$throughput_line" | grep -oiE "bw=[^,]*[^,[:space:]]B.s" | cut -d= -f2 | xargs || echo "N/A") # 查找延迟 avg 行 local lat_line=$(grep -i "\(lat.*avg\|clat.*avg\)" "$file" | head -1) local lat_raw=$(echo "$lat_line" | grep -oiE "avg=[0-9.]*[^,[:space:]]*(ns|us|ms)" | cut -d= -f2 | xargs || echo "N/A") # 返回三者 echo "$iops_raw,$bw_raw,$lat_raw" } # 执行提取 echo "" RESULT=$(parse_fio_result_stable "$TXT_OUT") if [ -z "$RESULT" ] || ! echo "$RESULT" | grep -q ","; then echo "⚠️ 提取失败,使用 N/A" RESULT="N/A,N/A,N/A" fi IFS=',' read -r IOPS_RAW BW_RAW LAT_RAW <<< "$RESULT" # 写入 CSV devices_quoted=$(printf '%s' "${DEVICE_ARRAY[*]}" | sed 's/,/","/g') timestamp_log="$(date '+%Y-%m-%d %H:%M:%S')" { echo "$timestamp_log,$TEST_TYPE,\"$devices_quoted\",$RW,$BS,$IODEPTH,$NUMJOBS,$SIZE,$IOENGINE,$RUNTIME,\"$IOPS_RAW\",\"$BW_RAW\",\"$LAT_RAW\"" } >> "$CSV_FILE" # 写入 log printf "%s | %-50s -> IOPS=%-8s, BW=%-10s, Lat=%-8s\n" \ "$timestamp_log" "$JOBNAME" "$IOPS_RAW" "$BW_RAW" "$LAT_RAW" >> "$LOG_FILE" # 终端显示 echo "📊 提取结果: IOPS=$IOPS_RAW, BW=$BW_RAW, Lat=$LAT_RAW" # 软链接 + 完成提示 ln -sf "$TIMESTAMP_FULL" "$OUTPUT_DIR/latest" 2>/dev/null || true echo "" echo "🎉 测试成功完成!" echo "📁 目录: $RUN_DIR" echo "📄 报告: $TXT_OUT" echo "📊 摘要: $LOG_FILE" echo "📈 汇总: $CSV_FILE" echo "❗ 日志: $ERROR_LOG" 将以上代码提取lat修改为这条命令:local lat_raw=$(echo "$lat_line" |grep -i "\(lat.*avg\|clat.*avg\)" | cut -d= -f4 |sed -n '3p' |cut -d, -f1 |xargs) 把没用的lat提取命令去掉!然后提供完整代码给我!
11-12
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值