Skip to content

Instantly share code, notes, and snippets.

@ggets
Last active June 22, 2019 13:21
Show Gist options
  • Save ggets/922d3528abb828aa3ab321b783e373ab to your computer and use it in GitHub Desktop.
Save ggets/922d3528abb828aa3ab321b783e373ab to your computer and use it in GitHub Desktop.
Check/Get TBW Live of a Samsung SSD
#!/bin/bash
################################################################################
### TBW for Samsung SSD ###
### -by GGetsov ###
### ------------------------------------------------------------------------ ###
### Requires: Cygwin, bash (with arrays support), bc, smartctl ###
################################################################################
arrtest[0]="1"||(echo "Failure: arrays not supported in this version of bash."&&exit 2)
#var
ver="0.0.4"
rev="22.06.2019"
declare -A b #binary tools
declare -A p #parameters
declare -A d #smart data
declare -A a #smart attributes
declare -A t #tbw life
declare -a e #errors
#fn
e(){
${b[echo]} -e "${@}"
}
err(){
e "${1:-Insufficient arguments. Type \"${0} --help\" to see usage help.}"
}
b(){
[ -z ${1+x} ]&&err "No commands to autodetect!"&&exit 1
while [[ "${#}" > "0" ]];do
t="$(type -t ${1})"
if [[ "${t}" == "builtin" ]]||[[ "${t}" == "function" ]]||[[ "${t}" == "alias" ]];then
b[${1}]="${1}"
elif [[ "${t}" == "file" ]];then
b[${1}]="$(type -p ${1})"
else
err "Could not find the command: ${1}"&&exit 1
fi
shift
done
}
#tools
b type echo printf bc
b[smartctl]="/computer/c/bin/smartmontools/bin/smartctl"
#arg
while [[ "${#}" > "0" ]];do
case "${1}" in
--help)
e "TBW for Samsung SSD script by hkr v${ver} (rev${rev})"
e " Usage:"
e " -d, --drive: Drive (Optional. Default: 'hda')"
e ""
e " --test: Only test print the string, don't execute"
e ""
exit 0
;;
-d|--drive)
[ -z ${2+x} ]||[[ ${2} == -* ]]&&err&&exit 1
p[drive]="${2}"
shift
;;
--test)
p[test]="1"
;;
*)
;;
esac
shift
done
#main
p[drive]="${p[drive]:=hda}" # default drive is 'hda'
t[250]="$[150*1024]"
t[500]="$[300*1024]"
t[1000]="$[600*1024]"
t[2000]="$[1200*1024]"
t[4000]="$[2400*1024]"
[ -z ${p[test]+x} ]||{
e "${b[smartctl]} -i -A ${p[drive]}"
exit 0
}
d[data]="$(${b[smartctl]} -i -A "${p[drive]}")"
[[ "${?}" > "0" ]]&&{
e "something went wrong."
exit 1
}
d[info]="${d[data]//=== START OF READ SMART DATA SECTION ===*}"
d[info]="${d[info]//*=== START OF INFORMATION SECTION ===}"
d[info]="${d[info]//[$'\r']}"
d[info]="${d[info]#"${d[info]%%[!$'\t\n ']*}"}"
d[info]="${d[info]%"${d[info]##*[!$'\t\n ']}"}"
IFS=$'\n'
al=(${d[info]})
unset IFS
for i in "${!al[@]}";do
k="${al[${i}]%%:[$'\t ']*}"
k="${k%%[$'\t ']is}"
v="${al[${i}]#*:}"
v="${v#"${v%%[!$'\t\n ']*}"}"
v="${v%"${v##*[!$'\t\n ']}"}"
a[${k}]="${v}"
done
d[attr]="${d[data]//*=== START OF READ SMART DATA SECTION ===}"
d[attr]="${d[attr]//*RAW_VALUE}"
d[attr]="${d[attr]//[$'\r']}"
d[attr]="${d[attr]#"${d[attr]%%[!$'\t\n ']*}"}"
d[attr]="${d[attr]%"${d[attr]##*[!$'\t\n ']}"}"
IFS=$'\n'
al=(${d[attr]})
unset IFS
for i in "${!al[@]}";do
arr=(${al[${i}]#"${al[${i}]%%[!$'\t\n ']*}"})
a[${arr[1]}]="${arr[-1]}"
done
[ -z ${a[Total_LBAs_Written]+x} ]&&{
e "This is not an SSD!"
exit 2
}
tbw="${a[Total_LBAs_Written]}"
tbw="$[${tbw:=0}*512]"
cap="${a[User Capacity]//,}"
cap="${cap%[$'\t ']bytes*}"
i="$[${cap}/1000/1000/1000]"
l="$[${t[${i}]}*1024*1024]"
wf="$(${b[bc]}<<<"scale=3;${tbw}/1024/${l}")"
df="${wf}"
[ "$(${b[bc]}<<<"${df}>1")" -eq 1 ]&&df="1"
p="$(${b[bc]}<<<"scale=1;(${wf}*100)/1")"
[ "$(${b[bc]}<<<"${p}<1")" -eq 1 ]&&[ "$(${b[bc]}<<<"${p}>0")" -eq 1 ]&&p="0${p}"
p=" ${p}% "
bl="60"
fw="$(${b[bc]}<<<"scale=0;(${bl}*${df}/1)")"
blr="$(${b[printf]} "%${fw}s")"
blf="${blr// /|}"
blr="$(${b[printf]} "%$[${bl}-${fw}]s")"
blb="${blr// /-}"
blr="${blf}${blb}"
bl="$[(${bl}/2)-(${#p}/2)]"
blb="${blr:$[${#blr}-${bl}]}"
[ "$((${#p}%2))" -ne "0" ]&&bl="$[${bl}-1]"
blf="${blr:0:${bl}}"
blr="${blf}${p}${blb}"
e "Life ( $[${tbw}/1024/1024/1024/1024]/$[${l}/1024/1024/1024] TB ):\n[${blr}]"
cap="${a[User Capacity]}"
cap="${cap#*[}"
cap="${cap%]*}"
e "Capacity: ${cap}"
e "TBW: $[${tbw}/1024/1024/1024] GB"
e "Temp: ${a[Airflow_Temperature_Cel]} C°"
e "Hours: ${a[Power_On_Hours]}"
e "Cycles: ${a[Power_Cycle_Count]}"
e "Firmware: ${a[Firmware Version]}"
e+=(Reallocated_Sector_Ct)
e+=(Runtime_Bad_Block)
e+=(Program_Fail_Cnt_Total)
e+=(Erase_Fail_Count_Total)
e+=(Reported_Uncorrect)
e "Errors: "
for i in "${!e[@]}";do e " ${a[${e[${i}]}]} (${e[${i}]})";done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment