本文共 5453 字,大约阅读时间需要 18 分钟。
#!/bin/sh -e #-e 表明。若指令传回值不等于0,则立即退出shell# shellcheck disable=SC1091#相对路径执行脚本. ../../utils/sh-test-libOUTPUT="$(pwd)/output"RESULT_FILE="${OUTPUT}/result.txt"export RESULT_FILEITERATION="5"usage() { echo "Usage: $0 [-p] [-t ] [-i ] [-s ]" 1>&2 exit 1}#通过while parse 可选参数while getopts "p:t:i:s:" o; do case "$o" in # The current working directory will be used by default. # Use '-p' specify partition that used for dd test. p) PARTITION="${OPTARG}" ;; # CAUTION: if FS_TYPE not equal to the existing fs type of the partition # specified with '-p', the partition will be formatted. t) FS_TYPE="${OPTARG}" ;; # You may need to run dd test 4-5 times for an accurate evaluation. i) ITERATION="${OPTARG}" ;; s) SKIP_INSTALL="${OPTARG}" ;; *) usage ;; esacdone#定义shell 函数prepare_partition() { #-n 表示存在partition if [ -n "${PARTITION}" ]; then #通过blkid 输出的结果中查找PARTITION device_attribute="$(blkid | grep "${PARTITION}")" #如果没有找到PARTITION,则输出错误日志 [ -z "${device_attribute}" ] && error_msg "${PARTITION} NOT found" #找到这个PARTITION的文件系统fs的类型 fs_type=$(echo "${device_attribute}" \ | grep "TYPE=" \ | awk '{print $3}' \ | awk -F '"' '{print $2}') # If PARTITION specified, its FS_TYPE needs to be specified explicitly. # 文件系统类型不存在的话,输出错误日志 [ -z "${FS_TYPE}" ] && \ error_msg "Please specify ${PARTITION} filesystem with -t" # Try to format the partition if it is unformatted or not the same as # the filesystem type specified with parameter '-t'. if [ -n "${FS_TYPE}" ]; then if [ "${FS_TYPE}" != "${fs_type}" ]; then #如果这个PARTITION的文件系统的类型和用户指定的不一致,则umount 掉这个PARTITION umount "${PARTITION}" > /dev/null 2>&1 info_msg "Formatting ${PARTITION} to ${FS_TYPE}..." #根据用于指定的文件系统重新格式化PARTITION,这里可以看出fat32 这种文件系统的 #格式化命令和其他的文件系统不同 if [ "${FS_TYPE}" = "fat32" ]; then echo "y" | mkfs -t vfat -F 32 "${PARTITION}" else echo "y" | mkfs -t "${FS_TYPE}" "${PARTITION}" fi info_msg "${PARTITION} formatted to ${FS_TYPE}" fi fi # Mount the partition and enter its mount point. #通过df 命令看是否可以找到mount point mount_point="$(df |grep "${PARTITION}" | awk '{print $NF}')" if [ -z "${mount_point}" ]; then #如果找不到mount point的话,则mount到/mnt mount_point="/mnt" mount "${PARTITION}" "${mount_point}" info_msg "${PARTITION} mounted to ${mount_point}" fi #进入这个目录准备测试 cd "${mount_point}" fi}#定义一个shell函数用于写测试dd_write() { echo echo "--- dd write speed test ---" #删除这个文件 rm -f dd-write-output.txt #测试的partition 可能有多个,这里用for 循环 for i in $(seq "${ITERATION}"); do echo "Running iteration ${i}..." #删除文件 rm -f dd.img #drop cache echo 3 > /proc/sys/vm/drop_caches #执行dd 命令开始写测试 dd if=/dev/zero of=dd.img bs=1048576 count=1024 conv=fsync 2>&1 \ | tee -a "${OUTPUT}"/dd-write-output.txt done}#定义一个shell函数用于读测试,这个函数和写函数操作类似dd_read() { echo echo "--- dd read speed test ---" rm -f dd-read-output.txt for i in $(seq "${ITERATION}"); do echo "Running iteration ${i}..." echo 3 > /proc/sys/vm/drop_caches dd if=dd.img of=/dev/null bs=1048576 count=1024 2>&1 \ | tee -a "${OUTPUT}"/dd-read-output.txt done rm -f dd.img}parse_output() { test_case_id="$1" #如果不存在文件,则输出警告并通过return 退出 if ! [ -f "${OUTPUT}/${test_case_id}-output.txt" ]; then warn_msg "${test_case_id} output file is missing" return 1 fi itr=1 #逐行读取 while read -r line; do if echo "${line}" | egrep -q "(M|G)B/s"; then measurement="$(echo "${line}" | awk '{print $(NF-1)}')" units="$(echo "${line}" | awk '{print substr($NF,1,2)}')" result=$(convert_to_mb "${measurement}" "${units}") add_metric "${test_case_id}-itr${itr}" "pass" "${result}" "MB/s" itr=$(( itr + 1 )) fi #从这个文件中读取 done < "${OUTPUT}/${test_case_id}-output.txt" # For mutiple times dd test, calculate the mean, min and max values. # Save them to result.txt. if [ "${ITERATION}" -gt 1 ]; then #用eval 执行字符串中的内容,为啥不直接执行呢? eval "$(grep "${test_case_id}" "${OUTPUT}"/result.txt \ | awk '{ if(min=="") {min=max=$3}; if($3>max) {max=$3}; if($3< min) {min=$3}; total+=$3; count+=1; } END { print "mean="total/count, "min="min, "max="max; }')" #输出测试结果 # shellcheck disable=SC2154 add_metric "${test_case_id}-mean" "pass" "${mean}" "MB/s" # shellcheck disable=SC2154 add_metric "${test_case_id}-min" "pass" "${min}" "MB/s" # shellcheck disable=SC2154 add_metric "${test_case_id}-max" "pass" "${max}" "MB/s" fi}# Test run.#检查是否是root用户! check_root && error_msg "This script must be run as root"create_out_dir "${OUTPUT}"info_msg "About to run dd test..."info_msg "Output directory: ${OUTPUT}"#安装这两个toolpkgs="e2fsprogs dosfstools"install_deps "${pkgs}" "${SKIP_INSTALL}"#准备要测试的partitionprepare_partitioninfo_msg "dd test directory: $(pwd)"#dd写测试dd_writeparse_output "dd-write"#dd读测试dd_readparse_output "dd-read"
转载地址:http://sznmi.baihongyu.com/