├── besttarce.sh ├── README.md ├── benchframe.sh └── fio.sh /besttarce.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 执行安装命令 4 | bash <(curl -Ls https://raw.githubusercontent.com/sjlleo/nexttrace/main/nt_install.sh) 5 | 6 | # 等待一段时间,确保安装完成 7 | 8 | # 运行程序 nexttrace,并模拟输入 1,回车,6,回车 9 | echo -e "1\n6\n" | nexttrace -T -F 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # benchframe 2 | 3 | 测试脚本聚合框架 4 | 5 | 特性:支持一次性自动化运行多个开源测试脚本,加入版权信息,后台运行,将结果提交到自建的pastebin,并通过 Telegram 进行通知。 6 | 7 | ## 快速开始 8 | 9 | ``` 10 | bash <(curl https://raw.githubusercontent.com/vpslog/benchframe/main/benchframe.sh) 11 | ``` 12 | 13 | 默认运行方式不支持高级功能,请继续查看使用说明 14 | 15 | ## 使用说明 16 | 17 | 请访问 [文档地址](https://blog.vpslog.org/blog/benchframe/) 18 | -------------------------------------------------------------------------------- /benchframe.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 休息 1 秒 4 | sleep 1 5 | # 清屏操作 6 | clear 7 | # 打印开始信息 8 | echo "测试脚本聚合框架 V1.0 by VPSLOG" 9 | echo "Github:https://github.com/vpslog/benchframe" 10 | echo "运行:bash <(curl https://raw.githubusercontent.com/vpslog/benchframe/main/benchframe.sh)" 11 | echo -e "教程:https://blog.vpslog.org/blog/benchframe/\n" 12 | # 记录脚本开始时间 13 | start_time=$(date +%s) 14 | 15 | # 默认 copyright 为空字符串 16 | COPYRIGHT="" 17 | 18 | # 默认不使用 screen 19 | USE_SCREEN=false 20 | 21 | # 默认的 Telegram Bot Token、User ID 和 pastebin 链接 22 | TELEGRAM_BOT_TOKEN="" 23 | TELEGRAM_USER_ID="" 24 | PASTEBIN_URL="https://pastebin.vpslog.org/" 25 | 26 | # 全局计数器 27 | counter=1 28 | 29 | # 保存所有参数到变量 30 | ALL_ARGS=("$@") 31 | 32 | # 处理参数 -c、-d、-t、-u 和 -p 33 | while getopts "c:dt:u:p:" opt; do 34 | case $opt in 35 | c) COPYRIGHT="$OPTARG";; 36 | d) USE_SCREEN=true;; 37 | t) TELEGRAM_BOT_TOKEN="$OPTARG";; 38 | u) TELEGRAM_USER_ID="$OPTARG";; 39 | p) PASTEBIN_URL="$OPTARG";; 40 | \?) echo "Invalid option: -$OPTARG" >&2; exit 1;; 41 | esac 42 | done 43 | 44 | # 如果使用 screen,则启动 screen 会话并运行脚本 45 | if [ "$USE_SCREEN" = true ]; then 46 | 47 | echo "安装 screen" 48 | # apt update > /dev/null 2>&1 && apt install screen -y > /dev/null 2>&1 49 | apt update && apt install screen -y 50 | echo "脚本已进入后台运行,请用 screen -r bench 命令查看运行状态,本窗口可以关闭" 51 | 52 | # 保存所有参数到变量,并从 ALL_ARGS 中去掉 -d 参数 53 | SCREEN_ARGS=("${ALL_ARGS[@]/-d}") 54 | 55 | # 下载 benchframe.sh 56 | curl -sL "https://raw.githubusercontent.com/vpslog/benchframe/main/benchframe.sh" > benchframe.sh 57 | 58 | # 使用 screen 运行 benchframe.sh,并传递所有参数 59 | screen -dmS bench bash -c "bash benchframe.sh ${SCREEN_ARGS[*]}" 60 | exit 61 | fi 62 | 63 | # 保存脚本执行结果的数组 64 | script_outputs=() 65 | 66 | # 函数定义:下载脚本到临时文件并执行替换操作 67 | run_script() { 68 | local script_name="$1" 69 | local script_url="$2" 70 | local temp_file=$(mktemp) 71 | local output_file="${counter}_output.txt" 72 | local interactive_input="$3" 73 | 74 | echo "####### 执行 $script_name 脚本 #######" 75 | # 下载脚本到临时文件 76 | curl -sL "$script_url" > "$temp_file" 77 | 78 | # 替换 clear 命令 79 | sed "s/clear/ > \"$output_file\"/" -i "$temp_file" 80 | 81 | # 执行脚本,同时保存结果到文件 82 | if [ -n "$interactive_input" ]; then 83 | echo -e "$interactive_input" | bash "$temp_file" | tee "$output_file" 84 | else 85 | bash "$temp_file" | tee "$output_file" 86 | fi 87 | 88 | # 将 COPYRIGHT 的内容写入到输出文件 89 | echo "$COPYRIGHT" >> "$output_file" 90 | echo "$COPYRIGHT" 91 | 92 | # 计数器递增 93 | ((counter++)) 94 | 95 | # 添加输出文件到数组 96 | script_outputs+=("$output_file") 97 | 98 | # 删除临时文件 99 | rm "$temp_file" 100 | } 101 | 102 | # 执行所有脚本 103 | run_script "基本测试" "https://bench.sh" 104 | run_script "GB5 测试" "https://raw.githubusercontent.com/i-abc/GB5/main/gb5-test.sh" "1\n" 105 | run_script "FIO 测试" "https://raw.githubusercontent.com/vpslog/benchframe/main/fio.sh" 106 | # run_script "三网测速" "https://raw.githubusercontent.com/i-abc/Speedtest/main/speedtest.sh" '2\n\n' 107 | run_script "三网测速" "https://bench.im/hyperspeed" '\n\n' 108 | run_script "教育网测速" "https://bench.im/hyperspeed" '6\n\n' 109 | # run_script "线路测试" "https://raw.githubusercontent.com/zhanghanyun/backtrace/main/install.sh" 110 | # run_script "流媒体解锁测试" "https://raw.githubusercontent.com/lmc999/RegionRestrictionCheck/main/check.sh" "1\n" 111 | run_script "流媒体解锁测试" "https://media.ispvps.com" "1\n" 112 | run_script "回程路由测试" "https://raw.githubusercontent.com/vpslog/benchframe/main/besttarce.sh" 113 | # 此脚本似乎有问题,不能自动退出 114 | # run_script "https://raw.githubusercontent.com/i-abc/Speedtest/main/speedtest.sh" '2\n' 115 | 116 | # 提交结果,注意 cat 命令输出时包含了空字节(null byte),而 Bash 不支持在命令替换中处理空字节,使用 tr 命令来删除文件中的空字节 117 | CONTENT=$(cat "${script_outputs[@]}" | tr -d '\000' | sed 's/\x1b\[[0-9;]*m//g') 118 | 119 | # 提交结果并提取返回值,注意 \n 不能直接写,直接提交似乎会有问题 120 | # 将内容保存到临时文件 121 | echo -e "测试脚本聚合框架 by VPSLOG"$'\n'"Github:https://github.com/vpslog/benchframe"$'\n'"运行:bash <(curl https://raw.githubusercontent.com/vpslog/benchframe/main/benchframe.sh)"$'\n'"教程:https://blog.vpslog.org/blog/benchframe/"$'\n\n'"$CONTENT" > temp_result_file.txt 122 | 123 | # 使用 curl 提交内容 124 | RESULT=$(curl -Fc=@temp_result_file.txt "$PASTEBIN_URL") 125 | 126 | # 删除临时文件 127 | rm temp_result_file.txt 128 | 129 | # 提取 url 和 admin 字段 130 | URL=$(echo "$RESULT" | grep -o '"url": "[^"]*' | awk -F'"' '{print $4}') 131 | ADMIN=$(echo "$RESULT" | grep -o '"admin": "[^"]*' | awk -F'"' '{print $4}') 132 | 133 | # 记录脚本结束时间 134 | end_time=$(date +%s) 135 | 136 | # 计算执行时间(秒) 137 | duration_seconds=$((end_time - start_time)) 138 | 139 | # 计算分钟和剩余秒数 140 | duration_minutes=$((duration_seconds / 60)) 141 | duration_seconds_remainder=$((duration_seconds % 60)) 142 | echo "脚本执行时间: $duration_minutes 分 $duration_seconds_remainder 秒" 143 | # 打印结果 144 | echo "结果链接: $URL" 145 | echo "修改或删除结果: $ADMIN" 146 | 147 | # 如果设置了 TELEGRAM_USER_ID 和 TELEGRAM_BOT_TOKEN,则发送 Telegram 通知 148 | if [ -n "$TELEGRAM_USER_ID" ] && [ -n "$TELEGRAM_BOT_TOKEN" ]; then 149 | # 发送 Telegram 通知 150 | MESSAGE="聚合框架提醒您:脚本已全部执行完毕。用时 $duration_minutes 分 $duration_seconds_remainder 秒"$'\n'"结果链接: $URL"$'\n'"修改或删除结果: $ADMIN" 151 | curl -s "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage" \ 152 | --data "text=$MESSAGE&chat_id=$TELEGRAM_USER_ID" > /dev/null 153 | fi 154 | 155 | #删除所有输出文件 156 | rm "${script_outputs[@]}" 157 | -------------------------------------------------------------------------------- /fio.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 基于以下两个 Github 仓库,只测 FIO 4 | # Yet Another Bench Script by Ivan Gao 5 | # Initial Sep 2022; Last update Sep 2022 6 | # 7 | # Disclaimer: This project is a work in progress. Any errors or suggestions should be 8 | # relayed to me via the GitHub project page linked below. 9 | # 10 | # Purpose: The purpose of this script is to quickly gauge the performance of a Linux 11 | # - sequential disk performance via fio. 12 | # The script is designed to not require any dependencies 13 | # - either compiled or installed - nor admin privileges to run. 14 | # 15 | # VERSION="v2022-09-13" 16 | 17 | # echo -e '# ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #' 18 | # echo -e '# Disk-Bench-Script #' 19 | # echo -e '# '$VERSION' #' 20 | # echo -e '# https://github.com/ivankf/bench #' 21 | # echo -e '# ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## #' 22 | 23 | echo -e 24 | date 25 | TIME_START=$(date '+%Y%m%d-%H%M%S') 26 | TARGET=$1 27 | 28 | # override locale to eliminate parsing errors (i.e. using commas as delimiters rather than periods) 29 | if locale -a | grep ^C$ > /dev/null ; then 30 | # locale "C" installed 31 | export LC_ALL=C 32 | else 33 | # locale "C" not installed, display warning 34 | echo -e "\nWarning: locale 'C' not detected. Test outputs may not be parsed correctly." 35 | fi 36 | 37 | # determine architecture of host 38 | ARCH=$(uname -m) 39 | if [[ $ARCH = *x86_64* ]]; then 40 | # host is running a 64-bit kernel 41 | ARCH="x64" 42 | elif [[ $ARCH = *i?86* ]]; then 43 | # host is running a 32-bit kernel 44 | ARCH="x86" 45 | elif [[ $ARCH = *aarch* || $ARCH = *arm* ]]; then 46 | KERNEL_BIT=`getconf LONG_BIT` 47 | if [[ $KERNEL_BIT = *64* ]]; then 48 | # host is running an ARM 64-bit kernel 49 | ARCH="aarch64" 50 | else 51 | # host is running an ARM 32-bit kernel 52 | ARCH="arm" 53 | fi 54 | echo -e "\nARM compatibility is considered *experimental*" 55 | else 56 | # host is running a non-supported kernel 57 | echo -e "Architecture not supported by bench." 58 | exit 1 59 | fi 60 | 61 | # check for local fio installs 62 | command -v fio >/dev/null 2>&1 && LOCAL_FIO=true || unset LOCAL_FIO 63 | 64 | # check for curl/wget 65 | command -v curl >/dev/null 2>&1 && LOCAL_CURL=true || unset LOCAL_CURL 66 | 67 | # create a directory in the same location that the script is being run to temporarily store Bench-related files 68 | DATE=`date -Iseconds | sed -e "s/:/_/g"` 69 | BENCH_PATH=$TARGET/$DATE 70 | touch $BENCH_PATH.test 2> /dev/null 71 | # test if the user has write permissions in the current directory and exit if not 72 | if [ ! -f "$BENCH_PATH.test" ]; then 73 | echo -e 74 | echo -e "You do not have write permission in this directory. Switch to an owned directory and re-run the script.\nExiting..." 75 | exit 1 76 | fi 77 | rm $BENCH_PATH.test 78 | mkdir -p $BENCH_PATH 79 | # trap CTRL+C signals to exit script cleanly 80 | trap catch_abort INT 81 | # catch_abort 82 | # Purpose: This method will catch CTRL+C signals in order to exit the script cleanly and remove 83 | # bench-related files. 84 | function catch_abort() { 85 | echo -e "\n** Aborting BENCH. Cleaning up files...\n" 86 | rm -rf $BENCH_PATH 87 | unset LC_ALL 88 | exit 0 89 | } 90 | # format_speed 91 | # Purpose: This method is a convenience function to format the output of the fio disk tests which 92 | # always returns a result in KB/s. If result is >= 1 GB/s, use GB/s. If result is < 1 GB/s 93 | # and >= 1 MB/s, then use MB/s. Otherwise, use KB/s. 94 | # Parameters: 95 | # 1. RAW - the raw disk speed result (in KB/s) 96 | # Returns: 97 | # Formatted disk speed in GB/s, MB/s, or KB/s 98 | function format_speed { 99 | RAW=$1 # disk speed in KB/s 100 | RESULT=$RAW 101 | local DENOM=1 102 | local UNIT="KB/s" 103 | # ensure raw value is not null, if it is, return blank 104 | if [ -z "$RAW" ]; then 105 | echo "" 106 | return 0 107 | fi 108 | # check if disk speed >= 1 GB/s 109 | if [ "$RAW" -ge 1000000 ]; then 110 | DENOM=1000000 111 | UNIT="GB/s" 112 | # check if disk speed < 1 GB/s && >= 1 MB/s 113 | elif [ "$RAW" -ge 1000 ]; then 114 | DENOM=1000 115 | UNIT="MB/s" 116 | fi 117 | # divide the raw result to get the corresponding formatted result (based on determined unit) 118 | RESULT=$(awk -v a="$RESULT" -v b="$DENOM" 'BEGIN { print a / b }') 119 | # shorten the formatted result to two decimal places (i.e. x.xx) 120 | RESULT=$(echo $RESULT | awk -F. '{ printf "%0.2f",$1"."substr($2,1,2) }') 121 | # concat formatted result value with units and return result 122 | RESULT="$RESULT $UNIT" 123 | echo $RESULT 124 | } 125 | # format_iops 126 | # Purpose: This method is a convenience function to format the output of the raw IOPS result 127 | # Parameters: 128 | # 1. RAW - the raw IOPS result 129 | # Returns: 130 | # Formatted IOPS (i.e. 8, 123, 1.7k, 275.9k, etc.) 131 | function format_iops { 132 | RAW=$1 # iops 133 | RESULT=$RAW 134 | # ensure raw value is not null, if it is, return blank 135 | if [ -z "$RAW" ]; then 136 | echo "" 137 | return 0 138 | fi 139 | # check if IOPS speed > 1k 140 | if [ "$RAW" -ge 1000 ]; then 141 | # divide the raw result by 1k 142 | RESULT=$(awk -v a="$RESULT" 'BEGIN { print a / 1000 }') 143 | # shorten the formatted result to one decimal place (i.e. x.x) 144 | RESULT=$(echo $RESULT | awk -F. '{ printf "%0.1f",$1"."substr($2,1,1) }') 145 | RESULT="$RESULT"k 146 | fi 147 | echo $RESULT 148 | } 149 | # disk_test 150 | # Purpose: This method is designed to test the disk performance of the host using the partition that the 151 | # script is being run from using fio seq read/write speed tests. 152 | # Parameters: 153 | # - (none) 154 | function disk_test { 155 | if [[ "$ARCH" = "aarch64" || "$ARCH" = "arm" ]]; then 156 | FIO_SIZE=512M 157 | else 158 | FIO_SIZE=2G 159 | fi 160 | # run a quick test to generate the fio test file to be used by the actual tests 161 | echo -en "Generating fio test file at $TARGET..." 162 | $FIO_CMD --name=setup --ioengine=libaio --rw=read --bs=64k --iodepth=64 --numjobs=2 --size=$FIO_SIZE --runtime=1 --gtod_reduce=1 --filename=$DISK_PATH/test.fio --direct=1 --minimal &> /dev/null 163 | echo -en "\r\033[0K" 164 | # get array of block sizes to evaluate 165 | BLOCK_SIZES=("$@") 166 | for BS in "${BLOCK_SIZES[@]}"; do 167 | # run seq read/write mixed fio test with block size = $BS 168 | echo -en "Running fio seq mixed R+W disk test with $BS block size..." 169 | DISK_TEST=$(timeout 35 $FIO_CMD --name=seq_rw_$BS --ioengine=libaio --rw=rw --rwmixread=30 --bs=$BS --iodepth=64 --numjobs=2 --size=$FIO_SIZE --runtime=30 --gtod_reduce=1 --direct=1 --filename=$DISK_PATH/test.fio --group_reporting --minimal 2> /dev/null | grep seq_rw_$BS) 170 | DISK_IOPS_R=$(echo $DISK_TEST | awk -F';' '{print $8}') 171 | DISK_IOPS_W=$(echo $DISK_TEST | awk -F';' '{print $49}') 172 | DISK_IOPS=$(awk -v a="$DISK_IOPS_R" -v b="$DISK_IOPS_W" 'BEGIN { print a + b }') 173 | DISK_TEST_R=$(echo $DISK_TEST | awk -F';' '{print $7}') 174 | DISK_TEST_W=$(echo $DISK_TEST | awk -F';' '{print $48}') 175 | DISK_TEST=$(awk -v a="$DISK_TEST_R" -v b="$DISK_TEST_W" 'BEGIN { print a + b }') 176 | DISK_RESULTS_RAW+=( "$DISK_TEST" "$DISK_TEST_R" "$DISK_TEST_W" "$DISK_IOPS" "$DISK_IOPS_R" "$DISK_IOPS_W" ) 177 | DISK_IOPS=$(format_iops $DISK_IOPS) 178 | DISK_IOPS_R=$(format_iops $DISK_IOPS_R) 179 | DISK_IOPS_W=$(format_iops $DISK_IOPS_W) 180 | DISK_TEST=$(format_speed $DISK_TEST) 181 | DISK_TEST_R=$(format_speed $DISK_TEST_R) 182 | DISK_TEST_W=$(format_speed $DISK_TEST_W) 183 | DISK_RESULTS+=( "$DISK_TEST" "$DISK_TEST_R" "$DISK_TEST_W" "$DISK_IOPS" "$DISK_IOPS_R" "$DISK_IOPS_W" ) 184 | echo -en "\r\033[0K" 185 | done 186 | } 187 | # dd_test 188 | # Purpose: This method is invoked if the fio disk test failed. dd sequential speed tests are 189 | # not indiciative or real-world results, however, some form of disk speed measure 190 | # is better than nothing. 191 | # Parameters: 192 | # - (none) 193 | function dd_test { 194 | I=0 195 | DISK_WRITE_TEST_RES=() 196 | DISK_READ_TEST_RES=() 197 | DISK_WRITE_TEST_AVG=0 198 | DISK_READ_TEST_AVG=0 199 | # run the disk speed tests (write and read) thrice over 200 | while [ $I -lt 3 ] 201 | do 202 | # write test using dd, "direct" flag is used to test direct I/O for data being stored to disk 203 | DISK_WRITE_TEST=$(dd if=/dev/zero of=$DISK_PATH/$DATE.test bs=64k count=16k oflag=direct |& grep copied | awk '{ print $(NF-1) " " $(NF)}') 204 | VAL=$(echo $DISK_WRITE_TEST | cut -d " " -f 1) 205 | [[ "$DISK_WRITE_TEST" == *"GB"* ]] && VAL=$(awk -v a="$VAL" 'BEGIN { print a * 1000 }') 206 | DISK_WRITE_TEST_RES+=( "$DISK_WRITE_TEST" ) 207 | DISK_WRITE_TEST_AVG=$(awk -v a="$DISK_WRITE_TEST_AVG" -v b="$VAL" 'BEGIN { print a + b }') 208 | # read test using dd using the 1G file written during the write test 209 | DISK_READ_TEST=$(dd if=$DISK_PATH/$DATE.test of=/dev/null bs=8k |& grep copied | awk '{ print $(NF-1) " " $(NF)}') 210 | VAL=$(echo $DISK_READ_TEST | cut -d " " -f 1) 211 | [[ "$DISK_READ_TEST" == *"GB"* ]] && VAL=$(awk -v a="$VAL" 'BEGIN { print a * 1000 }') 212 | DISK_READ_TEST_RES+=( "$DISK_READ_TEST" ) 213 | DISK_READ_TEST_AVG=$(awk -v a="$DISK_READ_TEST_AVG" -v b="$VAL" 'BEGIN { print a + b }') 214 | I=$(( $I + 1 )) 215 | done 216 | # calculate the write and read speed averages using the results from the three runs 217 | DISK_WRITE_TEST_AVG=$(awk -v a="$DISK_WRITE_TEST_AVG" 'BEGIN { print a / 3 }') 218 | DISK_READ_TEST_AVG=$(awk -v a="$DISK_READ_TEST_AVG" 'BEGIN { print a / 3 }') 219 | } 220 | 221 | # check if disk performance is being tested and the host has required space (2G) 222 | AVAIL_SPACE=`df -k . | awk 'NR==2{print $4}'` 223 | if [[ -z "$SKIP_FIO" && "$AVAIL_SPACE" -lt 2097152 && "$ARCH" != "aarch64" && "$ARCH" != "arm" ]]; then # 2GB = 2097152KB 224 | echo -e "\nLess than 2GB of space available. Skipping disk test..." 225 | elif [[ -z "$SKIP_FIO" && "$AVAIL_SPACE" -lt 524288 && ("$ARCH" = "aarch64" || "$ARCH" = "arm") ]]; then # 512MB = 524288KB 226 | echo -e "\nLess than 512MB of space available. Skipping disk test..." 227 | # if the skip disk flag was set, skip the disk performance test, otherwise test disk performance 228 | elif [ -z "$SKIP_FIO" ]; then 229 | # Perform ZFS filesystem detection and determine if we have enough free space according to spa_asize_inflation 230 | ZFSCHECK="/sys/module/zfs/parameters/spa_asize_inflation" 231 | if [[ -f "$ZFSCHECK" ]];then 232 | mul_spa=$((($(cat /sys/module/zfs/parameters/spa_asize_inflation)*2))) 233 | warning=0 234 | poss=() 235 | 236 | for pathls in $(df -Th | awk '{print $7}' | tail -n +2) 237 | do 238 | if [[ "${PWD##$pathls}" != "${PWD}" ]]; then 239 | poss+=($pathls) 240 | fi 241 | done 242 | 243 | long="" 244 | m=-1 245 | for x in ${poss[@]} 246 | do 247 | if [ ${#x} -gt $m ];then 248 | m=${#x} 249 | long=$x 250 | fi 251 | done 252 | 253 | size_b=$(df -Th | grep -w $long | grep -i zfs | awk '{print $5}' | tail -c 2 | head -c 1) 254 | free_space=$(df -Th | grep -w $long | grep -i zfs | awk '{print $5}' | head -c -2) 255 | 256 | if [[ $size_b == 'T' ]]; then 257 | free_space=$(bc <<< "$free_space*1024") 258 | size_b='G' 259 | fi 260 | 261 | if [[ $(df -Th | grep -w $long) == *"zfs"* ]];then 262 | 263 | if [[ $size_b == 'G' ]]; then 264 | if [[ $(echo "$free_space < $mul_spa" | bc) -ne 0 ]];then 265 | warning=1 266 | fi 267 | else 268 | warning=1 269 | fi 270 | 271 | fi 272 | 273 | if [[ $warning -eq 1 ]];then 274 | echo -en "\nWarning! You are running BENCH on a ZFS Filesystem and your disk space is too low for the fio test. Your test results will be inaccurate. You need at least $mul_spa GB free in order to complete this test accurately. For more information, please see https://github.com/masonr/yet-another-bench-script/issues/13\n" 275 | fi 276 | fi 277 | 278 | echo -en "\nPreparing system for disk tests..." 279 | 280 | # create temp directory to store disk write/read test files 281 | DISK_PATH=$BENCH_PATH/disk 282 | mkdir -p $DISK_PATH 283 | 284 | if [[ -z "$PREFER_BIN" && ! -z "$LOCAL_FIO" ]]; then # local fio has been detected, use instead of pre-compiled binary 285 | FIO_CMD=fio 286 | else 287 | # download fio binary 288 | if [[ ! -z $LOCAL_CURL ]]; then 289 | curl -s --connect-timeout 5 --retry 5 --retry-delay 0 https://raw.githubusercontent.com/masonr/yet-another-bench-script/master/bin/fio/fio_$ARCH -o $DISK_PATH/fio 290 | else 291 | wget -q -T 5 -t 5 -w 0 https://raw.githubusercontent.com/masonr/yet-another-bench-script/master/bin/fio/fio_$ARCH -O $DISK_PATH/fio 292 | fi 293 | 294 | if [ ! -f "$DISK_PATH/fio" ]; then # ensure fio binary download successfully 295 | echo -en "\r\033[0K" 296 | echo -e "Fio binary download failed. Running dd test as fallback...." 297 | DD_FALLBACK=True 298 | else 299 | chmod +x $DISK_PATH/fio 300 | FIO_CMD=$DISK_PATH/fio 301 | fi 302 | fi 303 | 304 | if [ -z "$DD_FALLBACK" ]; then # if not falling back on dd tests, run fio test 305 | echo -en "\r\033[0K" 306 | 307 | # init global array to store disk performance values 308 | declare -a DISK_RESULTS DISK_RESULTS_RAW 309 | # disk block sizes to evaluate 310 | BLOCK_SIZES=( "4k" "64k" "512k" "1m" ) 311 | 312 | # execute disk performance test 313 | disk_test "${BLOCK_SIZES[@]}" 314 | fi 315 | 316 | if [[ ! -z "$DD_FALLBACK" || ${#DISK_RESULTS[@]} -eq 0 ]]; then # fio download failed or test was killed or returned an error, run dd test instead 317 | if [ -z "$DD_FALLBACK" ]; then # print error notice if ended up here due to fio error 318 | echo -e "fio disk speed tests failed. Run manually to determine cause.\nRunning dd test as fallback..." 319 | fi 320 | 321 | dd_test 322 | 323 | # format the speed averages by converting to GB/s if > 1000 MB/s 324 | if [ $(echo $DISK_WRITE_TEST_AVG | cut -d "." -f 1) -ge 1000 ]; then 325 | DISK_WRITE_TEST_AVG=$(awk -v a="$DISK_WRITE_TEST_AVG" 'BEGIN { print a / 1000 }') 326 | DISK_WRITE_TEST_UNIT="GB/s" 327 | else 328 | DISK_WRITE_TEST_UNIT="MB/s" 329 | fi 330 | if [ $(echo $DISK_READ_TEST_AVG | cut -d "." -f 1) -ge 1000 ]; then 331 | DISK_READ_TEST_AVG=$(awk -v a="$DISK_READ_TEST_AVG" 'BEGIN { print a / 1000 }') 332 | DISK_READ_TEST_UNIT="GB/s" 333 | else 334 | DISK_READ_TEST_UNIT="MB/s" 335 | fi 336 | 337 | # print dd sequential disk speed test results 338 | echo -e 339 | echo -e "dd Sequential Disk Speed Tests:" 340 | echo -e "---------------------------------" 341 | printf "%-6s | %-6s %-4s | %-6s %-4s | %-6s %-4s | %-6s %-4s\n" "" "Test 1" "" "Test 2" "" "Test 3" "" "Avg" "" 342 | printf "%-6s | %-6s %-4s | %-6s %-4s | %-6s %-4s | %-6s %-4s\n" 343 | printf "%-6s | %-11s | %-11s | %-11s | %-6.2f %-4s\n" "Write" "${DISK_WRITE_TEST_RES[0]}" "${DISK_WRITE_TEST_RES[1]}" "${DISK_WRITE_TEST_RES[2]}" "${DISK_WRITE_TEST_AVG}" "${DISK_WRITE_TEST_UNIT}" 344 | printf "%-6s | %-11s | %-11s | %-11s | %-6.2f %-4s\n" "Read" "${DISK_READ_TEST_RES[0]}" "${DISK_READ_TEST_RES[1]}" "${DISK_READ_TEST_RES[2]}" "${DISK_READ_TEST_AVG}" "${DISK_READ_TEST_UNIT}" 345 | else # fio tests completed successfully, print results 346 | DISK_RESULTS_NUM=$(expr ${#DISK_RESULTS[@]} / 6) 347 | DISK_COUNT=0 348 | 349 | # print disk speed test results 350 | echo -e "fio Disk Speed Tests (Mixed R/W 30/70):" 351 | echo -e "---------------------------------" 352 | 353 | while [ $DISK_COUNT -lt $DISK_RESULTS_NUM ] ; do 354 | if [ $DISK_COUNT -gt 0 ]; then printf "%-10s | %-20s | %-20s\n"; fi 355 | printf "%-10s | %-11s %8s | %-11s %8s\n" "Block Size" "${BLOCK_SIZES[DISK_COUNT]}" "(IOPS)" "${BLOCK_SIZES[DISK_COUNT+1]}" "(IOPS)" 356 | printf "%-10s | %-11s %8s | %-11s %8s\n" " ------" "---" "---- " "----" "---- " 357 | printf "%-10s | %-11s %8s | %-11s %8s\n" "Read" "${DISK_RESULTS[DISK_COUNT*6+1]}" "(${DISK_RESULTS[DISK_COUNT*6+4]})" "${DISK_RESULTS[(DISK_COUNT+1)*6+1]}" "(${DISK_RESULTS[(DISK_COUNT+1)*6+4]})" 358 | printf "%-10s | %-11s %8s | %-11s %8s\n" "Write" "${DISK_RESULTS[DISK_COUNT*6+2]}" "(${DISK_RESULTS[DISK_COUNT*6+5]})" "${DISK_RESULTS[(DISK_COUNT+1)*6+2]}" "(${DISK_RESULTS[(DISK_COUNT+1)*6+5]})" 359 | printf "%-10s | %-11s %8s | %-11s %8s\n" "Total" "${DISK_RESULTS[DISK_COUNT*6]}" "(${DISK_RESULTS[DISK_COUNT*6+3]})" "${DISK_RESULTS[(DISK_COUNT+1)*6]}" "(${DISK_RESULTS[(DISK_COUNT+1)*6+3]})" 360 | DISK_COUNT=$(expr $DISK_COUNT + 2) 361 | done 362 | fi 363 | fi 364 | 365 | # finished all tests, clean up all BENCH files and exit 366 | echo -e 367 | rm -rf $BENCH_PATH 368 | 369 | # reset locale settings 370 | unset LC_ALL --------------------------------------------------------------------------------