+ eval $LOGFE
+}
+
+get_runlevel_data()
+{
+ eval $LOGFS
+ local runlvl=''
+ local runlevel_path=$( type -p runlevel )
+ if [[ -n $runlevel_path ]];then
+ runlvl="$( $runlevel_path | gawk '{ print $2 }' )"
+ fi
+ echo $runlvl
+ eval $LOGFE
+}
+
+get_sensors_data()
+{
+ eval $LOGFS
+
+ local sensors_path=$( type -p sensors )
+
+ IFS=$'\n'
+ if [[ -n $sensors_path ]];then
+ # note: non-configured sensors gives error message, which we need to redirect to stdout
+ # also, -F ':' no space, since some cases have the data starting right after,like - :1287
+ A_SENSORS_DATA=( $(
+ $sensors_path | gawk -F ':' -v userCpuNo="$SENSORS_CPU_NO" '
+ BEGIN {
+ IGNORECASE=1
+ core0Temp="" # only if all else fails...
+ cpuTemp=""
+ cpuTempReal=""
+ fanWorking=""
+ indexCountaFanMain=0
+ indexCountaFanDefault=0
+ i=""
+ j=""
+ moboTemp=""
+ moboTempReal=""
+ psuTemp=""
+ separator=""
+ sysFanString=""
+ temp1=""
+ temp2=""
+ tempFanType="" # set to 1 or 2
+ tempUnit=""
+ tempWorking=""
+ tempWorkingUnit=""
+ }
+ # dumping the extra + signs after testing for them, nobody has negative temps.
+ # also, note gawk treats ° as a space, so we have to get the C/F data
+ # there are some guesses here, but with more sensors samples it will get closer.
+ # note: using arrays starting at 1 for all fan arrays to make it easier overall
+ # more validation because gensub if fails to get match returns full string, so
+ # we have to be sure we are working with the actual real string before assiging
+ # data to real variables and arrays. Extracting C/F degree unit as well to use
+ # when constructing temp items for array.
+ # note that because of charset issues, no tempUnit="°" tempWorkingUnit degree sign
+ # used, but it is required in testing regex to avoid error.
+ /^(M\/B|MB|SIO|SYS)(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
+ moboTemp=gensub( /[ \t]+\+([0-9\.]*)(.*)/, "\\1", 1, $2 )
+ tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
+ if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
+ tempUnit=tempWorkingUnit
+ }
+ }
+ /^CPU(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
+ cpuTemp=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
+ tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
+ if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
+ tempUnit=tempWorkingUnit
+ }
+ }
+ /^(P\/S|Power)(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
+ psuTemp=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
+ tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
+ if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
+ tempUnit=tempWorkingUnit
+ }
+ }
+ $1 ~ /^temp1$/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
+ tempWorking=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
+ if ( temp1 == "" || tempWorking > 0 ) {
+ temp1=tempWorking
+ }
+ tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
+ if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
+ tempUnit=tempWorkingUnit
+ }
+ }
+ $1 ~ /^temp2$/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
+ tempWorking=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
+ if ( temp2 == "" || tempWorking > 0 ) {
+ temp2=tempWorking
+ }
+ tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
+ if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
+ tempUnit=tempWorkingUnit
+ }
+ }
+
+ # final fallback if all else fails, funtoo user showed sensors putting
+ # temp on wrapped second line, not handled
+ /^(core0|core 0)(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
+ tempWorking=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
+ if ( core0Temp == "" || tempWorking > 0 ) {
+ core0Temp=tempWorking
+ }
+ tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
+ if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
+ tempUnit=tempWorkingUnit
+ }
+ }
+
+ # note: can be cpu fan:, cpu fan speed:, etc. Some cases have no space before
+ # $2 starts (like so :1234 RPM), so skip that space test in regex
+ /^CPU(.*)[ \t]*([0-9]+)[ \t]RPM/ {
+ aFanMain[1]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
+ }
+ /^(M\/B|MB|SYS)(.*)[ \t]*([0-9]+)[ \t]RPM/ {
+ aFanMain[2]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
+ }
+ /(Power|P\/S|POWER)(.*)[ \t]*([0-9]+)[ \t]RPM/ {
+ aFanMain[3]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
+ }
+ # note that the counters are dynamically set for fan numbers here
+ # otherwise you could overwrite eg aux fan2 with case fan2 in theory
+ # note: cpu/mobo/ps are 1/2/3
+ # NOTE: test: ! i in array does NOT work, this appears to be an awk/gawk bug
+ /^(AUX(1)? |CASE(1)? |CHASSIS(1)? )(.*)[ \t]*([0-9]+)[ \t]RPM/ {
+ for ( i = 4; i < 7; i++ ){
+ if ( i in aFanMain ){
+ ##
+ }
+ else {
+ aFanMain[i]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
+ break
+ }
+ }
+ }
+ /^(AUX([2-9]) |CASE([2-9]) |CHASSIS([2-9]) )(.*)[ \t]*([0-9]+)[ \t]RPM/ {
+ for ( i = 5; i < 30; i++ ){
+ if ( i in aFanMain ) {
+ ##
+ }
+ else {
+ sysFanNu = i
+ aFanMain[i]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
+ break
+ }
+ }
+ }
+ # in rare cases syntax is like: fan1: xxx RPM
+ /^(FAN(1)?[ \t:])(.*)[ \t]*([0-9]+)[ \t]RPM/ {
+ aFanDefault[1]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
+ }
+ /^FAN([2-9]|1[0-9])(.*)[ \t]*([0-9]+)[ \t]RPM/ {
+ fanWorking=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
+ sysFanNu=gensub( /fan([0-9]+)/, "\\1", 1, $1 )
+ if ( sysFanNu ~ /^([0-9]+)$/ ) {
+ # add to array if array index does not exist OR if number is > existing number
+ if ( sysFanNu in aFanDefault ) {
+ if ( fanWorking >= aFanDefault[sysFanNu] ) {
+ aFanDefault[sysFanNu]=fanWorking
+ }
+ }
+ else {
+ aFanDefault[sysFanNu]=fanWorking
+ }
+ }
+ }
+
+ END {
+ # first we need to handle the case where we have to determine which temp/fan to use for cpu and mobo:
+ # note, for rare cases of weird cool cpus, user can override in their prefs and force the assignment
+ if ( temp1 != "" && temp2 != "" ){
+ if ( userCpuNo != "" && userCpuNo ~ /(1|2)/ ) {
+ tempFanType=userCpuNo
+ }
+ else {
+ # first some fringe cases with cooler cpu than mobo: assume which is cpu temp based on fan speed
+ # but only if other fan speed is 0
+ if ( temp1 >= temp2 && 1 in aFanDefault && 2 in aFanDefault && aFanDefault[1] == 0 && aFanDefault[2] > 0 ) {
+ tempFanType=2
+ }
+ else if ( temp2 >= temp1 && 1 in aFanDefault && 2 in aFanDefault && aFanDefault[2] == 0 && aFanDefault[1] > 0 ) {
+ tempFanType=1
+ }
+ # then handle the standard case if these fringe cases are false
+ else if ( temp1 >= temp2 ) {
+ tempFanType=1
+ }
+ else {
+ tempFanType=2
+ }
+ }
+ }
+ # need a case for no temps at all reported, like with old intels
+ else if ( temp2 == "" && cpuTemp == "" ){
+ if ( temp1 == "" && moboTemp == "" ){
+ tempFanType=1
+ }
+ else if ( temp1 != "" && moboTemp == "" ){
+ tempFanType=1
+ }
+ else if ( temp1 != "" && moboTemp != "" ){
+ tempFanType=1
+ }
+ }
+
+ # then get the real cpu temp, best guess is hottest is real
+ if ( cpuTemp != "" ){
+ cpuTempReal=cpuTemp
+ }
+ else if ( tempFanType != "" ){
+ if ( tempFanType == 1 ){
+ cpuTempReal=temp1
+ }
+ else {
+ cpuTempReal=temp2
+ }
+ }
+ else {
+ cpuTempReal=temp1
+ }
+ # if all else fails, use core0 temp if it is present and cpu is null
+ if ( cpuTempReal == "" && core0Temp != "" ) {
+ cpuTempReal=core0Temp
+ }
+
+ # then the real mobo temp
+ if ( moboTemp != "" ){
+ moboTempReal=moboTemp
+ }
+ else if ( tempFanType != "" ){
+ if ( tempFanType == 1 ) {
+ moboTempReal=temp2
+ }
+ else {
+ moboTempReal=temp1
+ }
+ }
+ else {
+ moboTempReal=temp2
+ }
+ # then set the cpu fan speed
+ if ( aFanMain[1] == "" ) {
+ # note, you cannot test for aFanDefault[1] or [2] != ""
+ # because that creates an array item in gawk just by the test itself
+ if ( tempFanType == 1 && 1 in aFanDefault ) {
+ aFanMain[1]=aFanDefault[1]
+ aFanDefault[1]=""
+ }
+ else if ( tempFanType == 2 && 2 in aFanDefault ) {
+ aFanMain[1]=aFanDefault[2]
+ aFanDefault[2]=""
+ }
+ }
+
+ # then we need to get the actual numeric max array count for both fan arrays
+ for (i = 0; i <= 29; i++) {
+ if ( i in aFanMain && i > indexCountaFanMain ) {
+ indexCountaFanMain=i
+ }
+ }
+ for (i = 0; i <= 14; i++) {
+ if ( i in aFanDefault && i > indexCountaFanDefault ) {
+ indexCountaFanDefault=i
+ }
+ }
+
+ # clear out any duplicates. Primary fan real trumps fan working always if same speed
+ for (i = 1; i <= indexCountaFanMain; i++) {
+ if ( i in aFanMain && aFanMain[i] != "" && aFanMain[i] != 0 ) {
+ for (j = 1; j <= indexCountaFanDefault; j++) {
+ if ( j in aFanDefault && aFanMain[i] == aFanDefault[j] ) {
+ aFanDefault[j] = ""
+ }
+ }
+ }
+ }
+
+ # now see if you can find the fast little mobo fan, > 5000 rpm and put it as mobo
+ # note that gawk is returning true for some test cases when aFanDefault[j] < 5000
+ # which has to be a gawk bug, unless there is something really weird with arrays
+ # note: 500 > aFanDefault[j] < 1000 is the exact trigger, and if you manually
+ # assign that value below, the > 5000 test works again, and a print of the value
+ # shows the proper value, so the corruption might be internal in awk.
+ # Note: gensub is the culprit I think, assigning type string for range 501-1000 but
+ # type integer for all others, this triggers true for >
+ for (j = 1; j <= indexCountaFanDefault; j++) {
+ if ( j in aFanDefault && int( aFanDefault[j] ) > 5000 && aFanMain[2] == "" ) {
+ aFanMain[2] = aFanDefault[j]
+ aFanDefault[j] = ""
+ # then add one if required for output
+ if ( indexCountaFanMain < 2 ) {
+ indexCountaFanMain = 2
+ }
+ }
+ }
+
+ # then construct the sys_fan string for echo, note that iteration 1
+ # makes: fanDefaultString separator null, ie, no space or ,
+ for (j = 1; j <= indexCountaFanDefault; j++) {
+ fanDefaultString = fanDefaultString separator aFanDefault[j]
+ separator=","
+ }
+ separator="" # reset to null for next loop
+ # then construct the sys_fan string for echo
+ for (j = 1; j <= indexCountaFanMain; j++) {
+ fanMainString = fanMainString separator aFanMain[j]
+ separator=","
+ }
+
+ # and then build the temps:
+ if ( moboTempReal != "" ) {
+ moboTempReal = moboTempReal tempUnit
+ }
+ if ( cpuTempReal != "" ) {
+ cpuTempReal = cpuTempReal tempUnit
+ }
+
+ # if they are ALL null, print error message. psFan is not used in output currently
+ if ( cpuTempReal == "" && moboTempReal == "" && aFanMain[1] == "" && aFanMain[2] == "" && aFanMain[3] == "" && fanDefaultString == "" ) {
+ print "No active sensors found. Have you configured your sensors yet?"
+ }
+ else {
+ # then build array arrays:
+ print cpuTempReal "," moboTempReal "," psuTemp
+ # this is for output, a null print line does NOT create a new array index in bash
+ if ( fanMainString == "" ) {
+ fanMainString=","
+ }
+ print fanMainString
+ print fanDefaultString
+ }
+ }
+ '
+ ) )
+ # the error case needs to go here because we are setting special array delimiter ','
+ else
+ A_SENSORS_DATA=( "You do not have the sensors app installed." )
+ fi
+
+ IFS="$ORIGINAL_IFS"
+ log_function_data "A_SENSORS_DATA: ${A_SENSORS_DATA[@]}"
+# echo "A_SENSORS_DATA: ${A_SENSORS_DATA[@]}"
+ eval $LOGFE
+}
+
+get_unmounted_partition_data()
+{
+ eval $LOGFS
+ local a_unmounted_working='' mounted_partitions='' separator='' unmounted_fs=''
+ local dev_working='' uuid_working='' label_working=''
+
+ if [[ $B_PARTITIONS_FILE == 'true' ]];then
+ # set dev disk label/uuid data globals
+ get_partition_uuid_label_data 'label'
+ get_partition_uuid_label_data 'uuid'
+
+ # create list for slicing out the mounted partitions
+ for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
+ do
+ IFS=","
+ a_unmounted_working=( ${A_PARTITION_DATA[i]} )
+ IFS="$ORIGINAL_IFS"
+ if [[ -n ${a_unmounted_working[6]} ]];then
+ mounted_partitions="$mounted_partitions$separator${a_unmounted_working[6]}"
+ separator='|'
+ fi
+ done
+
+ A_UNMOUNTED_PARTITION_DATA=( $( grep -Ev '('$mounted_partitions')' $FILE_PARTITIONS | gawk '
+ BEGIN {
+ IGNORECASE=1
+ }
+ # note that size 1 means it is a logical extended partition container
+ # lvm might have dm-1 type syntax
+ # need to exclude loop type file systems, squashfs for example
+ /[a-z][0-9]+$|dm-[0-9]+$/ && $3 != 1 && $NF !~ /loop/ {
+ size = sprintf( "%.2f", $3*1024/1000**3 )
+ print $4 "," size "G"
+ }' ) )
+
+ for (( i=0; i < ${#A_UNMOUNTED_PARTITION_DATA[@]}; i++ ))
+ do
+ IFS=","
+ a_unmounted_working=( ${A_UNMOUNTED_PARTITION_DATA[i]} )
+ IFS="$ORIGINAL_IFS"
+
+ label_working=$( grep -E "${a_unmounted_working[0]}$" <<< "$DEV_DISK_LABEL" | gawk '{
+ print $(NF - 2)
+ }' )
+ uuid_working=$( grep -E "${a_unmounted_working[0]}$" <<< "$DEV_DISK_UUID" | gawk '{
+ print $(NF - 2)
+ }' )
+ unmounted_fs=$( get_unmounted_partition_filesystem "/dev/${a_unmounted_working[0]}" )
+
+ IFS=","
+ A_UNMOUNTED_PARTITION_DATA[i]=${a_unmounted_working[0]}","${a_unmounted_working[1]}","$label_working","$uuid_working","$unmounted_fs
+ IFS="$ORIGINAL_IFS"
+ done
+ fi
+# echo "${A_PARTITION_DATA[@]}"
+# echo "${A_UNMOUNTED_PARTITION_DATA[@]}"
+ eval $LOGFE
+}
+
+# a few notes, normally file -s requires root, but you can set user rights in /etc/sudoers.
+# list of file systems: http://en.wikipedia.org/wiki/List_of_file_systems
+# args: $1 - /dev/<disk><part> to be tested for
+get_unmounted_partition_filesystem()
+{
+ eval $LOGFS
+ local partition_filesystem='' sudo_command=''
+
+ if [[ $B_FILE_TESTED != 'true' ]];then
+ B_FILE_TESTED='true'
+ FILE_PATH=$( type -p file )
+ fi
+
+ if [[ $B_SUDO_TESTED != 'true' ]];then
+ B_SUDO_TESTED='true'
+ SUDO_PATH=$( type -p sudo )
+ fi
+
+ if [[ -n $FILE_PATH && -n $1 ]];then
+ # only use sudo if not root, -n option requires sudo -V 1.7 or greater. sudo will just error out
+ # which is the safest course here for now, otherwise that interactive sudo password thing is too annoying
+ # important: -n makes it non interactive, no prompt for password
+ if [[ $B_ROOT != 'true' && -n $SUDO_PATH ]];then
+ sudo_command='sudo -n '
+ fi
+ # this will fail if regular user and no sudo present, but that's fine, it will just return null
+ # note the hack that simply slices out the first line if > 1 items found in string
+ partition_filesystem=$( eval $sudo_command $FILE_PATH -s $1 | grep -Eio '(ext2|ext3|ext4|ext5|ext[[:space:]]|ntfs|fat32|fat16|fat[[:space:]]\(.*\)|vfat|fatx|tfat|swap|btrfs|ffs[[:space:]]|hfs\+|hfs[[:space:]]plus|hfs[[:space:]]extended[[:space:]]version[[:space:]][1-9]|hfsj|hfs[[:space:]]|jfs[[:space:]]|nss[[:space:]]|reiserfs|reiser4|ufs2|ufs[[:space:]]|xfs[[:space:]]|zfs[[:space:]])' | grep -Em 1 '.*' )
+ if [[ -n $partition_filesystem ]];then
+ echo $partition_filesystem
+ fi
+ fi
+ eval $LOGFE