2 ########################################################################
7 ########################################################################
9 ########################################################################
10 #### Special thanks to all those in #lsc and #smxi for their tireless
11 #### dedication helping test inxi modules.
12 ########################################################################
14 ########################################################################
15 #### inxi is a fork of infobash 3.02, the original bash sys info tool by locsmif
16 #### As time permits functionality improvements and recoding will occur.
18 #### inxi, the universal, portable, system information tool for irc.
19 #### Tested with Irssi, Xchat, Konversation, BitchX, KSirc, ircII,
20 #### Gaim/Pidgin, Weechat, KVIrc and Kopete.
21 #### Original infobash author and copyright holder:
22 #### Copyright (C) 2005-2007 Michiel de Boer a.k.a. locsmif
23 #### inxi version: Copyright (C) 2008-2016 Scott Rogers & Harald Hope
24 #### Further fixes (listed as known): Horst Tritremmel <hjt at sidux.com>
25 #### Steven Barrett (aka: damentz) - usb audio patch; swap percent used patch
26 #### Jarett.Stevens - dmidecde -M patch for older systems with the /sys
28 #### Current script home page/wiki/git: https://github.com/smxi/inxi
29 #### Documentation/wiki pages will move to http://smxi.org soon.
30 #### Script forums: http://techpatterns.com/forums/forum-33.html
31 #### IRC support: irc.oftc.net channel #smxi
33 #### * https://github.com/smxi/inxi
34 #### * git: git pull https://github.com/smxi/inxi master
35 #### * svn checkout url: https://github.com/smxi/inxi
37 #### This program is free software; you can redistribute it and/or modify
38 #### it under the terms of the GNU General Public License as published by
39 #### the Free Software Foundation; either version 3 of the License, or
40 #### (at your option) any later version.
42 #### This program is distributed in the hope that it will be useful,
43 #### but WITHOUT ANY WARRANTY; without even the implied warranty of
44 #### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45 #### GNU General Public License for more details.
47 #### You should have received a copy of the GNU General Public License
48 #### along with this program. If not, see <http://www.gnu.org/licenses/>.
50 #### If you don't understand what Free Software is, please read (or reread)
51 #### this page: http://www.gnu.org/philosophy/free-sw.html
52 ########################################################################
55 #### PACKAGE NAME NOTES
56 #### * Package names in (...) are the Debian Squeeze package name. Check your
57 #### distro for proper package name by doing this: which <application>
58 #### then find what package owns that application file. Or run --recommends
59 #### which shows package names for Debian/Ubuntu, Arch, and Fedora/Redhat/Suse
62 #### * bash >=3.0 (bash); df, readlink, stty, tr, uname, wc (coreutils);
63 #### gawk (gawk); grep (grep); lspci (pciutils);
64 #### ps, find (findutils)
65 #### * Also the proc filesystem should be present and mounted for Linux
66 #### * Some features, like -M and -d will not work, or will work incompletely,
67 #### if /sys is missing
69 #### Apparently unpatched bash 3.0 has arrays broken; bug reports:
70 #### http://ftp.gnu.org/gnu/bash/bash-3.0-patches/bash30-008
71 #### http://lists.gnu.org/archive/html/bug-bash/2004-08/msg00144.html
72 #### Bash 3.1 for proper array use
74 #### Arrays work in bash 2.05b, but "grep -Em" does not
76 #### RECOMMENDS (Needed to run certain features, listed by option)
77 #### -A - for output of usb audio information: lsusb (usbutils)
78 #### -Ax -Nx - for audio/network module version: modinfo (module-init-tools)
79 #### -Dx - for hdd temp output (root only default): hddtemp (hddtemp)
80 #### For user level hdd temp output: sudo (sudo)
81 #### Note: requires user action for this feature to run as user (edit /etc/sudoers file)
82 #### -G - full graphics output requires: glxinfo (mesa-utils); xdpyinfo (X11-utils);
83 #### xrandr (x11-xserver-utils)
84 #### -i - IP information, local/wan - ip (iproute) legacy, not used if ip present: ifconfig (net-tools)
85 #### -I - uptime (procps, check Debian if changed)
86 #### -Ix - view current runlevel while not in X window system (or with -x): runlevel (sysvinit)
87 #### -m - all systems, dmidecode, unless someone can find a better way.
88 #### -M - for older systems whose kernel does not have /sys data for machine, dmidecode (dmidecode)
89 #### -o - for unmounted file system information in unmounted drives (root only default): file (file)
90 #### Note: requires user action for this feature to run as user (edit /etc/sudoers file)
91 #### For user level unmounted file system type output: sudo (sudo)
92 #### -s For any sensors output, fan, temp, etc: sensors (lm-sensors)
93 #### Note: requires setup of lm-sensors (sensors-detect and adding modules/modprobe/reboot,
94 #### and ideally, pwmconfig) prior to full output being available.
95 #### -S For desktop environment, user must be in X and have xprop installed (in X11-utils)
96 ########################################################################
98 #### * sed -i '' form supported by using SED_I="-i ''".
99 #### * Note: New BSD sed supports using -r instead of -E for compatibility with gnu sed
100 #### However, older, like FreeBSD 7.x, does not have -r so using SED_RX='-E' for this.
101 #### * Gnu grep options can be used if the function component is only run in linux
102 #### These are the options that bsd grep does not support that inxi uses: -m <number> -o
103 #### so make sure if you use those to have them in gnu/linux only sections.
104 #### It appears that freebsd uses gnu grep but openbsd uses bsd grep, however.
105 #### * BSD ps does not support --without-headers option, and also does not support --sort <option>
106 #### Tests show that -m fails to sort memory as expected, but -r does sort cpu percentage.
107 #### * BSD_TYPE is set with values null, debian-bsd (debian gnu/kfreebsd), bsd (all other bsds)
108 #### * Subshell and array closing ) must not be on their own line unless you use an explicit \
109 #### to indicate that logic continues to next line where closing ) or )) are located.
110 ########################################################################
112 #### * Character Encoding: UTF-8 - this file contains special characters that must be opened and saved as UTF8
113 #### * Indentation: TABS
114 #### * Do not use `....` (back quotes), those are totally non-reabable, use $(....).
115 #### * Do not use one liner flow controls.
116 #### The ONLY time you should use ';' (semi-colon) is in this single case: if [[ condition ]];then.
117 #### Never use compound 'if': ie, if [[ condition ]] && statement.
118 #### * Note: [[ -n $something ]] - double brackets does not require quotes for variables: ie, "$something".
119 #### * Always use quotes, double or single, for all string values.
120 #### * All new code/methods must be in a function.
122 #### * For all boolean tests, use 'true' / 'false'.
123 #### !! Do NOT use 0 or 1 unless it's a function return.
124 #### * Avoid complicated tests in the if condition itself.
125 #### * To 'return' a value in a function, use 'echo <var>'.
126 #### * For gawk: use always if ( num_of_cores > 1 ) { hanging { starter for all blocks
127 #### This lets us use one method for all gawk structures, including BEGIN/END, if, for, etc
128 #### * Using ${VAR} is about 30% slower than $VAR because bash has to check the stuff for actions
129 #### SUBSHELLS ARE EXPENSIVE! - run these two if you do not believe me.
130 #### time for (( i=0; i<1000; i++ )) do ff='/usr/local/bin/foo.pid';ff=${ff##*/};ff=${ff%.*};done;echo $ff
131 #### time for (( i=0; i<1000; i++ )) do ff='/usr/local/bin/foo.pid';ff=$( basename $ff | cut -d '.' -f 1 );done;echo $ff
133 #### VARIABLE/FUNCTION NAMING:
134 #### * All functions should follow standard naming--verb adjective noun.
135 #### ie, get_cpu_data
136 #### * All variables MUST be initialized / declared explicitly, either top of file, for Globals, or using local
137 #### * All variables should clearly explain what they are, except counters like i, j.
138 #### * Each word of Bash variable must be separated by '_' (underscore) (camel form), like: cpu_data
139 #### * Each word of Gawk variable must be like this (first word lower, following start with upper): cpuData
140 #### * Global variables are 'UPPER CASE', at top of this file.
141 #### ie, SOME_VARIABLE=''
142 #### * Local variables are 'lower case' and declared at the top of the function using local, always.
143 #### ie: local some_variable=''
144 #### * Locals that will be inherited by child functions have first char capitalized (so you know they are inherited).
145 #### ie, Some_Variable
146 #### * Booleans should start with b_ (local) or B_ (global) and state clearly what is being tested.
147 #### * Arrays should start with a_ (local) or A_ (global).
150 #### * The color variable ${C2} must always be followed by a space unless you know what
151 #### character is going to be next for certain. Otherwise irc color codes can be accidentally
152 #### activated or altered.
153 #### * For native script konversation support (check distro for correct konvi scripts path):
154 #### ln -s <path to inxi> /usr/share/apps/konversation/scripts/inxi
155 #### DCOP doesn't like \n, so avoid using it for most output unless required, as in error messages.
156 #### * print_screen_output " " # requires space, not null, to avoid error in for example in irssi
157 #### * For logging of array data, array must be placed into the a_temp, otherwise only the first key logs
158 #### * In gawk search patterns, . is a wildcard EXCEPT in [0-9.] type containers, then it's a literal
159 #### So outside of bracketed items, it must be escaped, \. but inside, no need. Outside of gawk it should
160 #### be escaped in search patterns if you are using it as a literal.
162 #### PACKAGE MANAGER DATA (note, while inxi tries to avoid using package managers to get data, sometimes
163 #### it's the only way to get some data):
164 #### * dpkg options: http://www.cyberciti.biz/howto/question/linux/dpkg-cheat-sheet.php
165 #### * pacman options: https://wiki.archlinux.org/index.php/Pacman_Rosetta
167 #### As with all 'rules' there are acceptions, these are noted where used.
168 ###################################################################################
169 #### KDE Konversation information. Moving from dcop(qt3/KDE3) to dbus(qt4/KDE4)
170 ###################################################################################
171 #### * dcop and dbus -- these talk back to Konversation from this program
172 #### * Scripting info -- http://konversation.berlios.de/docs/scripting.html
173 #### -- http://www.kde.org.uk/apps/konversation/
174 #### * dbus info -- http://dbus.freedesktop.org/doc/dbus-tutorial.html
175 #### view dbus info -- https://fedorahosted.org/d-feet/
177 #### * Konvi dbus/usage-- qdbus org.kde.konversation /irc say <server> <target-channel> <output>
178 #### * Python usage -- http://wiki.python.org/moin/DbusExamples (just in case)
180 #### Because webpages come and go, the above information needs to be moved to inxi's wiki
181 ########################################################################
182 #### Valuable Resources
183 #### CPU flags: http://unix.stackexchange.com/questions/43539/what-do-the-flags-in-proc-cpuinfo-mean
184 #### Advanced Bash: http://wiki.bash-hackers.org/syntax/pe
185 #### gawk arrays: http://www.math.utah.edu/docs/info/gawk_12.html
186 #### raid mdstat: http://www-01.ibm.com/support/docview.wss?uid=isg3T1011259
187 #### http://www.howtoforge.com/replacing_hard_disks_in_a_raid1_array
188 #### https://raid.wiki.kernel.org/index.php/Mdstat
189 ########################################################################
191 #### inxi supports advanced testing triggers to do various things, using -! <arg>
192 #### -! 1 - triggers default B_TESTING_1='true' to trigger some test or other
193 #### -! 2 - triggers default B_TESTING_2='true' to trigger some test or other
194 #### -! 3 - triggers B_TESTING_1='true' and B_TESTING_2='true'
195 #### -! 10 - triggers an update from the primary dev download server instead of svn
196 #### -! 11 - triggers an update from svn branch one - if present, of course
197 #### -! 12 - triggers an update from svn branch two - if present, of course
198 #### -! 13 - triggers an update from svn branch three - if present, of course
199 #### -! 14 - triggers an update from svn branch four - if present, of course
200 #### -! <http://......> - Triggers an update from whatever server you list.
201 #### LOG FLAGS (logs to $HOME/.inxi/inxi.log with rotate 3 total)
202 #### -@ 8 - Basic data logging of generated data / array values
203 #### -@ 9 - Full logging of all data used, including cat of files and system data
204 #### -@ 10 - Basic data logging plus color code logging
205 ########################################################################
207 ########################################################################
209 ## NOTE: we can use hwinfo if it's available in all systems, or most, to get
210 ## a lot more data and verbosity levels going
212 ### DISTRO MAINTAINER FLAGS ###
213 # flag to allow distro maintainers to turn off update features. If false, turns off
214 # -U and -! testing/advanced update options, as well as removing the -U help menu item
215 # NOTE: Usually you want to create these in /etc/inxi.conf to avoid having to update each time
216 B_ALLOW_UPDATE='true'
217 B_ALLOW_WEATHER='true'
219 ### USER CONFIGS: SET IN inxi.conf file see wiki for directions ###
220 # http://code.google.com/p/inxi/wiki/script_configuration_files
221 # override in user config if desired, seems like less than .3 doesn't work as reliably
223 FILTER_STRING='<filter>'
225 # for features like help/version will fit to terminal / console screen width. Console
226 # widths will be dynamically set in main() based on cols in term/console
227 COLS_MAX_CONSOLE='115'
229 # note, this is console out of x/display server, will also be set dynamically
230 # not used currently, but maybe in future
231 COLS_MAX_NO_DISPLAY='140'
233 # change to less, or more if you have very slow connection
235 ### END USER CONFIGS ###
237 ### LOCALIZATION - DO NOT CHANGE! ###
238 # set to default LANG to avoid locales errors with , or .
240 # Make sure every program speaks English.
246 # Clear nullglob, because it creates unpredictable situations with IFS=$'\n' ARR=($VAR) IFS="$ORIGINAL_IFS"
247 # type constructs. Stuff like [rev a1] is now seen as a glob expansion pattern, and fails, and
248 # therefore results in nothing.
250 ## info on bash built in: $IFS - http://tldp.org/LDP/abs/html/internalvariables.html
251 # Backup the current Internal Field Separator
261 A_CPU_TYPE_PCNT_CCNT=''
265 A_GRAPHICS_CARD_DATA=''
273 A_OPTICAL_DRIVE_DATA=''
279 A_UNMOUNTED_PARTITION_DATA=''
281 A_DISPLAY_SERVER_DATA=''
284 ## standard boolean flags ##
285 B_BSD_DISK_SET='false'
287 B_COLOR_SCHEME_SET='false'
288 B_CONSOLE_IRC='false'
289 # triggers full display of cpu flags
290 B_CPU_FLAGS_FULL='false'
291 # test for dbus irc client
292 B_DBUS_CLIENT='false'
295 # Debug flood override: make 'true' to allow long debug output
296 B_DEBUG_FLOOD='false'
297 # for special -i debugging cases
299 B_DMIDECODE_SET='false'
300 # show extra output data
303 B_EXTRA_EXTRA_DATA='false'
304 B_FORCE_DMIDECODE='false'
306 # override certain errors due to currupted data
307 B_HANDLE_CORRUPT_DATA='false'
311 B_LOG_FULL_DATA='false'
313 B_OUTPUT_FILTER='false'
314 B_OVERRIDE_FILTER='false'
316 B_PCICONF_SET='false'
322 B_RUN_COLOR_SELECTOR='false'
323 B_RUNNING_IN_DISPLAY='false' # in x type display server
324 if tty >/dev/null;then
329 # this sets the debug buffer
331 B_SHOW_ADVANCED_NETWORK='false'
332 # Show sound card data
334 B_SHOW_BASIC_RAID='false'
335 B_SHOW_BASIC_CPU='false'
336 B_SHOW_BASIC_DISK='false'
337 B_SHOW_BASIC_OPTICAL='false'
338 B_SHOW_BATTERY='false'
339 B_SHOW_BATTERY_FORCED='false'
341 B_SHOW_DISPLAY_DATA='false'
342 B_SHOW_DISK_TOTAL='false'
344 # Show full hard disk output
345 B_SHOW_FULL_HDD='false'
346 B_SHOW_FULL_OPTICAL='false'
347 B_SHOW_GRAPHICS='false'
348 # Set this to 'false' to avoid printing the hostname, can be set false now
352 B_SHOW_LABELS='false'
353 B_SHOW_MACHINE='false'
354 B_SHOW_MEMORY='false'
355 B_SHOW_NETWORK='false'
356 # either -v > 3 or -P will show partitions
357 B_SHOW_PARTITIONS='false'
358 B_SHOW_PARTITIONS_FULL='false'
359 B_SHOW_PS_CPU_DATA='false'
360 B_SHOW_PS_MEM_DATA='false'
362 # because many systems have no mdstat file, -b/-F should not show error if no raid file found
363 B_SHOW_RAID_R='false'
365 B_SHOW_SENSORS='false'
366 # triggers only short inxi output
367 B_SHOW_SHORT_OUTPUT='false'
368 B_SHOW_SYSTEM='false'
369 B_SHOW_UNMOUNTED_PARTITIONS='false'
371 B_SHOW_WEATHER='false'
373 # triggers various debugging and new option testing
376 B_UPLOAD_DEBUG_DATA='false'
377 B_USB_NETWORKING='false'
378 # set to true here for debug logging from script start
379 B_USE_LOGGING='false'
383 ## Directory/file exist flags; test as [[ $(boolean) ]] not [[ $boolean ]]
384 B_ASOUND_DEVICE_FILE='false'
385 B_ASOUND_VERSION_FILE='false'
387 B_CPUINFO_FILE='false'
388 B_DMESG_BOOT_FILE='false' # bsd only
390 B_MDSTAT_FILE='false'
391 B_MEMINFO_FILE='false'
392 B_MODULES_FILE='false' #
393 B_MOUNTS_FILE='false'
394 B_OS_RELEASE_FILE='false' # new default distro id file? will this one work where lsb-release didn't?
395 B_PARTITIONS_FILE='false' #
399 ## app tested for and present, to avoid repeat tests
400 B_FILE_TESTED='false'
401 B_HDDTEMP_TESTED='false'
402 B_MODINFO_TESTED='false'
403 B_SUDO_TESTED='false'
405 ### CONSTANTS/INITIALIZE - SOME MAY BE RESET LATER ###
407 DEBUG=0 # Set debug levels from 1-10 (8-10 trigger logging levels)
408 # Debug Buffer Index, index into a debug buffer storing debug messages until inxi is 'all up'
410 ## note: the debugger rerouting to /dev/null has been moved to the end of the get_parameters function
411 ## so -@[number] debug levels can be set if there is a failure, otherwise you can't even see the errors
412 SED_I='-i' # for gnu sed, will be set to -i '' for bsd sed
413 SED_RX='-r' # for gnu sed, will be set to -E for bsd sed for backward compatibility
415 # default to false, no konversation found, 1 is native konvi (qt3/KDE3) script mode, 2 is /cmd inxi start,
416 ## 3 is Konversation > 1.2 (qt4/KDE4)
418 # NO_CPU_COUNT=0 # Wether or not the string "dual" or similar is found in cpuinfo output. If so, avoid dups.
419 # This is a variable that controls how many parameters inxi will parse in a /proc/<pid>/cmdline file before stopping.
421 SCHEME=0 # set default scheme - do not change this, it's set dynamically
422 # this is set in user prefs file, to override dynamic temp1/temp2 determination of sensors output in case
423 # cpu runs colder than mobo
425 # SHOW_IRC=1 to avoid showing the irc client version number, or SHOW_IRC=0 to disable client information completely.
427 # Verbosity level defaults to 0, this can also be set with -v0, -v2, -v3, etc as a parameter.
429 # Supported number of verbosity levels, including 0
433 ## logging eval variables, start and end function: Insert to LOGFS LOGFE when debug level >= 8
434 LOGFS_STRING='log_function_data fs $FUNCNAME "$( echo $@ )"'
435 LOGFE_STRING='log_function_data fe $FUNCNAME'
438 # uncomment for debugging from script start
439 # LOGFS=$LOGFS_STRING
440 # LOGFE=$LOGFE_STRING
442 ### FILE NAMES/PATHS/URLS - must be non root writable ###
443 # File's used when present
444 FILE_ASOUND_DEVICE='/proc/asound/cards'
445 FILE_ASOUND_MODULES='/proc/asound/modules' # not used but maybe for -A?
446 FILE_ASOUND_VERSION='/proc/asound/version'
447 FILE_CPUINFO='/proc/cpuinfo'
448 FILE_DMESG_BOOT='/var/run/dmesg.boot'
449 FILE_LSB_RELEASE='/etc/lsb-release'
450 FILE_MDSTAT='/proc/mdstat'
451 FILE_MEMINFO='/proc/meminfo'
452 FILE_MODULES='/proc/modules'
453 FILE_MOUNTS='/proc/mounts'
454 FILE_OS_RELEASE='/etc/os-release'
455 FILE_PARTITIONS='/proc/partitions'
456 FILE_SCSI='/proc/scsi/scsi'
457 FILE_XORG_LOG='/var/log/Xorg.0.log' # if not found, search and replace with actual location
464 SCRIPT_DATA_DIR="$HOME/.inxi"
465 ALTERNATE_FTP='' # for data uploads
466 ALTERNATE_WEATHER_LOCATION='' # weather alternate location
467 LOG_FILE="$SCRIPT_DATA_DIR/inxi.log"
468 LOG_FILE_1="$SCRIPT_DATA_DIR/inxi.1.log"
469 LOG_FILE_2="$SCRIPT_DATA_DIR/inxi.2.log"
470 MAN_FILE_DOWNLOAD='https://github.com/smxi/inxi/raw/master/inxi.1.gz'
471 MAN_FILE_LOCATION='/usr/share/man/man1'
473 SCRIPT_PATCH_NUMBER=''
474 SCRIPT_PATH='' #filled-in in Main
475 SCRIPT_VERSION_NUMBER="" #filled-in in Main
476 SCRIPT_DOWNLOAD='https://github.com/smxi/inxi/raw/master/'
477 SCRIPT_DOWNLOAD_BRANCH_1='https://github.com/smxi/inxi/raw/one/'
478 SCRIPT_DOWNLOAD_BRANCH_2='https://github.com/smxi/inxi/raw/two/'
479 SCRIPT_DOWNLOAD_BRANCH_3='https://github.com/smxi/inxi/raw/three/'
480 SCRIPT_DOWNLOAD_BRANCH_4='https://github.com/smxi/inxi/raw/four/'
481 SCRIPT_DOWNLOAD_BRANCH_BSD='https://github.com/smxi/inxi/raw/bsd/'
482 SCRIPT_DOWNLOAD_BRANCH_GNUBSD='https://github.com/smxi/inxi/raw/gnubsd/'
483 SCRIPT_DOWNLOAD_DEV='http://smxi.org/test/'
484 # note, you can use any ip url here as long as it's the only line on the output page.
485 # Also the ip address must be the last thing on that line. If you abuse this ip tool
486 # you will be banned from further access. Most > 24x daily automated queries to it are abuse.
487 WAN_IP_URL='http://smxi.org/opt/ip.php'
488 KONVI_CFG="konversation/scripts/$SCRIPT_NAME.conf" # relative path to $(kde-config --path data)
490 ### INITIALIZE VARIABLES NULL ###
503 IRC_CLIENT_VERSION=''
508 # These two determine separators in single line output, to force irc clients not to break off sections
511 # these will assign a separator to non irc states. Important! Using ':' can trigger stupid emoticon
512 # behaviors in output on IRC, so do not use those.
515 SEP3='' # do not set, will be set dynamically
516 LINE1='---------------------------------------------------------------------------'
517 LINE2='- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -'
519 # Default indentation level. NOTE: actual indent is 1 greater to allow for spacing
522 ### COLUMN WIDTHS ###
523 COLS_INNER='' ## for width minus INDENT
526 # these will be set dynamically in main()
530 # Only for legacy user config files se we can test and convert the var name
535 # Defaults to 2, make this 1 for normal, 0 for no colorcodes at all. Use following variables in config
536 # files to change defaults for each type, or global
537 # Same as runtime parameter.
538 DEFAULT_COLOR_SCHEME=2
539 ## color variables - set dynamically
544 ## Always leave these blank, these are only going to be set in inxi.conf files, that makes testing
545 ## for user changes easier after sourcing the files
547 GLOBAL_COLOR_SCHEME=''
549 IRC_CONS_COLOR_SCHEME=''
550 IRC_X_TERM_COLOR_SCHEME=''
551 CONSOLE_COLOR_SCHEME=''
552 VIRT_TERM_COLOR_SCHEME=''
555 # A more elegant way to have a scheme that doesn't print color codes (neither ANSI nor mIRC) at all. See below.
557 # DGREY BLACK RED DRED GREEN DGREEN YELLOW DYELLOW
558 ANSI_COLORS="
\e[1;30m
\e[0;30m
\e[1;31m
\e[0;31m
\e[1;32m
\e[0;32m
\e[1;33m
\e[0;33m"
559 IRC_COLORS=" \x0314 \x0301 \x0304 \x0305 \x0309 \x0303 \x0308 \x0307"
560 # BLUE DBLUE MAGENTA DMAGENTA CYAN DCYAN WHITE GREY NORMAL
561 ANSI_COLORS="$ANSI_COLORS
\e[1;34m
\e[0;34m
\e[1;35m
\e[0;35m
\e[1;36m
\e[0;36m
\e[1;37m
\e[0;37m
\e[0;37m"
562 IRC_COLORS=" $IRC_COLORS \x0312 \x0302 \x0313 \x0306 \x0311 \x0310 \x0300 \x0315 \x03"
564 #ANSI_COLORS=($ANSI_COLORS); IRC_COLORS=($IRC_COLORS)
565 A_COLORS_AVAILABLE=( DGREY BLACK RED DRED GREEN DGREEN YELLOW DYELLOW BLUE DBLUE MAGENTA DMAGENTA CYAN DCYAN WHITE GREY NORMAL )
567 # See above for notes on EMPTY
568 ## note: group 1: 0, 1 are null/normal
569 ## Following: group 2: generic, light/dark or dark/light; group 3: dark on light; group 4 light on dark;
570 # this is the count of the first two groups, starting at zero
582 DYELLOW,NORMAL,NORMAL
585 MAGENTA,NORMAL,NORMAL
590 DBLUE,DMAGENTA,NORMAL
593 DGREEN,DYELLOW,NORMAL
595 DMAGENTA,BLACK,NORMAL
605 MAGENTA,YELLOW,NORMAL
622 #echo ${#A_COLOR_SCHEMES[@]};exit
624 # WARNING: In the main part below (search for 'KONVI')
625 # there's a check for Konversation-specific config files.
626 # Any one of these can override the above if inxi is run
630 # In cases of derived distros where the version file of the base distro can also be found under /etc,
631 # the derived distro's version file should go first. (Such as with Sabayon / Gentoo)
632 DISTROS_DERIVED="antix-version aptosid-version kanotix-version knoppix-version mandrake-release pardus-release porteus-version sabayon-release siduction-version sidux-version slitaz-release solusos-release turbolinux-release zenwalk-version"
633 # debian_version excluded from DISTROS_PRIMARY so Debian can fall through to /etc/issue detection. Same goes for Ubuntu.
634 DISTROS_EXCLUDE_LIST="debian_version devuan_version ubuntu_version"
635 DISTROS_PRIMARY="arch-release gentoo-release redhat-release slackware-version SuSE-release"
636 DISTROS_LSB_GOOD="mandrake-release mandriva-release mandrakelinux-release"
637 # this is being used both by core distros and derived distros now, eg, solusos 1 uses it for solusos id, while
638 # debian, solusos base, uses it as well, so we have to know which it is.
639 DISTROS_OS_RELEASE_GOOD="arch-release SuSE-release "
640 ## Distros with known problems
641 # DSL (Bash 2.05b: grep -m doesn't work; arrays won't work) --> unusable output
642 # Puppy Linux 4.1.2 (Bash 3.0: arrays won't work) --> works partially
644 ## OUTPUT FILTERS/SEARCH ##
645 # Note that \<ltd\> bans only words, not parts of strings; in \<corp\> you can't use punctuation characters like . or ,
646 # we're saving about 10+% of the total script exec time by hand building the ban lists here, using hard quotes.
648 BAN_LIST_NORMAL='chipset|components|computing|computer|corporation|communications|electronics|electrical|electric|gmbh|group|incorporation|industrial|international|nee|revision|semiconductor|software|technologies|technology|ltd\.|\<ltd\>|inc\.|\<inc\>|intl\.|co\.|\<co\>|corp\.|\<corp\>|\(tm\)|\(r\)|®|\(rev ..\)'
649 BAN_LIST_CPU='@||cpu |cpu deca|dual core|dual-core|tri core|tri-core|quad core|quad-core|ennea|genuine|hepta|hexa|multi|octa|penta|processor|single|triple|[0-9\.]+ *[MmGg][Hh][Zz]'
650 # See github issue 75 for more details on value: *, triggers weird behaviors if present in value
651 # /sys/devices/virtual/dmi/id/product_name:['*']
652 # this is for bash arrays AND avoiding * in arrays: ( fred * greg ) expands to the contents of the directory
653 BAN_LIST_ARRAY=',|\*'
655 SENSORS_GPU_SEARCH='amdgpu|intel|radeon|nouveau'
657 ### USB networking search string data, because some brands can have other products than
658 ### wifi/nic cards, they need further identifiers, with wildcards.
659 ### putting the most common and likely first, then the less common, then some specifics
660 USB_NETWORK_SEARCH="Wi-Fi.*Adapter|Wireless.*Adapter|Ethernet.*Adapter|WLAN.*Adapter|Network.*Adapter|802\.11|Atheros|Atmel|D-Link.*Adapter|D-Link.*Wireless|Linksys|Netgea|Ralink|Realtek.*Network|Realtek.*Wireless|Realtek.*WLAN|Belkin.*Wireless|Belkin.*WLAN|Belkin.*Network"
661 USB_NETWORK_SEARCH="$USB_NETWORK_SEARCH|Actiontec.*Wireless|Actiontec.*Network|AirLink.*Wireless|Asus.*Network|Asus.*Wireless|Buffalo.*Wireless|Davicom|DWA-.*RangeBooster|DWA-.*Wireless|ENUWI-.*Wireless|LG.*Wi-Fi|Rosewill.*Wireless|RNX-.*Wireless|Samsung.*LinkStick|Samsung.*Wireless|Sony.*Wireless|TEW-.*Wireless|TP-Link.*Wireless|WG[0-9][0-9][0-9].*Wireless|WNA[0-9][0-9][0-9]|WNDA[0-9][0-9][0-9]|Zonet.*ZEW.*Wireless|54 Mbps"
662 # then a few known hard to ID ones added
663 # belkin=050d; d-link=07d1; netgear=0846; ralink=148f; realtek=0bda;
664 USB_NETWORK_SEARCH="$USB_NETWORK_SEARCH|050d:935b|0bda:8189|0bda:8197"
666 ########################################################################
667 #### MAIN: Where it all begins
668 ########################################################################
673 local color_scheme='' kde_config_app=''
674 # this will be used by all functions following
675 local Ps_aux_Data="$( ps aux )"
677 # This function just initializes variables
680 # Source global config overrides, needs to be here because some things
681 # can be reset that were set in initialize, but check_required_apps needs
682 if [[ -s /etc/$SCRIPT_NAME.conf ]];then
683 source /etc/$SCRIPT_NAME.conf
685 # Source user config variables override /etc/inxi.conf variables
686 if [[ -s $HOME/.$SCRIPT_NAME/$SCRIPT_NAME.conf ]];then
687 source $HOME/.$SCRIPT_NAME/$SCRIPT_NAME.conf
689 set_display_width 'live' # can be reset with -y
691 # echo SCHEME $SCHEME
694 # Check for dependencies BEFORE running ANYTHING else except above functions
695 # Not all distro's have these depends installed by default. Don't want to run
696 # this if the user is requesting to see this information in the first place
697 # Only continue if required apps tests ok
698 if [[ $1 != '--recommends' ]];then
700 check_recommended_apps
703 SCRIPT_VERSION_NUMBER=$( parse_version_data 'main' )
704 SCRIPT_PATCH_NUMBER=$( parse_version_data 'patch' )
706 # previous source location, check for bugs
708 ## this needs to run before the KONVI stuff is set below
709 ## Konversation 1.2 apparently does not like the $PPID test in get_start_client
710 ## So far there is no known way to detect if qt4_konvi is the parent process
711 ## this method will infer qt4_konvi as parent
714 # note: this only works if it's run from inside konversation as a script builtin or something
715 # only do this if inxi has been started as a konversation script, otherwise bypass this
716 # KONVI=3 ## for testing puroses
717 if [[ $KONVI -eq 1 || $KONVI -eq 3 ]];then
718 if [[ $KONVI -eq 1 ]]; then ## dcop Konversation (ie 1.x < 1.2(qt3))
723 elif [[ $KONVI -eq 3 ]]; then ## dbus Konversation (> 1.2 (qt4))
724 DCSERVER="$1" ##dbus testing
725 DCTARGET="$2" ##dbus testing
728 # always have the current stable kde version tested first,
729 # then use fallbacks and future proofing
730 if type -p kde4-config &>/dev/null;then
731 kde_config_app='kde4-config'
732 elif type -p kde5-config &>/dev/null;then
733 kde_config_app='kde5-config'
734 elif type -p kde-config &>/dev/null;then
735 kde_config_app='kde-config'
737 # The section below is on request of Argonel from the Konversation developer team:
738 # it sources config files like $HOME/.kde/share/apps/konversation/scripts/inxi.conf
739 if [[ -n $kde_config_app ]];then
741 for kde_config in $( $kde_config_app --path data )
743 if [[ -r $kde_config$KONVI_CFG ]];then
744 source "$kde_config$KONVI_CFG"
752 ## leave this for debugging dcop stuff if we get that working
753 # print_screen_output "DCPORT: $DCPORT"
754 # print_screen_output "DCSERVER: $DCSERVER"
755 # print_screen_output "DCTARGET: $DCTARGET"
757 # first init function must be set first for colors etc. Remember, no debugger
758 # stuff works on this function unless you set the debugging flag manually.
759 # Debugging flag -@ [number] will not work until get_parameters runs.
761 # "$@" passes every parameter separately quoted, "$*" passes all parameters as one quoted parameter.
762 # must be here to allow debugger and other flags to be set.
765 # If no colorscheme was set in the parameter handling routine, then set the default scheme
766 if [[ $B_COLOR_SCHEME_SET != 'true' ]];then
767 # This let's user pick their color scheme. For IRC, only shows the color schemes, no interactive
768 # The override value only will be placed in user config files. /etc/inxi.conf can also override
769 if [[ $B_RUN_COLOR_SELECTOR == 'true' ]];then
770 select_default_color_scheme
772 # set the default, then override as required
773 color_scheme=$DEFAULT_COLOR_SCHEME
774 if [[ -n $GLOBAL_COLOR_SCHEME ]];then
775 color_scheme=$GLOBAL_COLOR_SCHEME
777 if [[ $B_IRC == 'false' ]];then
778 if [[ -n $CONSOLE_COLOR_SCHEME && -z $DISPLAY ]];then
779 color_scheme=$CONSOLE_COLOR_SCHEME
780 elif [[ -n $VIRT_TERM_COLOR_SCHEME ]];then
781 color_scheme=$VIRT_TERM_COLOR_SCHEME
784 if [[ -n $IRC_X_TERM_COLOR_SCHEME && $B_CONSOLE_IRC == 'true' && -n $B_RUNNING_IN_DISPLAY ]];then
785 color_scheme=$IRC_X_TERM_COLOR_SCHEME
786 elif [[ -n $IRC_CONS_COLOR_SCHEME && -z $DISPLAY ]];then
787 color_scheme=$IRC_CONS_COLOR_SCHEME
788 elif [[ -n $IRC_COLOR_SCHEME ]];then
789 color_scheme=$IRC_COLOR_SCHEME
793 set_color_scheme $color_scheme
796 if [[ $B_IRC == 'false' ]];then
799 # too hard to read if no colors, so force that for users on irc
800 if [[ $SCHEME == 0 ]];then
807 # all the pre-start stuff is in place now
809 script_debugger "Debugger: $SCRIPT_NAME is up and running..."
811 # then create the output
815 # weechat's executor plugin forced me to do this, and rightfully so, because else the exit code
816 # from the last command is taken..
820 #### -------------------------------------------------------------------
821 #### basic tests: set script data, booleans, PATH, version numbers
822 #### -------------------------------------------------------------------
824 # Set PATH data so we can access all programs as user. Set BAN lists.
825 # initialize some boleans, these directories are used throughout the script
826 # some apps are used for extended functions any directory used, should be
827 # checked here first.
832 BSD_VERSION=$( uname -s 2>/dev/null | tr '[A-Z]' '[a-z]' )
833 # note: archbsd says they are a freebsd distro, so assuming it's the same as freebsd
834 if [[ -z ${BSD_VERSION/*bsd*/} || -z ${BSD_VERSION/*dragonfly*/} || -z ${BSD_VERSION/*darwin*/} ]];then
835 if [[ -z ${BSD_VERSION/*openbsd*/} ]];then
836 BSD_VERSION='openbsd'
837 elif [[ -z ${BSD_VERSION/*darwin*/} ]];then
840 # GNU/kfreebsd will by definition have GNU tools like sed/grep
841 if [[ -z ${BSD_VERSION/*kfreebsd*/} ]];then
842 BSD_TYPE='debian-bsd' # debian gnu bsd
844 BSD_TYPE='bsd' # all other bsds
847 ESC=$(echo | tr '\n' '\033')
850 # now set the script BOOLEANS for files required to run features
851 # note that freebsd has /proc but it's empty
852 if [[ -d "/proc/" && -z $BSD_TYPE ]];then
854 elif [[ -n $BSD_TYPE ]];then
862 if type -p dig &>/dev/null;then
867 if ! type -p wget &>/dev/null;then
868 # first check for bsd stuff
869 if type -p fetch &>/dev/null;then
871 elif type -p curl &>/dev/null;then
873 elif [[ $BSD_VERSION == 'openbsd' && -n $( type -p ftp ) ]];then
876 DOWNLOADER='no-downloader'
880 if [[ -n $BSD_TYPE ]];then
881 if [[ -e $FILE_DMESG_BOOT ]];then
882 B_DMESG_BOOT_FILE='true'
885 # found a case of battery existing but having nothing in it on desktop mobo
886 # not all laptops show the first. /proc/acpi/battery is deprecated.
887 if [[ -n $( ls /proc/acpi/battery 2>/dev/null ) || -n $( ls /sys/class/power_supply/ 2>/dev/null ) ]];then
891 if [[ -e $FILE_CPUINFO ]]; then
892 B_CPUINFO_FILE='true'
894 if [[ -e $FILE_MEMINFO ]];then
895 B_MEMINFO_FILE='true'
897 if [[ -e $FILE_ASOUND_DEVICE ]];then
898 B_ASOUND_DEVICE_FILE='true'
900 if [[ -e $FILE_ASOUND_VERSION ]];then
901 B_ASOUND_VERSION_FILE='true'
903 if [[ -f $FILE_LSB_RELEASE ]];then
906 if [[ -f $FILE_OS_RELEASE ]];then
907 B_OS_RELEASE_FILE='true'
909 if [[ -e $FILE_SCSI ]];then
912 if [[ -n $DISPLAY ]];then
913 B_SHOW_DISPLAY_DATA='true'
914 B_RUNNING_IN_DISPLAY='true'
916 if [[ -e $FILE_MDSTAT ]];then
919 if [[ -e $FILE_MODULES ]];then
920 B_MODULES_FILE='true'
922 if [[ -e $FILE_MOUNTS ]];then
925 if [[ -e $FILE_PARTITIONS ]];then
926 B_PARTITIONS_FILE='true'
928 # default to the normal location, then search for it
929 if [[ -e $FILE_XORG_LOG ]];then
932 # Detect location of the Xorg log file
933 if type -p xset &>/dev/null; then
934 FILE_XORG_LOG=$( xset q 2>/dev/null | grep -i 'Log file' | gawk '{print $3}')
935 if [[ -e $FILE_XORG_LOG ]];then
940 # gfx output will require this flag
941 if [[ $( whoami ) == 'root' ]];then
947 # args: $1 - default OR override default cols max integer count
950 local cols_max_override=$1
952 if [[ $cols_max_override == 'live' ]];then
953 ## sometimes tput will trigger an error (mageia) if irc client
954 if [[ $B_IRC == 'false' ]];then
955 if type -p tput &>/dev/null;then
956 TERM_COLUMNS=$(tput cols)
957 TERM_LINES=$(tput lines)
959 # double check, just in case it's missing functionality or whatever
960 if [[ -z $TERM_COLUMNS || -n ${TERM_COLUMNS//[0-9]/} ]];then
965 # Convert to new variable names if set in config files, legacy test
966 if [[ -n $LINE_MAX_CONSOLE ]];then
967 COLS_MAX_CONSOLE=$LINE_MAX_CONSOLE
969 if [[ -n $LINE_MAX_IRC ]];then
970 COLS_MAX_IRC=$LINE_MAX_IRC
972 # this lets you set different widths for in or out of display server
973 # if [[ $B_RUNNING_IN_DISPLAY == 'false' && -n $COLS_MAX_NO_DISPLAY ]];then
974 # COLS_MAX_CONSOLE=$COLS_MAX_NO_DISPLAY
976 # TERM_COLUMNS is set in top globals, using tput cols
977 # echo tc: $TERM_COLUMNS cmc: $COLS_MAX_CONSOLE
978 if [[ $TERM_COLUMNS -lt $COLS_MAX_CONSOLE ]];then
979 COLS_MAX_CONSOLE=$TERM_COLUMNS
981 # adjust, some terminals will wrap if output cols == term cols
982 COLS_MAX_CONSOLE=$(( $COLS_MAX_CONSOLE - 2 ))
983 # echo cmc: $COLS_MAX_CONSOLE
984 # comes after source for user set stuff
985 if [[ $B_IRC == 'false' ]];then
986 COLS_MAX=$COLS_MAX_CONSOLE
988 COLS_MAX=$COLS_MAX_IRC
991 COLS_MAX=$cols_max_override
993 COLS_INNER=$(( $COLS_MAX - $INDENT - 1 ))
994 # echo cm: $COLS_MAX ci: $COLS_INNER
997 # arg: $1 - version number: main/patch/date
1000 local version_data=''
1002 # note, using ####[[:space:]]+ to avoid having this function also trip the version datas
1005 version_data=$( gawk -F ': ' '
1006 /####[[:space:]]+Date:/ {
1008 }' "$SCRIPT_PATH/$SCRIPT_NAME" )
1011 version_data=$( gawk '
1012 /####[[:space:]]+Version:/ {
1014 }' "$SCRIPT_PATH/$SCRIPT_NAME" )
1017 version_data=$( gawk '
1018 /####[[:space:]]+Patch Number:/ {
1020 }' "$SCRIPT_PATH/$SCRIPT_NAME" )
1028 local path='' added_path='' b_path_found='' sys_path=''
1029 # Extra path variable to make execute failures less likely, merged below
1030 local extra_paths="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/opt/local/bin"
1032 # this needs to be set here because various options call the parent initialize function directly.
1033 SCRIPT_PATH=$( dirname "$0" )
1035 # Fallback paths put into $extra_paths; This might, among others, help on gentoo.
1036 # Now, create a difference of $PATH and $extra_paths and add that to $PATH:
1038 for path in $extra_paths
1040 b_path_found='false'
1041 for sys_path in $PATH
1043 if [[ $path == $sys_path ]];then
1047 if [[ $b_path_found == 'false' ]];then
1048 added_path="$added_path:$path"
1053 PATH="$PATH$added_path"
1054 # echo "PATH='$PATH'"
1055 ##/bin/sh -c 'echo "PATH in subshell=\"$PATH\""'
1058 check_recommended_apps()
1061 local bash_array_test=( "one" "two" )
1063 # check for array ability of bash, this is only good for the warning at this time
1064 # the boolean could be used later
1065 # bash version 2.05b is used in DSL
1066 # bash version 3.0 is used in Puppy Linux; it has a known array bug <reference to be placed here>
1067 # versions older than 3.1 don't handle arrays
1068 # distro's using below 2.05b are unknown, released in 2002
1069 if [[ ${bash_array_test[1]} -eq "two" ]];then
1072 script_debugger "Suggestion: update to Bash v3.1 for optimal inxi output"
1074 # test for a few apps that bsds may not have after initial tests
1075 if type -p lspci &>/dev/null;then
1078 if [[ -n $BSD_TYPE ]];then
1079 if type -p sysctl &>/dev/null;then
1082 if type -p pciconf &>/dev/null;then
1086 # now setting qdbus/dcop for first run, some systems can have both by the way
1087 if type -p qdbus &>/dev/null;then
1090 if type -p dcop &>/dev/null;then
1096 # Determine if any of the absolutely necessary tools are absent
1098 check_required_apps()
1102 # bc removed from deps for now
1103 local depends="df gawk grep ps readlink tr uname wc"
1105 if [[ -z $BSD_TYPE ]];then
1106 depends="$depends lspci"
1107 elif [[ $BSD_TYPE == 'bsd' ]];then
1108 depends="$depends sysctl"
1109 # debian-bsd has lspci but you must be root to run it
1110 elif [[ $BSD_TYPE == 'debian-bsd' ]];then
1111 depends="$depends sysctl lspci"
1113 # no need to add xprop because it will just give N/A if not there, but if we expand use of xprop,
1114 # should add that here as a test, then use the B_SHOW_DISPLAY_DATA flag to trigger the tests in de function
1115 local x_apps="xrandr xdpyinfo glxinfo"
1117 if [[ $B_RUNNING_IN_DISPLAY == 'true' ]];then
1118 for app_name in $x_apps
1120 if ! type -p $app_name &>/dev/null;then
1121 script_debugger "Resuming in non X mode: $app_name not found. For package install advice run: $SCRIPT_NAME --recommends"
1122 B_SHOW_DISPLAY_DATA='false'
1130 for app_name in $depends
1132 if ! type -p $app_name &>/dev/null;then
1133 error_handler 5 "$app_name"
1139 ## note: this is now running inside each gawk sequence directly to avoid exiting gawk
1140 ## looping in bash through arrays, then re-entering gawk to clean up, then writing back to array
1141 ## in bash. For now I'll leave this here because there's still some interesting stuff to get re methods
1142 # Enforce boilerplate and buzzword filters
1143 # args: $1 - BAN_LIST_NORMAL/BAN_LIST_CPU; $2 - string to sanitize
1144 sanitize_characters()
1147 # Cannot use strong quotes to unquote a string with pipes in it!
1148 # bash will interpret the |'s as usual and try to run a subshell!
1149 # Using weak quotes instead, or use '"..."'
1156 gsub(/ [ ]+/,\" \") ## ([ ]+) with (space)
1157 gsub(/^ +| +$/,\"\") ## (pipe char) with (nothing)
1158 print ## prints (returns) cleaned input
1163 # Set the colorscheme
1164 # args: $1 = <scheme number>|<"none">
1168 local i='' a_output_colors='' a_color_codes=''
1170 if [[ $1 -ge ${#A_COLOR_SCHEMES[@]} ]];then
1173 # Set a global variable to allow checking for chosen scheme later
1175 if [[ $B_IRC == 'false' ]];then
1176 a_color_codes=( $ANSI_COLORS )
1178 a_color_codes=( $IRC_COLORS )
1180 for (( i=0; i < ${#A_COLORS_AVAILABLE[@]}; i++ ))
1182 eval "${A_COLORS_AVAILABLE[i]}=\"${a_color_codes[i]}\""
1185 a_output_colors=( ${A_COLOR_SCHEMES[$1]} )
1187 # then assign the colors globally
1188 C1="${!a_output_colors[0]}"
1189 C2="${!a_output_colors[1]}"
1190 CN="${!a_output_colors[2]}"
1191 # ((COLOR_SCHEME++)) ## note: why is this? ##
1192 # handle some explicit colors that are used for no color 0
1193 if [[ $SCHEME -eq 0 ]];then
1200 select_default_color_scheme()
1203 local spacer=' ' options='' user_selection='' config_variable=''
1204 local config_file="$HOME/.$SCRIPT_NAME/$SCRIPT_NAME.conf"
1205 local irc_clear="
\e[0m"
1206 local irc_gui='Unset' irc_console='Unset' irc_x_term='Unset'
1207 local console='Unset' virt_term='Unset' global='Unset'
1209 if [[ -n $IRC_COLOR_SCHEME ]];then
1210 irc_gui="Set: $IRC_COLOR_SCHEME"
1212 if [[ -n $IRC_CONS_COLOR_SCHEME ]];then
1213 irc_console="Set: $IRC_CONS_COLOR_SCHEME"
1215 if [[ -n $IRC_X_TERM_COLOR_SCHEME ]];then
1216 irc_x_term="Set: $IRC_X_TERM_COLOR_SCHEME"
1218 if [[ -n $VIRT_TERM_COLOR_SCHEME ]];then
1219 virt_term="Set: $VIRT_TERM_COLOR_SCHEME"
1221 if [[ -n $CONSOLE_COLOR_SCHEME ]];then
1222 console="Set: $CONSOLE_COLOR_SCHEME"
1224 if [[ -n $GLOBAL_COLOR_SCHEME ]];then
1225 global="Set: $GLOBAL_COLOR_SCHEME"
1228 # don't want these printing in irc since they show literally
1229 if [[ $B_IRC == 'true' ]];then
1232 # first make output neutral so it's just plain default for console client
1233 set_color_scheme "0"
1234 # print_lines_basic "0" "" ""
1235 if [[ $B_IRC == 'false' ]];then
1236 print_lines_basic "0" "" "Welcome to $SCRIPT_NAME! Please select the default $COLOR_SELECTION color scheme."
1237 # print_screen_output "You will see this message only one time per user account, unless you set preferences in: /etc/$SCRIPT_NAME.conf"
1238 print_screen_output " "
1240 print_lines_basic "0" "" "Because there is no way to know your $COLOR_SELECTION foreground/background colors, you can set your color preferences from color scheme option list below. 0 is no colors, 1 neutral. After these, there are 4 sets: 1-dark or light backgrounds; 2-light backgrounds; 3-dark backgrounds; 4-miscellaneous."
1241 if [[ $B_IRC == 'false' ]];then
1242 print_lines_basic "0" "" "Please note that this will set the $COLOR_SELECTION preferences only for user: $(whoami)"
1244 print_screen_output "$LINE1"
1245 for (( i=0; i < ${#A_COLOR_SCHEMES[@]}; i++ ))
1247 if [[ $i -gt 9 ]];then
1250 # only offer the safe universal defaults
1251 case $COLOR_SELECTION in
1252 global|irc|irc-console|irc-virtual-terminal)
1253 if [[ $i -gt $SAFE_COLOR_COUNT ]];then
1259 print_screen_output "$irc_clear $i)$spacer${C1}Card:${C2} nVidia G86 [GeForce 8400 GS] ${C1}X.Org${C2} 1.7.7"
1263 if [[ $B_IRC == 'false' ]];then
1266 print_screen_output "$irc_clear $i)${spacer}Remove all color settings. Restore $SCRIPT_NAME default."
1267 print_screen_output "$irc_clear $(($i+1)))${spacer}Continue, no changes or config file setting."
1268 print_screen_output "$irc_clear $(($i+2)))${spacer}Exit, use another terminal, or set manually."
1269 print_screen_output "$LINE1"
1270 print_lines_basic "0" "" "Simply type the number for the color scheme that looks best to your eyes for your $COLOR_SELECTION settings and hit ENTER. NOTE: You can bring this option list up by starting $SCRIPT_NAME with option: -c plus one of these numbers:"
1271 print_lines_basic "0" "" "94^(console,^no X^-^$console); 95^(terminal,^X^-^$virt_term); 96^(irc,^gui,^X^-^$irc_gui); 97^(irc,^X,^in^terminal^-^$irc_x_term); 98^(irc,^no^X^-^$irc_console); 99^(global^-^$global)"
1272 print_lines_basic "0" "" ""
1273 print_screen_output "Your selection(s) will be stored here: $config_file"
1274 print_lines_basic "0" "" "Global overrides all individual color schemes. Individual schemes remove the global setting."
1275 print_screen_output "$LINE1"
1277 if [[ "$user_selection" =~ ^([0-9]+)$ && $user_selection -lt $i ]];then
1278 case $COLOR_SELECTION in
1280 config_variable='IRC_COLOR_SCHEME'
1283 config_variable='IRC_CONS_COLOR_SCHEME'
1285 irc-virtual-terminal)
1286 config_variable='IRC_X_TERM_COLOR_SCHEME'
1289 config_variable='CONSOLE_COLOR_SCHEME'
1292 config_variable='VIRT_TERM_COLOR_SCHEME'
1295 config_variable='GLOBAL_COLOR_SCHEME'
1298 set_color_scheme $user_selection
1299 # make file/directory first if missing
1300 if [[ ! -f $config_file ]];then
1301 if [[ ! -d $HOME/.$SCRIPT_NAME ]];then
1302 mkdir $HOME/.$SCRIPT_NAME
1306 if [[ -z $( grep -s "$config_variable=" $config_file ) ]];then
1307 print_lines_basic "0" "" "Creating and updating config file for $COLOR_SELECTION color scheme now..."
1308 echo "$config_variable=$user_selection" >> $config_file
1310 print_screen_output "Updating config file for $COLOR_SELECTION color scheme now..."
1311 sed $SED_I "s/$config_variable=.*/$config_variable=$user_selection/" $config_file
1313 # file exists now so we can go on to cleanup
1314 case $COLOR_SELECTION in
1315 irc|irc-console|irc-virtual-terminal|console|virtual-terminal)
1316 sed $SED_I '/GLOBAL_COLOR_SCHEME=/d' $config_file
1319 sed $SED_I -e '/VIRT_TERM_COLOR_SCHEME=/d' -e '/CONSOLE_COLOR_SCHEME=/d' -e '/IRC_COLOR_SCHEME=/d' \
1320 -e '/IRC_CONS_COLOR_SCHEME=/d' -e '/IRC_X_TERM_COLOR_SCHEME=/d' $config_file
1323 elif [[ $user_selection == $i ]];then
1324 print_screen_output "Removing all color settings from config file now..."
1325 sed $SED_I -e '/VIRT_TERM_COLOR_SCHEME=/d' -e '/GLOBAL_COLOR_SCHEME=/d' -e '/CONSOLE_COLOR_SCHEME=/d' \
1326 -e '/IRC_COLOR_SCHEME=/d' -e '/IRC_CONS_COLOR_SCHEME=/d' -e '/IRC_X_TERM_COLOR_SCHEME=/d' $config_file
1327 set_color_scheme $DEFAULT_COLOR_SCHEME
1328 elif [[ $user_selection == $(( $i+1 )) ]];then
1329 print_lines_basic "0" "" "Ok, continuing $SCRIPT_NAME unchanged. You can set the colors anytime by starting with: -c 95 to 99"
1330 if [[ -n $CONSOLE_COLOR_SCHEME && -z $DISPLAY ]];then
1331 set_color_scheme $CONSOLE_COLOR_SCHEME
1332 elif [[ -n $VIRT_TERM_COLOR_SCHEME ]];then
1333 set_color_scheme $VIRT_TERM_COLOR_SCHEME
1335 set_color_scheme $DEFAULT_COLOR_SCHEME
1337 elif [[ $user_selection == $(( $i+2 )) ]];then
1338 set_color_scheme $DEFAULT_COLOR_SCHEME
1339 print_screen_output "Ok, exiting $SCRIPT_NAME now. You can set the colors later."
1342 print_screen_output "Error - Invalid Selection. You entered this: $user_selection"
1343 print_screen_output " "
1344 select_default_color_scheme
1347 print_screen_output "$LINE1"
1348 print_lines_basic "0" "" "After finding the scheme number you like, simply run this again in a terminal to set the configuration data file for your irc client. You can set color schemes for the following: start inxi with -c plus:"
1349 print_screen_output "94 (console, no X - $console); 95 (terminal, X - $virt_term); 96 (irc, gui, X - $irc_gui);"
1350 print_screen_output "97 (irc, X, in terminal - $irc_x_term); 98 (irc, no X - $irc_console); 99 (global - $global)"
1357 ########################################################################
1358 #### UTILITY FUNCTIONS
1359 ########################################################################
1361 #### -------------------------------------------------------------------
1362 #### error handler, debugger, script updater
1363 #### -------------------------------------------------------------------
1366 # args: $1 - error number; $2 - optional, extra information; $3 - optional extra info
1370 local error_message=''
1372 # assemble the error message
1374 2) error_message="large flood danger, debug buffer full!"
1376 3) error_message="unsupported color scheme number: $2"
1378 4) error_message="unsupported verbosity level: $2"
1380 5) error_message="dependency not met: $2 not found in path.\nFor distribution installation package names and missing apps information, run: $SCRIPT_NAME --recommends"
1382 6) error_message="/proc not found! Quitting..."
1384 7) error_message="One of the options you entered in your script parameters: $2\nis not supported.The option may require extra arguments to work.\nFor supported options (and their arguments), check the help menu: $SCRIPT_NAME -h"
1386 8) error_message="the self-updater failed, $DOWNLOADER exited with error: $2.\nYou probably need to be root.\nHint, to make for easy updates without being root, do: chown <user name> $SCRIPT_PATH/$SCRIPT_NAME"
1388 9) error_message="unsupported debugging level: $2"
1391 error_message="the alt download url you provided: $2\nappears to be wrong, download aborted. Please note, the url\nneeds to end in /, without $SCRIPT_NAME, like: http://yoursite.com/downloads/"
1394 error_message="unsupported testing option argument: -! $2"
1397 error_message="the git branch download url: $2\nappears to be empty currently. Make sure there is an actual svn branch version\nactive before you try this again. Check https://github.com/smxi/inxi\nto verify the branch status."
1400 error_message="The -t option requires the following extra arguments (no spaces between letters/numbers):\nc m cm [required], for example: -t cm8 OR -t cm OR -t c9\n(numbers: 1-20, > 5 throttled to 5 in irc clients) You entered: $2"
1403 error_message="failed to write correctly downloaded $SCRIPT_NAME to location $SCRIPT_PATH.\nThis usually means you don't have permission to write to that location, maybe you need to be root?\nThe operation failed with error: $2"
1406 error_message="failed set execute permissions on $SCRIPT_NAME at location $SCRIPT_PATH.\nThis usually means you don't have permission to set permissions on files there, maybe you need to be root?\nThe operation failed with error: $2"
1409 error_message="$SCRIPT_NAME downloaded but the file data is corrupted. Purged data and using current version."
1412 error_message="All $SCRIPT_NAME self updater features have been disabled by the distribution\npackage maintainer. This includes the option you used: $2"
1415 error_message="The argument you provided for $2 does not have supported syntax.\nPlease use the following formatting:\n$3"
1418 error_message="The option $2 has been deprecated. Please use $3 instead.\nSee -h for instructions and syntax."
1421 error_message="The option you selected has been deprecated. $2\nSee the -h (help) menu for currently supported options."
1424 error_message="Width option requires an integer value of 80 or more.\nYou entered: $2"
1426 *) error_message="error unknown: $@"
1430 # then print it and exit
1431 print_screen_output "Error $1: $error_message"
1436 # prior to script up set, pack the data into an array
1437 # then we'll print it out later.
1438 # args: $1 - $@ debugging string text
1442 if [[ $B_SCRIPT_UP == 'true' ]];then
1443 # only return if debugger is off and no pre start up errors have occured
1444 if [[ $DEBUG -eq 0 && $DEBUG_BUFFER_INDEX -eq 0 ]];then
1446 # print out the stored debugging information if errors occured
1447 elif [[ $DEBUG_BUFFER_INDEX -gt 0 ]];then
1448 for (( DEBUG_BUFFER_INDEX=0; DEBUG_BUFFER_INDEX < ${#A_DEBUG_BUFFER[@]}; DEBUG_BUFFER_INDEX++ ))
1450 print_screen_output "${A_DEBUG_BUFFER[$DEBUG_BUFFER_INDEX]}"
1452 DEBUG_BUFFER_INDEX=0
1454 # or print out normal debugger messages if debugger is on
1455 if [[ $DEBUG -gt 0 ]];then
1456 print_screen_output "$1"
1459 if [[ $B_DEBUG_FLOOD == 'true' && $DEBUG_BUFFER_INDEX -gt 10 ]];then
1461 # this case stores the data for later printout, will print out only
1462 # at B_SCRIPT_UP == 'true' if array index > 0
1464 A_DEBUG_BUFFER[$DEBUG_BUFFER_INDEX]="$1"
1465 # increment count for next pre script up debugging error
1466 (( DEBUG_BUFFER_INDEX++ ))
1472 # NOTE: no logging available until get_parameters is run, since that's what sets logging
1473 # in order to trigger earlier logging manually set B_USE_LOGGING to true in top variables.
1474 # $1 alone: logs data; $2 with or without $3 logs func start/end.
1475 # $1 type (fs/fe/cat/raw) or logged data; [$2 is $FUNCNAME; [$3 - function args]]
1478 if [ "$B_USE_LOGGING" == 'true' ];then
1479 local logged_data='' spacer=' ' line='----------------------------------------'
1482 logged_data="Function: $2 - Primary: Start"
1484 logged_data="$logged_data\n${spacer}Args: $3"
1489 logged_data="Function: $2 - Primary: End"
1493 if [[ $B_LOG_FULL_DATA == 'true' ]];then
1496 logged_data="$logged_data\n$line\nFull file data: cat $cat_file\n\n$( cat $cat_file )\n$line\n"
1502 if [[ $B_LOG_FULL_DATA == 'true' ]];then
1503 logged_data="\n$line\nRaw system data:\n\n$2\n$line\n"
1511 # Create any required line breaks and strip out escape color code, either ansi (case 1)or irc (case 2).
1512 # This pattern doesn't work for irc colors, if we need that someone can figure it out
1513 if [[ -n $logged_data ]];then
1514 if [[ $B_LOG_COLORS != 'true' ]];then
1515 echo -e "${spacer}$logged_data" | sed $SED_RX 's/\x1b\[[0-9]{1,2}(;[0-9]{1,2}){0,2}m//g' >> $LOG_FILE
1517 echo -e "${spacer}$logged_data" >> $LOG_FILE
1523 # called in the initial -@ 10 script args setting so we can get logging as soon as possible
1524 # will have max 3 files, inxi.log, inxi.1.log, inxi.2.log
1525 create_rotate_logfiles()
1527 if [[ ! -d $SCRIPT_DATA_DIR ]];then
1528 mkdir $SCRIPT_DATA_DIR
1530 # do the rotation if logfile exists
1531 if [[ -f $LOG_FILE ]];then
1532 # copy if present second to third
1533 if [[ -f $LOG_FILE_1 ]];then
1534 mv -f $LOG_FILE_1 $LOG_FILE_2
1536 # then copy initial to second
1537 mv -f $LOG_FILE $LOG_FILE_1
1539 # now create the logfile
1541 # and echo the start data
1542 echo "=========================================================" >> $LOG_FILE
1543 echo "START $SCRIPT_NAME LOGGING:" >> $LOG_FILE
1544 echo "Script started: $( date +%Y-%m-%d-%H:%M:%S )" >> $LOG_FILE
1545 echo "=========================================================" >> $LOG_FILE
1548 # args: $1 - download url, not including file name; $2 - string to print out
1549 # $3 - update type option
1550 # note that $1 must end in / to properly construct the url path
1551 script_self_updater()
1554 local downloader_error=0 file_contents='' downloader_man_error=0
1555 local man_file_path="$MAN_FILE_LOCATION/inxi.1.gz"
1557 if [[ $B_IRC == 'true' ]];then
1558 print_screen_output "Sorry, you can't run the $SCRIPT_NAME self updater option (-$3) in an IRC client."
1562 print_screen_output "Starting $SCRIPT_NAME self updater."
1563 print_screen_output "Currently running $SCRIPT_NAME version number: $SCRIPT_VERSION_NUMBER"
1564 print_screen_output "Current version patch number: $SCRIPT_PATCH_NUMBER"
1565 print_screen_output "Updating $SCRIPT_NAME in $SCRIPT_PATH using $2 as download source..."
1568 file_contents="$( curl -s $1$SCRIPT_NAME )" || downloader_error=$?
1571 file_contents="$( fetch -q -o - $1$SCRIPT_NAME )" || downloader_error=$?
1574 file_contents="$( ftp -o - $1$SCRIPT_NAME 2>/dev/null )" || downloader_error=$?
1577 file_contents="$( wget -q -O - $1$SCRIPT_NAME )" || downloader_error=$?
1584 # then do the actual download
1585 if [[ $downloader_error -eq 0 ]];then
1586 # make sure the whole file got downloaded and is in the variable
1587 if [[ -n $( grep '###\*\*EOF\*\*###' <<< "$file_contents" ) ]];then
1588 echo "$file_contents" > $SCRIPT_PATH/$SCRIPT_NAME || error_handler 14 "$?"
1589 chmod +x $SCRIPT_PATH/$SCRIPT_NAME || error_handler 15 "$?"
1590 SCRIPT_VERSION_NUMBER=$( parse_version_data 'main' )
1591 SCRIPT_PATCH_NUMBER=$( parse_version_data 'patch' )
1592 print_screen_output "Successfully updated to $2 version: $SCRIPT_VERSION_NUMBER"
1593 print_screen_output "New $2 version patch number: $SCRIPT_PATCH_NUMBER"
1594 print_screen_output "To run the new version, just start $SCRIPT_NAME again."
1595 print_screen_output "----------------------------------------"
1596 print_screen_output "Starting download of man page file now."
1597 if [[ ! -d $MAN_FILE_LOCATION ]];then
1598 print_screen_output "The required man directory was not detected on your system, unable to continue: $MAN_FILE_LOCATION"
1600 if [[ $B_ROOT == 'true' ]];then
1601 print_screen_output "Checking Man page download URL..."
1602 if [[ -f /usr/share/man/man8/inxi.8.gz ]];then
1603 print_screen_output "Updating man page location to man1."
1604 mv -f /usr/share/man/man8/inxi.8.gz /usr/share/man/man1/inxi.1.gz
1605 if type -p mandb &>/dev/null;then
1606 exec $( type -p mandb ) -q
1609 if [[ $DOWNLOADER == 'wget' ]];then
1610 wget -q --spider $MAN_FILE_DOWNLOAD || downloader_man_error=$?
1612 if [[ $downloader_man_error -eq 0 ]];then
1613 if [[ $DOWNLOADER == 'wget' ]];then
1614 print_screen_output "Man file download URL verified: $MAN_FILE_DOWNLOAD"
1616 print_screen_output "Downloading Man page file now."
1619 curl -s -o $man_file_path $MAN_FILE_DOWNLOAD || downloader_man_error=$?
1622 fetch -q -o $man_file_path $MAN_FILE_DOWNLOAD || downloader_man_error=$?
1625 ftp -o $man_file_path $MAN_FILE_DOWNLOAD 2>/dev/null || downloader_man_error=$?
1628 wget -q -O $man_file_path $MAN_FILE_DOWNLOAD || downloader_man_error=$?
1631 downloader_man_error=1
1634 if [[ $downloader_man_error -gt 0 ]];then
1635 print_screen_output "Oh no! Something went wrong downloading the Man gz file at: $MAN_FILE_DOWNLOAD"
1636 print_screen_output "Check the error messages for what happened. Error: $downloader_man_error"
1638 print_screen_output "Download/install of man page successful. Check to make sure it works: man inxi"
1641 print_screen_output "Man file download URL failed, unable to continue: $MAN_FILE_DOWNLOAD"
1644 print_screen_output "Updating / Installing the Man page requires root user, writing to: $MAN_FILE_LOCATION"
1645 print_screen_output "If you want the man page, you'll have to run $SCRIPT_NAME -$3 as root."
1652 # now run the error handlers on any wget failure
1654 if [[ $2 == 'svn server' ]];then
1655 error_handler 8 "$downloader_error"
1656 elif [[ $2 == 'alt server' ]];then
1657 error_handler 10 "$1"
1659 error_handler 12 "$1"
1665 # args: $1 - debug data type: sys|xorg|disk
1666 debug_data_collector()
1668 local xiin_app='' xiin_data_file='' xiin_download='' error='' b_run_xiin='false'
1669 local debug_data_dir='' bsd_string='' xorg_d_files='' xorg_file='' a_distro_ids=''
1670 local completed_gz_file='' xiin_file='xiin.py' ftp_upload='ftp.techpatterns.com/incoming'
1671 local xiin_url="https://github.com/smxi/inxi/raw/xiin/$xiin_file"
1672 local Line='-------------------------' root_string=''
1673 local start_directory=$( pwd )
1674 local host=$( tr '[A-Z]' '[a-z]' <<< "$HOSTNAME" )
1675 local downloader_error=0 debug_i=''
1677 if [[ $B_DEBUG_I == 'true' ]];then
1681 if [[ -n $host ]];then
1686 if [[ -n $BSD_TYPE ]];then
1687 bsd_string="-$BSD_TYPE-$BSD_VERSION"
1689 if [[ $( whoami ) == 'root' ]];then
1693 debug_data_dir="inxi$bsd_string-$host-$(date +%Y%m%d-%H%M%S)-$1$root_string"
1695 if [[ $B_IRC == 'false' ]];then
1696 if [[ -n $ALTERNATE_FTP ]];then
1697 ftp_upload=$ALTERNATE_FTP
1699 echo "Starting debugging data collection type: $1"
1700 echo -n "Checking/creating required directories... "
1701 if [[ ! -d $SCRIPT_DATA_DIR ]];then
1702 mkdir $SCRIPT_DATA_DIR
1706 if [[ -d $SCRIPT_DATA_DIR/$debug_data_dir ]];then
1707 echo 'Deleting previous xiin data directory...'
1708 rm -rf $SCRIPT_DATA_DIR/$debug_data_dir
1710 mkdir $SCRIPT_DATA_DIR/$debug_data_dir
1711 if [[ -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz ]];then
1712 echo 'Deleting previous tar.gz file...'
1713 rm -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz
1716 echo 'Collecting system info: sensors, lsusb, lspci, lspci -v data, plus /proc data'
1717 echo 'also checking for dmidecode data: note, you must be root to have dmidecode work.'
1718 echo "Data going into: $SCRIPT_DATA_DIR/$debug_data_dir"
1719 # bsd tools http://cb.vu/unixtoolbox.xhtml
1721 if type -p pciconf &>/dev/null;then
1722 pciconf -l -cv &> $debug_data_dir/bsd-pciconf-cvl.txt
1723 pciconf -vl &> $debug_data_dir/bsd-pciconf-vl.txt
1724 pciconf -l &> $debug_data_dir/bsd-pciconf-l.txt
1726 touch $debug_data_dir/bsd-pciconf-absent
1729 if type -p pcidump &>/dev/null;then
1730 pcidump &> $debug_data_dir/bsd-pcidump-openbsd.txt
1731 pcidump -v &> $debug_data_dir/bsd-pcidump-v-openbsd.txt
1733 touch $debug_data_dir/bsd-pcidump-openbsd-absent
1736 if type -p pcictl &>/dev/null;then
1737 pcictl list &> $debug_data_dir/bsd-pcictl-list-netbsd.txt
1738 pcictl list -n &> $debug_data_dir/bsd-pcictl-list-n-netbsd.txt
1740 touch $debug_data_dir/bsd-pcictl-netbsd-absent
1742 if type -p sysctl &>/dev/null;then
1743 sysctl -a &> $debug_data_dir/bsd-sysctl-a.txt
1745 touch $debug_data_dir/bsd-sysctl-absent
1747 if type -p usbdevs &>/dev/null;then
1748 usbdevs -v &> $debug_data_dir/bsd-usbdevs-v.txt
1750 touch $debug_data_dir/bsd-usbdevs-absent
1752 if type -p kldstat &>/dev/null;then
1753 kldstat &> $debug_data_dir/bsd-kldstat.txt
1755 touch $debug_data_dir/bsd-kldstat-absent
1757 # diskinfo -v <disk>
1759 dmidecode &> $debug_data_dir/dmidecode.txt
1761 get_repo_data "$SCRIPT_DATA_DIR/$debug_data_dir"
1763 if type -p shopt &>/dev/null;then
1765 a_distro_ids=(/etc/*[-_]{release,version})
1767 echo ${a_distro_ids[@]} &> $debug_data_dir/etc-distro-files.txt
1768 for distro_file in ${a_distro_ids[@]} /etc/issue
1770 if [[ -f $distro_file ]];then
1771 cat $distro_file &> $debug_data_dir/distro-file${distro_file//\//-}
1775 dmesg &> $debug_data_dir/dmesg.txt
1776 lscpu &> $debug_data_dir/lscpu.txt
1777 lspci &> $debug_data_dir/lspci.txt
1778 lspci -k &> $debug_data_dir/lspci-k.txt
1779 lspci -knn &> $debug_data_dir/lspci-knn.txt
1780 lspci -n &> $debug_data_dir/lspci-n.txt
1781 lspci -nn &> $debug_data_dir/lspci-nn.txt
1782 lspci -mm &> $debug_data_dir/lspci-mm.txt
1783 lspci -mmnn &> $debug_data_dir/lspci-mmnn.txt
1784 lspci -mmnnv &> $debug_data_dir/lspci-mmnnv.txt
1785 lspci -v &> $debug_data_dir/lspci-v.txt
1786 lsusb &> $debug_data_dir/lsusb.txt
1787 if type -p hciconfig &>/dev/null;then
1788 hciconfig -a &> $debug_data_dir/hciconfig-a.txt
1790 touch $debug_data_dir/hciconfig-absent
1792 ls /sys &> $debug_data_dir/ls-sys.txt
1793 ps aux &> $debug_data_dir/ps-aux.txt
1794 ps -e &> $debug_data_dir/ps-e.txt
1795 ps -p 1 &> $debug_data_dir/ps-p-1.txt
1796 cat /proc/1/comm &> $debug_data_dir/proc-1-comm.txt
1797 runlevel &> $debug_data_dir/runlevel.txt
1798 if type -p rc-status &>/dev/null;then
1799 rc-status -a &> $debug_data_dir/rc-status-a.txt
1800 rc-status -l &> $debug_data_dir/rc-status-l.txt
1801 rc-status -r &> $debug_data_dir/rc-status-r.txt
1803 touch $debug_data_dir/rc-status-absent
1805 if type -p systemctl &>/dev/null;then
1806 systemctl list-units &> $debug_data_dir/systemctl-list-units.txt
1807 systemctl list-units --type=target &> $debug_data_dir/systemctl-list-units-target.txt
1809 touch $debug_data_dir/systemctl-absent
1811 if type -p initctl &>/dev/null;then
1812 initctl list &> $debug_data_dir/initctl-list.txt
1814 touch $debug_data_dir/initctl-absent
1816 sensors &> $debug_data_dir/sensors.txt
1817 if type -p strings &>/dev/null;then
1818 touch $debug_data_dir/strings-present
1820 touch $debug_data_dir/strings-absent
1822 local id_dir='/sys/class/power_supply/'
1823 local ids=$( ls $id_dir 2>/dev/null )
1824 if [[ -n $ids ]];then
1827 cat $id_dir$batid'/uevent' &> $debug_data_dir/sys-power-supply-$batid.txt
1830 touch $debug_data_dir/sys-power-supply-none
1833 # leaving this commented out to remind that some systems do not
1834 # support strings --version, but will just simply hang at that command
1835 # which you can duplicate by simply typing: strings then hitting enter, you will get hang.
1836 # strings --version &> $debug_data_dir/strings.txt
1837 if type -p nvidia-smi &>/dev/null;then
1838 nvidia-smi -q &> $debug_data_dir/nvidia-smi-q.txt
1839 nvidia-smi -q -x &> $debug_data_dir/nvidia-smi-xq.txt
1841 touch $debug_data_dir/nvidia-smi-absent
1843 head -n 1 /proc/asound/card*/codec* &> $debug_data_dir/proc-asound-card-codec.txt
1844 if [[ -f /proc/version ]];then
1845 cat /proc/version &> $debug_data_dir/proc-version.txt
1847 touch $debug_data_dir/proc-version-absent
1849 echo $CC &> $debug_data_dir/cc-content.txt
1850 ls /usr/bin/gcc* &> $debug_data_dir/gcc-sys-versions.txt
1851 if type -p gcc &>/dev/null;then
1852 gcc --version &> $debug_data_dir/gcc-version.txt
1854 touch $debug_data_dir/gcc-absent
1856 if type -p clang &>/dev/null;then
1857 clang --version &> $debug_data_dir/clang-version.txt
1859 touch $debug_data_dir/clang-absent
1861 cat /etc/src.conf &> $debug_data_dir/bsd-etc-src-conf.txt
1862 cat /etc/make.conf &> $debug_data_dir/bsd-etc-make-conf.txt
1863 cat /etc/issue &> $debug_data_dir/etc-issue.txt
1864 cat $FILE_LSB_RELEASE &> $debug_data_dir/lsb-release.txt
1865 cat $FILE_OS_RELEASE &> $debug_data_dir/os-release.txt
1866 cat $FILE_ASOUND_DEVICE &> $debug_data_dir/proc-asound-device.txt
1867 cat $FILE_ASOUND_VERSION &> $debug_data_dir/proc-asound-version.txt
1868 cat $FILE_CPUINFO &> $debug_data_dir/proc-cpu-info.txt
1869 cat $FILE_MEMINFO &> $debug_data_dir/proc-meminfo.txt
1870 cat $FILE_MODULES &> $debug_data_dir/proc-modules.txt
1871 cat /proc/net/arp &> $debug_data_dir/proc-net-arp.txt
1873 cat /var/run/dmesg.boot &> $debug_data_dir/bsd-var-run-dmesg.boot.txt
1874 echo $COLS_INNER &> $debug_data_dir/cols-inner.txt
1876 check_recommends_user_output &> $debug_data_dir/check-recommends-user-output.txt
1877 # first download and verify xiin
1878 if [[ $B_UPLOAD_DEBUG_DATA == 'true' || $1 == 'disk' || $1 == 'sys' || $1 == 'all' ]];then
1879 touch $SCRIPT_DATA_DIR/$debug_data_dir/xiin-error.txt
1880 echo "Downloading required tree traverse tool $xiin_file..."
1881 if [[ -f xiin && ! -f $xiin_file ]];then
1882 mv -f xiin $xiin_file
1884 # -Nc is creating really weird download anomolies, so using -O instead
1887 xiin_download="$( curl -s $xiin_url )" || downloader_error=$?
1890 xiin_download="$( fetch -q -o - $xiin_url )" || downloader_error=$?
1893 xiin_download="$( ftp -o - $xiin_url 2>/dev/null )" || downloader_error=$?
1896 xiin_download="$( wget -q -O - $xiin_url )" || downloader_error=$?
1902 # if nothing got downloaded kick out error, otherwise we'll use an older version
1903 if [[ $downloader_error -gt 0 && ! -f $xiin_file ]];then
1904 echo -e "ERROR: Failed to download required file: $xiin_file\nMaybe the remote site is down or your networking is broken?"
1905 echo "Continuing with incomplete data collection."
1906 echo "$xiin_file download failed and no existing $xiin_file" >> $debug_data_dir/xiin-error.txt
1907 elif [[ -n $( grep -s '# EOF' <<< "$xiin_download" ) || -f $xiin_file ]];then
1908 if [[ -n $( grep -s '# EOF' <<< "$xiin_download" ) ]];then
1909 echo "Updating $xiin_file from remote location"
1910 echo "$xiin_download" > $xiin_file
1912 echo "Using local $xiin_file due to download failure"
1916 echo -e "ERROR: $xiin_file downloaded but the program file data is corrupted.\nContinuing with incomplete data collection."
1917 echo "$xiin_file downloaded but the program file data is corrupted." >> $debug_data_dir/xiin-error.txt
1920 # note, only bash 4> supports ;;& for case, so using if/then here
1921 if [[ $1 == 'disk' || $1 == 'sys' || $1 == 'all' ]];then
1922 xiin_data_file=$SCRIPT_DATA_DIR/$debug_data_dir/xiin-sys.txt
1923 echo 'Collecting networking data...'
1924 ifconfig &> $debug_data_dir/ifconfig.txt
1925 ip addr &> $debug_data_dir/ip-addr.txt
1926 if [[ $b_run_xiin == 'true' && -z $BSD_TYPE ]];then
1928 echo "Running $xiin_file tool now on /sys..."
1929 echo "Using Python version:" && python --version
1930 python --version &> $debug_data_dir/python-version.txt
1931 python ./$xiin_file -d /sys -f $xiin_data_file
1932 if [[ $? -ne 0 ]];then
1934 echo -e "ERROR: $xiin_file exited with error $error - removing data file.\nContinuing with incomplete data collection."
1935 echo "Continuing with incomplete data collection."
1936 rm -f $xiin_data_file
1937 echo "$xiin_file data generation failed with python error $error" >> $debug_data_dir/xiin-error.txt
1942 if [[ $1 == 'xorg' || $1 == 'all' ]];then
1943 if [[ $B_RUNNING_IN_DISPLAY != 'true' ]];then
1944 echo 'Warning: only some of the data collection can occur if you are not in X'
1945 touch $debug_data_dir/warning-user-not-in-x
1947 if [[ $B_ROOT == 'true' ]];then
1948 echo 'Warning: only some of the data collection can occur if you are running as Root user'
1949 touch $debug_data_dir/warning-root-user
1951 echo 'Collecting Xorg log and xorg.conf files'
1952 if [[ -e $FILE_XORG_LOG ]];then
1953 cat $FILE_XORG_LOG &> $debug_data_dir/xorg-log-file.txt
1955 touch $debug_data_dir/xorg-log-file-absent
1957 if [[ -e /etc/X11/xorg.conf ]];then
1958 cat /etc/X11/xorg.conf &> $debug_data_dir/xorg-conf.txt
1960 touch $debug_data_dir/xorg-conf-file-absent
1962 if [[ -n $( ls /etc/X11/xorg.conf.d/ 2>/dev/null ) ]];then
1963 ls /etc/X11/xorg.conf.d &> $debug_data_dir/ls-etc-x11-xorg-conf-d.txt
1964 xorg_d_files=$(ls /etc/X11/xorg.conf.d)
1965 for xorg_file in $xorg_d_files
1967 cat /etc/X11/xorg.conf.d/$xorg_file &> $debug_data_dir/xorg-conf-d-$xorg_file.txt
1970 touch $debug_data_dir/xorg-conf-d-files-absent
1972 echo 'Collecting X, xprop, glxinfo, xrandr, xdpyinfo data, wayland, weston...'
1973 if type -p weston-info &>/dev/null; then
1974 weston-info &> $debug_data_dir/weston-info.txt
1976 touch $debug_data_dir/weston-info-absent
1978 if type -p weston &>/dev/null; then
1979 weston --version &> $debug_data_dir/weston-version.txt
1981 touch $debug_data_dir/weston-absent
1983 if type -p xprop &>/dev/null; then
1984 xprop -root &> $debug_data_dir/xprop_root.txt
1986 touch $debug_data_dir/xprop-absent
1988 if type -p xprop &>/dev/null; then
1989 glxinfo &> $debug_data_dir/glxinfo.txt
1991 touch $debug_data_dir/glxinfo-absent
1993 if type -p xdpyinfo &>/dev/null; then
1994 xdpyinfo &> $debug_data_dir/xdpyinfo.txt
1996 touch $debug_data_dir/xdpyinfo-absent
1998 if type -p xrandr &>/dev/null; then
1999 xrandr &> $debug_data_dir/xrandr.txt
2001 touch $debug_data_dir/xrandr-absent
2003 if type -p X &>/dev/null; then
2004 X -version &> $debug_data_dir/x-version.txt
2006 touch $debug_data_dir/x-absent
2008 if type -p Xorg &>/dev/null; then
2009 Xorg -version &> $debug_data_dir/xorg-version.txt
2011 touch $debug_data_dir/xorg-absent
2014 echo $GNOME_DESKTOP_SESSION_ID &> $debug_data_dir/gnome-desktop-session-id.txt
2016 echo $KDE_FULL_SESSION &> $debug_data_dir/kde3-full-session.txt
2017 echo $KDE_SESSION_VERSION &> $debug_data_dir/kde-gte-4-session-version.txt
2018 if type -p kf5-config &>/dev/null; then
2019 kf5-config --version &> $debug_data_dir/kde-kf5-config-version-data.txt
2020 elif type -p kf6-config &>/dev/null; then
2021 kf6-config --version &> $debug_data_dir/kde-kf6-config-version-data.txt
2022 elif type -p kf$KDE_SESSION_VERSION-config &>/dev/null; then
2023 kf$KDE_SESSION_VERSION-config --version &> $debug_data_dir/kde-kf$KDE_SESSION_VERSION-KSV-config-version-data.txt
2025 touch $debug_data_dir/kde-kf-config-absent
2027 if type -p plasmashell &>/dev/null; then
2028 plasmashell --version &> $debug_data_dir/kde-plasmashell-version-data.txt
2030 touch $debug_data_dir/kde-plasmashell-absent
2032 if type -p kwin_x11 &>/dev/null; then
2033 kwin_x11 --version &> $debug_data_dir/kde-kwin_x11-version-data.txt
2035 touch $debug_data_dir/kde-kwin_x11-absent
2037 if type -p kded4 &>/dev/null; then
2038 kded4 --version &> $debug_data_dir/kded4-version-data.txt
2039 elif type -p kded5 &>/dev/null; then
2040 kded5 --version &> $debug_data_dir/kded5-version-data.txt
2041 elif type -p kded &>/dev/null; then
2042 kded --version &> $debug_data_dir/kded-version-data.txt
2044 touch $debug_data_dir/kded-$KDE_SESSION_VERSION-absent
2046 # kde 5/plasma desktop 5, this is maybe an extra package and won't be used
2047 if type -p about-distro &>/dev/null; then
2048 about-distro &> $debug_data_dir/kde-about-distro.txt
2050 touch $debug_data_dir/kde-about-distro-absent
2052 echo $XDG_CURRENT_DESKTOP &> $debug_data_dir/xdg-current-desktop.txt
2054 if [[ $1 == 'disk' || $1 == 'all' ]];then
2055 echo 'Collecting dev, label, disk, uuid data, df...'
2056 ls -l /dev &> $debug_data_dir/dev-data.txt
2057 ls -l /dev/disk &> $debug_data_dir/dev-disk-data.txt
2058 ls -l /dev/disk/by-id &> $debug_data_dir/dev-disk-id-data.txt
2059 ls -l /dev/disk/by-label &> $debug_data_dir/dev-disk-label-data.txt
2060 ls -l /dev/disk/by-uuid &> $debug_data_dir/dev-disk-uuid-data.txt
2061 # http://comments.gmane.org/gmane.linux.file-systems.zfs.user/2032
2062 ls -l /dev/disk/by-wwn &> $debug_data_dir/dev-disk-wwn-data.txt
2063 ls -l /dev/disk/by-path &> $debug_data_dir/dev-disk-path-data.txt
2064 ls -l /dev/mapper &> $debug_data_dir/dev-disk-mapper-data.txt
2065 readlink /dev/root &> $debug_data_dir/dev-root.txt
2066 df -h -T -P --exclude-type=aufs --exclude-type=squashfs --exclude-type=unionfs --exclude-type=devtmpfs --exclude-type=tmpfs --exclude-type=iso9660 --exclude-type=devfs --exclude-type=linprocfs --exclude-type=sysfs --exclude-type=fdescfs &> $debug_data_dir/df-h-T-P-excludes.txt
2067 df -T -P --exclude-type=aufs --exclude-type=squashfs --exclude-type=unionfs --exclude-type=devtmpfs --exclude-type=tmpfs --exclude-type=iso9660 --exclude-type=devfs --exclude-type=linprocfs --exclude-type=sysfs --exclude-type=fdescfs &> $debug_data_dir/df-T-P-excludes.txt
2068 df -T -P --exclude-type=aufs --exclude-type=squashfs --exclude-type=unionfs --exclude-type=devtmpfs --exclude-type=tmpfs --exclude-type=iso9660 --exclude-type=devfs --exclude-type=linprocfs --exclude-type=sysfs --exclude-type=fdescfs --total &> $debug_data_dir/df-T-P-excludes-total.txt
2069 df -h -T &> $debug_data_dir/bsd-df-h-T-no-excludes.txt
2070 df -h &> $debug_data_dir/bsd-df-h-no-excludes.txt
2071 df -k -T &> $debug_data_dir/bsd-df-k-T-no-excludes.txt
2072 df -k &> $debug_data_dir/bsd-df-k-no-excludes.txt
2073 atacontrol list &> $debug_data_dir/bsd-atacontrol-list.txt
2074 camcontrol devlist &> $debug_data_dir/bsd-camcontrol-devlist.txt
2076 mount &> $debug_data_dir/mount.txt
2077 btrfs filesystem show &> $debug_data_dir/btrfs-filesystem-show.txt
2078 btrfs filesystem show --mounted &> $debug_data_dir/btrfs-filesystem-show-mounted.txt
2079 # btrfs filesystem show --all-devices &> $debug_data_dir/btrfs-filesystem-show-all-devices.txt
2080 gpart list &> $debug_data_dir/bsd-gpart-list.txt
2081 gpart show &> $debug_data_dir/bsd-gpart-show.txt
2082 gpart status &> $debug_data_dir/bsd-gpart-status.txt
2083 swapctl -l -k &> $debug_data_dir/bsd-swapctl-l-k.txt
2084 swapon -s &> $debug_data_dir/swapon-s.txt
2085 sysctl -b kern.geom.conftxt &> $debug_data_dir/bsd-sysctl-b-kern.geom.conftxt.txt
2086 sysctl -b kern.geom.confxml &> $debug_data_dir/bsd-sysctl-b-kern.geom.confxml.txt
2087 zfs list &> $debug_data_dir/bsd-zfs-list.txt
2088 zpool list &> $debug_data_dir/bsd-zpool-list.txt
2089 zpool list -v &> $debug_data_dir/bsd-zpool-list-v.txt
2090 df -P --exclude-type=aufs --exclude-type=squashfs --exclude-type=unionfs --exclude-type=devtmpfs --exclude-type=tmpfs --exclude-type=iso9660 &> $debug_data_dir/df-P-excludes.txt
2091 df -P &> $debug_data_dir/bsd-df-P-no-excludes.txt
2092 cat /proc/mdstat &> $debug_data_dir/proc-mdstat.txt
2093 cat $FILE_PARTITIONS &> $debug_data_dir/proc-partitions.txt
2094 cat $FILE_SCSI &> $debug_data_dir/proc-scsi.txt
2095 cat $FILE_MOUNTS &> $debug_data_dir/proc-mounts.txt
2096 cat /proc/sys/dev/cdrom/info &> $debug_data_dir/proc-cdrom-info.txt
2097 ls /proc/ide/ &> $debug_data_dir/proc-ide.txt
2098 cat /proc/ide/*/* &> $debug_data_dir/proc-ide-hdx-cat.txt
2099 cat /etc/fstab &> $debug_data_dir/etc-fstab.txt
2100 cat /etc/mtab &> $debug_data_dir/etc-mtab.txt
2102 echo 'Creating inxi output file now. This can take a few seconds...'
2103 echo "Starting $SCRIPT_NAME from: $start_directory"
2105 $SCRIPT_PATH/$SCRIPT_NAME -F${debug_i}Rfrploudmxxx -c 0 -@ 8 -y 120 > $SCRIPT_DATA_DIR/$debug_data_dir/inxi-F${debug_i}Rfrploudmxxxy120.txt
2106 cp $LOG_FILE $SCRIPT_DATA_DIR/$debug_data_dir
2107 if [[ -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz ]];then
2108 echo "Found and removing previous tar.gz data file: $debug_data_dir.tar.gz"
2109 rm -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz
2112 echo 'Creating tar.gz compressed file of this material now. Contents:'
2114 tar -cvzf $debug_data_dir.tar.gz $debug_data_dir
2116 echo 'Cleaning up leftovers...'
2117 rm -rf $debug_data_dir
2118 echo 'Testing gzip file integrity...'
2119 gzip -t $debug_data_dir.tar.gz
2120 if [[ $? -gt 0 ]];then
2121 echo 'Data in gz is corrupted, removing gzip file, try running data collector again.'
2122 rm -f $debug_data_dir.tar.gz
2123 echo "Data in gz is corrupted, removed gzip file" >> $debug_data_dir/gzip-error.txt
2125 echo 'All done, you can find your data gzipped directory here:'
2126 completed_gz_file=$SCRIPT_DATA_DIR/$debug_data_dir.tar.gz
2127 echo $completed_gz_file
2128 if [[ $B_UPLOAD_DEBUG_DATA == 'true' ]];then
2130 if [[ $b_run_xiin == 'true' ]];then
2131 echo "Running automatic upload of data to remote server $ftp_upload now..."
2132 python ./$xiin_file --version
2133 python ./$xiin_file -u $completed_gz_file $ftp_upload
2134 if [[ $? -gt 0 ]];then
2136 echo "Error: looks like the ftp upload failed. Error number: $?"
2137 echo "The ftp upload failed. Error number: $?" >> $debug_data_dir/xiin-error.txt
2140 echo 'Unable to run the automoatic ftp upload because of an error with the xiin download.'
2141 echo "Unable to run the automoatic ftp upload because of an error with the xiin download" >> $debug_data_dir/xiin-error.txt
2144 echo 'You can upload this here using most file managers: ftp.techpatterns.com/incoming'
2145 echo 'then let a maintainer know it is uploaded.'
2149 echo 'This feature only available in console or shell client! Exiting now.'
2154 check_recommends_user_output()
2157 local gawk_version='N/A' sed_version='N/A' sudo_version='N/A' python_version='N/A'
2158 local downloaders_bsd=''
2160 if [[ $B_IRC == 'true' ]];then
2161 print_screen_output "Sorry, you can't run this option in an IRC client."
2164 if [[ -n $BSD_TYPE ]];then
2166 fetch:BSD-only~BSD-only~BSD-only~:-i_wan_ip;-w/-W;-U/-!_[11-15]_(BSDs)
2167 ftp:ftp-OpenBSD-only~ftp-OpenBSD-only~ftp-OpenBSD-only~:-i_wan_ip;-w/-W;-U/-!_[11-15]_(OpenBSD_only)'
2170 print_lines_basic "0" "" "$SCRIPT_NAME will now begin checking for the programs it needs to operate. First a check of the main languages and tools $SCRIPT_NAME uses. Python is only for debugging data collection."
2172 echo "Bash version: $( bash --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^GNU bash/ {print $4}' )"
2173 if type -p gawk &>/dev/null;then
2174 gawk_version=$( gawk --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^GNU Awk/ {print $3}' )
2176 if type -p sed &>/dev/null;then
2177 sed_version=$( sed --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^GNU sed version/ {print $4}' )
2178 if [[ -z $sed_version ]];then
2179 # note: bsd sed shows error with --version flag
2180 sed_version=$( sed --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^sed: illegal option/ {print "BSD sed"}' )
2183 if type -p sudo &>/dev/null;then
2184 sudo_version=$( sudo -V 2>&1 | awk 'BEGIN {IGNORECASE=1} /^Sudo version/ {print $3}' )
2186 if type -p python &>/dev/null;then
2187 python_version=$( python --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^Python/ {print $2}' )
2189 echo "Gawk version: $gawk_version"
2190 echo "Sed version: $sed_version"
2191 echo "Sudo version: $sudo_version"
2192 echo "Python version: $python_version"
2195 echo "Test One: Required System Directories (Linux Only)."
2196 print_lines_basic "0" "" "If one of these system directories is missing, $SCRIPT_NAME cannot operate:"
2198 check_recommends_items 'required-dirs'
2200 echo "Test Two: Required Core Applications."
2201 print_lines_basic "0" "" "If one of these applications is missing, $SCRIPT_NAME cannot operate:"
2203 check_recommends_items 'required-apps'
2205 print_lines_basic "0" "" "Test Three: Script Recommends for Graphics Features."
2206 print_lines_basic "0" "" "NOTE: If you do not use X these do not matter (like a headless server). Otherwise, if one of these applications is missing, $SCRIPT_NAME will have incomplete output:"
2208 check_recommends_items 'recommended-x-apps'
2210 echo 'Test Four: Script Recommends for Remaining Features.'
2211 print_lines_basic "0" "" "If one of these applications is missing, $SCRIPT_NAME will have incomplete output:"
2213 check_recommends_items 'recommended-apps'
2215 echo 'Test Five: Script Recommends for Remaining Features.'
2216 print_lines_basic "0" "" "One of these downloaders needed for options -i/-w/-W (-U/-! [11-15], if supported):"
2218 check_recommends_items 'downloaders'
2220 echo 'Test Six: System Directories for Various Information.'
2221 echo '(Unless otherwise noted, these are for GNU/Linux systems)'
2222 print_lines_basic "0" "" "If one of these directories is missing, $SCRIPT_NAME may have incomplete output:"
2224 check_recommends_items 'system-dirs'
2226 echo 'Test Seven: System Files for Various Information.'
2227 echo '(Unless otherwise noted, these are for GNU/Linux systems)'
2228 print_lines_basic "0" "" "If one of these files is missing, $SCRIPT_NAME may have incomplete output:"
2230 check_recommends_items 'system-files'
2232 echo 'All tests completed.'
2234 # args: $1 - check item
2235 check_recommends_items()
2237 local item='' item_list='' item_string='' missing_items='' missing_string=''
2238 local package='' application='' feature='' type='' starter='' finisher=''
2239 local package_deb='' package_pacman='' package_rpm=''
2240 local print_string='' separator='' width=56
2241 local required_dirs='/proc /sys'
2242 # package-owner: 1 - debian/ubuntu; 2 - arch; 3 - yum/rpm
2243 # pardus: pisi sf -q /usr/bin/package
2244 local required_apps='
2245 df:coreutils~coreutils~coreutils~:partition_data
2246 gawk:gawk~gawk~gawk~:core_tool
2247 grep:grep~grep~grep~:string_search
2248 lspci:pciutils~pciutils~pciutils~:hardware_data
2249 ps:procps~procps~procps~:process_data
2250 readlink:coreutils~coreutils~coreutils~:
2251 sed:sed~sed~sed~:string_replace
2252 tr:coreutils~coreutils~coreutils~:character_replace
2253 uname:uname~coreutils~coreutils~:kernel_data
2254 wc:coreutils~coreutils~coreutils~:word_character_count
2256 local x_recommends='
2257 glxinfo:mesa-utils~mesa-demos~glx-utils_(openSUSE_12.3_and_later_Mesa-demo-x)~:-G_glx_info
2258 xdpyinfo:X11-utils~xorg-xdpyinfo~xorg-x11-utils~:-G_multi_screen_resolution
2259 xprop:X11-utils~xorg-xprop~x11-utils~:-S_desktop_data
2260 xrandr:x11-xserver-utils~xrandr~x11-server-utils~:-G_single_screen_resolution
2262 local recommended_apps='
2263 dig:dnsutils~dnsutils~bind-utils:-i_first_wlan_ip_default_test
2264 dmidecode:dmidecode~dmidecode~dmidecode~:-M_if_no_sys_machine_data;_-m_memory
2265 file:file~file~file~:-o_unmounted_file_system
2266 hciconfig:bluez~bluez-utils~bluez-utils~:-n_-i_bluetooth_data
2267 hddtemp:hddtemp~hddtemp~hddtemp~:-Dx_show_hdd_temp
2268 ifconfig:net-tools~net-tools~net-tools~:-i_ip_lan-deprecated
2269 ip:iproute~iproute2~iproute~:-i_ip_lan
2270 sensors:lm-sensors~lm_sensors~lm-sensors~:-s_sensors_output
2271 strings:binutils~~~:-I_sysvinit_version
2272 lsusb:usbutils~usbutils~usbutils~:-A_usb_audio;-N_usb_networking
2273 modinfo:module-init-tools~module-init-tools~module-init-tools~:-Ax,-Nx_module_version
2274 runlevel:sysvinit~sysvinit~systemd~:-I_runlevel
2275 sudo:sudo~sudo~sudo~:-Dx_hddtemp-user;-o_file-user
2276 uptime:procps~procps~procps~:-I_uptime_(check_which_package_owns_Debian)
2280 wget:wget~wget~wget~:-i_wan_ip;-w/-W;-U/-!_[11-15]_(if_supported)
2281 curl:curl~curl~curl~:-i_wan_ip;-w/-W;-U/-!_[11-15]_(if_supported)
2284 local recommended_dirs='
2285 /sys/class/dmi/id:-M_system,_motherboard,_bios
2286 /dev:-l,-u,-o,-p,-P,-D_disk_partition_data
2287 /dev/disk/by-label:-l,-o,-p,-P_partition_labels
2288 /dev/disk/by-uuid:-u,-o,-p,-P_partition_uuid
2290 local recommended_files="
2291 $FILE_ASOUND_DEVICE:-A_sound_card_data
2292 $FILE_ASOUND_VERSION:-A_ALSA_data
2293 $FILE_CPUINFO:-C_cpu_data
2294 $FILE_LSB_RELEASE:-S_distro_version_data_[deprecated]
2295 $FILE_MDSTAT:-R_mdraid_data
2296 $FILE_MEMINFO:-I_memory_data
2297 $FILE_OS_RELEASE:-S_distro_version_data
2298 $FILE_PARTITIONS:-p,-P_partitions_data
2299 $FILE_MODULES:-G_module_data
2300 $FILE_MOUNTS:-P,-p_partition_advanced_data
2301 $FILE_DMESG_BOOT:-D,-d_disk_data_[BSD_only]
2302 $FILE_SCSI:-D_Advanced_hard_disk_data_[used_rarely]
2303 $FILE_XORG_LOG:-G_graphics_driver_load_status
2306 if [[ -n $COLS_INNER ]];then
2307 if [[ $COLS_INNER -ge 90 ]];then
2308 width=${#LINE1} # match width of $LINE1
2309 elif [[ $COLS_INNER -ge 78 ]];then
2310 width=$(( $COLS_INNER - 11 ))
2316 item_list=$downloaders
2317 item_string='Downloaders'
2319 missing_string='downloaders, and their corresponding packages,'
2323 item_list=$required_dirs
2324 item_string='Required file system'
2326 missing_string='system directories'
2330 item_list=$required_apps
2331 item_string='Required application'
2333 missing_string='applications, and their corresponding packages,'
2337 item_list=$x_recommends
2338 item_string='Recommended X application'
2340 missing_string='applications, and their corresponding packages,'
2344 item_list=$recommended_apps
2345 item_string='Recommended application'
2347 missing_string='applications, and their corresponding packages,'
2351 item_list=$recommended_dirs
2352 item_string='System directory'
2354 missing_string='system directories'
2358 item_list=$recommended_files
2359 item_string='System file'
2361 missing_string='system files'
2365 # great trick from: http://ideatrash.net/2011/01/bash-string-padding-with-sed.html
2366 # left pad: sed -e :a -e 's/^.\{1,80\}$/& /;ta'
2367 # right pad: sed -e :a -e 's/^.\{1,80\}$/ &/;ta'
2368 # center pad: sed -e :a -e 's/^.\{1,80\}$/ & /;ta'
2370 for item in $item_list
2372 if [[ $( awk -F ":" '{print NF-1}' <<< $item ) -eq 0 ]];then
2377 elif [[ $( awk -F ":" '{print NF-1}' <<< $item ) -eq 1 ]];then
2378 application=$( cut -d ':' -f 1 <<< $item )
2380 feature=$( cut -d ':' -f 2 <<< $item )
2383 application=$( cut -d ':' -f 1 <<< $item )
2384 package=$( cut -d ':' -f 2 <<< $item )
2385 location=$( type -p $application )
2386 if [[ $( awk -F ":" '{print NF-1}' <<< $item ) -eq 2 ]];then
2387 feature=$( cut -d ':' -f 3 <<< $item )
2392 if [[ -n $feature ]];then
2393 print_string="$item_string$application (info: $( sed 's/_/ /g' <<< $feature ))"
2395 print_string="$item_string$application"
2398 starter="$( sed -e :a -e 's/^.\{1,'$width'\}$/&./;ta' <<< $print_string )"
2399 if [[ -z $( grep '^/' <<< $application ) && -n $location ]] || [[ -d $application || -f $application ]];then
2400 if [[ -n $location ]];then
2401 finisher=" $location"
2407 missing_items="$missing_items$separator$application:$package"
2411 echo "$starter$finisher"
2414 if [[ -n $missing_items ]];then
2415 echo "The following $type are missing from your system:"
2416 for item in $missing_items
2418 application=$( cut -d ':' -f 1 <<< $item )
2419 if [[ $type == 'applications' ]];then
2421 package=$( cut -d ':' -f 2 <<< $item )
2422 package_deb=$( cut -d '~' -f 1 <<< $package )
2423 package_pacman=$( cut -d '~' -f 2 <<< $package )
2424 package_rpm=$( cut -d '~' -f 3 <<< $package )
2425 echo "Application: $application"
2426 print_lines_basic "0" "" "To add to your system, install the proper distribution package for your system:"
2427 print_lines_basic "0" "" "Debian/Ubuntu:^$package_deb^:: Arch Linux:^$package_pacman^:: Redhat/Fedora/Suse:^$package_rpm"
2428 elif [[ $type == 'directories' ]];then
2429 echo "Directory: $application"
2430 elif [[ $type == 'files' ]];then
2431 echo "File: $application"
2434 if [[ $item_string == 'System directory' ]];then
2435 print_lines_basic "0" "" "These directories are created by the kernel, so don't worry if they are not present."
2438 echo "All the $( cut -d ' ' -f 1 <<< $item_string | sed -e 's/Re/re/' -e 's/Sy/sy/' ) $type are present."
2443 #### -------------------------------------------------------------------
2444 #### print / output cleaners
2445 #### -------------------------------------------------------------------
2447 # inxi speaks through here. When run by Konversation script alias mode, uses DCOP
2448 # for dcop to work, must use 'say' operator, AND colors must be evaluated by echo -e
2449 # note: dcop does not seem able to handle \n so that's being stripped out and replaced with space.
2450 print_screen_output()
2453 # the double quotes are needed to avoid losing whitespace in data when certain output types are used
2454 # trim off whitespace at end
2455 local print_data="$( echo -e "$1" )"
2457 # just using basic debugger stuff so you can tell which thing is printing out the data. This
2458 # should help debug kde 4 konvi issues when that is released into sid, we'll see. Turning off
2459 # the redundant debugger output which as far as I can tell does exactly nothing to help debugging.
2460 if [[ $DEBUG -gt 5 ]];then
2461 if [[ $KONVI -eq 1 ]];then
2462 # konvi doesn't seem to like \n characters, it just prints them literally
2463 # print_data="$( tr '\n' ' ' <<< "$print_data" )"
2464 # dcop "$DCPORT" "$DCOPOBJ" say "$DCSERVER" "$DCTARGET" "konvi='$KONVI' saying : '$print_data'"
2465 print_data="KP-$KONVI: $print_data"
2466 elif [[ $KONVI -eq 2 ]];then
2467 # echo "konvi='$KONVI' saying : '$print_data'"
2468 print_data="KP-$KONVI: $print_data"
2470 # echo "printing out: '$print_data'"
2471 print_data="P: $print_data"
2474 if [[ $KONVI -eq 1 && $B_DCOP == 'true' ]]; then ## dcop Konversation (<= 1.1 (qt3))
2475 # konvi doesn't seem to like \n characters, it just prints them literally
2476 $print_data="$( tr '\n' ' ' <<< "$print_data" )"
2477 dcop "$DCPORT" "$DCOPOBJ" say "$DCSERVER" "$DCTARGET" "$print_data"
2478 elif [[ $KONVI -eq 3 && $B_QDBUS == 'true' ]]; then ## dbus Konversation (> 1.2 (qt4))
2479 qdbus org.kde.konversation /irc say "$DCSERVER" "$DCTARGET" "$print_data"
2480 # elif [[ $IRC_CLIENT == 'X-Chat' ]]; then
2481 # qdbus org.xchat.service print "$print_data\n"
2483 # the -n is needed to avoid double spacing of output in terminal
2484 echo -ne "$print_data\n"
2489 ## this handles all verbose line construction with indentation/line starter
2490 ## args: $1 - null (, actually: " ") or line starter; $2 - line content
2494 # convoluted, yes, but it works to trim spaces off end
2495 local line=${2%${2##*[![:space:]]}}
2496 printf "${C1}%-${INDENT}s${C2} %s" "$1" "$line${CN}"
2500 # this removes newline and pipes.
2501 # args: $1 - string to clean
2502 remove_erroneous_chars()
2505 ## RS is input record separator
2506 ## gsub is substitute;
2512 gsub(/\n$/,"") ## (newline; end of string) with (nothing)
2513 gsub(/\n/," "); ## (newline) with (space)
2514 gsub(/^ *| *$/, "") ## (pipe char) with (nothing)
2515 gsub(/ +/, " ") ## ( +) with (space)
2516 gsub(/ [ ]+/, " ") ## ([ ]+) with (space)
2517 gsub(/^ +| +$/, "") ## (pipe char) with (nothing)
2519 }' "$1" ## prints (returns) cleaned input
2523 #### -------------------------------------------------------------------
2524 #### parameter handling, print usage functions.
2525 #### -------------------------------------------------------------------
2527 # Get the parameters. Note: standard options should be lower case, advanced or testing, upper
2528 # args: $1 - full script startup args: $@
2532 local opt='' downloader_test='' debug_data_type='' weather_flag='wW:'
2533 local use_short='true' # this is needed to trigger short output, every v/d/F/line trigger sets this false
2535 # if distro maintainers don't want the weather feature disable it
2536 if [[ $B_ALLOW_WEATHER == 'false' ]];then
2539 if [[ $1 == '--version' ]];then
2542 elif [[ $1 == '--help' ]];then
2545 elif [[ $1 == '--recommends' ]];then
2546 check_recommends_user_output
2548 # the short form only runs if no args output args are used
2549 # no need to run through these if there are no args
2550 # reserved for future use: -g for extra Graphics; -m for extra Machine; -d for extra Disk
2551 elif [[ -n $1 ]];then
2552 while getopts AbBc:CdDfFGhHiIlmMnNopPrRsSt:uUv:V${weather_flag}xy:zZ%@:!: opt
2555 A) B_SHOW_AUDIO='true'
2558 b) use_short='false'
2559 B_SHOW_BASIC_CPU='true'
2560 B_SHOW_BASIC_RAID='true'
2561 B_SHOW_DISK_TOTAL='true'
2562 B_SHOW_GRAPHICS='true'
2564 B_SHOW_MACHINE='true'
2565 B_SHOW_BATTERY='true'
2566 B_SHOW_NETWORK='true'
2567 B_SHOW_SYSTEM='true'
2569 B) B_SHOW_BATTERY_FORCED='true'
2570 B_SHOW_BATTERY='true'
2573 c) if [[ $OPTARG =~ ^[0-9][0-9]?$ ]];then
2576 B_RUN_COLOR_SELECTOR='true'
2577 COLOR_SELECTION='global'
2580 B_RUN_COLOR_SELECTOR='true'
2581 COLOR_SELECTION='irc-console'
2584 B_RUN_COLOR_SELECTOR='true'
2585 COLOR_SELECTION='irc-virtual-terminal'
2588 B_RUN_COLOR_SELECTOR='true'
2589 COLOR_SELECTION='irc'
2592 B_RUN_COLOR_SELECTOR='true'
2593 COLOR_SELECTION='virtual-terminal'
2596 B_RUN_COLOR_SELECTOR='true'
2597 COLOR_SELECTION='console'
2600 B_COLOR_SCHEME_SET='true'
2601 ## note: not sure about this, you'd think user values should be overridden, but
2602 ## we'll leave this for now
2603 if [[ -z $COLOR_SCHEME ]];then
2604 set_color_scheme "$OPTARG"
2609 error_handler 3 "$OPTARG"
2612 C) B_SHOW_CPU='true'
2615 d) B_SHOW_DISK='true'
2616 B_SHOW_FULL_OPTICAL='true'
2618 # error_handler 20 "-d has been replaced by -b"
2620 D) B_SHOW_DISK='true'
2623 f) B_SHOW_CPU='true'
2624 B_CPU_FLAGS_FULL='true'
2627 F) # B_EXTRA_DATA='true'
2628 B_SHOW_ADVANCED_NETWORK='true'
2630 # B_SHOW_BASIC_OPTICAL='true'
2633 B_SHOW_GRAPHICS='true'
2635 B_SHOW_MACHINE='true'
2636 B_SHOW_BATTERY='true'
2637 B_SHOW_NETWORK='true'
2638 B_SHOW_PARTITIONS='true'
2640 B_SHOW_SENSORS='true'
2641 B_SHOW_SYSTEM='true'
2644 G) B_SHOW_GRAPHICS='true'
2648 B_SHOW_NETWORK='true'
2649 B_SHOW_ADVANCED_NETWORK='true'
2652 I) B_SHOW_INFO='true'
2655 l) B_SHOW_LABELS='true'
2656 B_SHOW_PARTITIONS='true'
2659 m) B_SHOW_MEMORY='true'
2662 M) B_SHOW_MACHINE='true'
2663 B_SHOW_BATTERY='true'
2666 n) B_SHOW_ADVANCED_NETWORK='true'
2667 B_SHOW_NETWORK='true'
2670 N) B_SHOW_NETWORK='true'
2673 o) B_SHOW_UNMOUNTED_PARTITIONS='true'
2676 p) B_SHOW_PARTITIONS_FULL='true'
2677 B_SHOW_PARTITIONS='true'
2680 P) B_SHOW_PARTITIONS='true'
2683 r) B_SHOW_REPOS='true'
2686 R) B_SHOW_RAID='true'
2687 # it turns out only users with mdraid software installed will have raid,
2688 # so unless -R is explicitly called, blank -b/-F/-v6 and less output will not show
2689 # error if file is missing.
2690 B_SHOW_RAID_R='true'
2693 s) B_SHOW_SENSORS='true'
2696 S) B_SHOW_SYSTEM='true'
2699 t) if [[ $OPTARG =~ ^(c|m|cm|mc)([1-9]|1[0-9]|20)?$ ]];then
2701 if [[ -n $( grep -E '[0-9]+' <<< $OPTARG ) ]];then
2702 PS_COUNT=$( sed 's/[^0-9]//g' <<< $OPTARG )
2704 if [[ -n $( grep 'c' <<< $OPTARG ) ]];then
2705 B_SHOW_PS_CPU_DATA='true'
2707 if [[ -n $( grep 'm' <<< $OPTARG ) ]];then
2708 B_SHOW_PS_MEM_DATA='true'
2711 error_handler 13 "$OPTARG"
2714 u) B_SHOW_UUIDS='true'
2715 B_SHOW_PARTITIONS='true'
2718 v) if [[ $OPTARG =~ ^[0-9][0-9]?$ && $OPTARG -le $VERBOSITY_LEVELS ]];then
2719 if [[ $OPTARG -ge 1 ]];then
2721 B_SHOW_BASIC_CPU='true'
2722 B_SHOW_DISK_TOTAL='true'
2723 B_SHOW_GRAPHICS='true'
2725 B_SHOW_SYSTEM='true'
2727 if [[ $OPTARG -ge 2 ]];then
2728 B_SHOW_BASIC_DISK='true'
2729 B_SHOW_BASIC_RAID='true'
2730 B_SHOW_BATTERY='true'
2731 B_SHOW_MACHINE='true'
2732 B_SHOW_NETWORK='true'
2734 if [[ $OPTARG -ge 3 ]];then
2735 B_SHOW_ADVANCED_NETWORK='true'
2739 if [[ $OPTARG -ge 4 ]];then
2741 B_SHOW_PARTITIONS='true'
2743 if [[ $OPTARG -ge 5 ]];then
2745 B_SHOW_BASIC_OPTICAL='true'
2746 B_SHOW_MEMORY='true'
2747 B_SHOW_SENSORS='true'
2748 B_SHOW_LABELS='true'
2752 if [[ $OPTARG -ge 6 ]];then
2753 B_SHOW_FULL_OPTICAL='true'
2754 B_SHOW_PARTITIONS_FULL='true'
2755 B_SHOW_UNMOUNTED_PARTITIONS='true'
2756 B_EXTRA_EXTRA_DATA='true'
2758 if [[ $OPTARG -ge 7 ]];then
2759 B_EXTRA_EXTRA_EXTRA_DATA='true'
2761 B_SHOW_RAID_R='true'
2764 error_handler 4 "$OPTARG"
2767 U) if [[ $B_ALLOW_UPDATE == 'true' ]];then
2768 script_self_updater "$SCRIPT_DOWNLOAD" 'svn server' "$opt"
2770 error_handler 17 "-$opt"
2773 V) print_version_info
2776 w) B_SHOW_WEATHER=true
2779 W) ALTERNATE_WEATHER_LOCATION=$( sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' <<< $OPTARG )
2780 if [[ -n $( grep -Esi '([^,]+,.+|[0-9-]+)' <<< $ALTERNATE_WEATHER_LOCATION ) ]];then
2784 error_handler 18 "-$opt: '$OPTARG'" "city,state OR latitude,longitude OR postal/zip code."
2787 # this will trigger either with x, xx, xxx or with Fx but not with xF
2788 x) if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
2789 B_EXTRA_EXTRA_EXTRA_DATA='true'
2790 elif [[ $B_EXTRA_DATA == 'true' ]];then
2791 B_EXTRA_EXTRA_DATA='true'
2796 y) if [[ -z ${OPTARG//[0-9]/} && $OPTARG -ge 80 ]];then
2797 set_display_width "$OPTARG"
2799 error_handler 21 "$OPTARG"
2802 z) B_OUTPUT_FILTER='true'
2804 Z) B_OVERRIDE_FILTER='true'
2809 H) show_options 'full'
2812 ## debuggers and testing tools
2813 %) B_HANDLE_CORRUPT_DATA='true'
2815 @) if [[ -n $( grep -E "^([1-9]|1[0-5])$" <<< $OPTARG ) ]];then
2817 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
2818 B_UPLOAD_DEBUG_DATA='true'
2821 # switch on logging only for -@ 8-10
2824 if [[ $OPTARG -eq 10 ]];then
2826 elif [[ $OPTARG -eq 9 ]];then
2827 B_LOG_FULL_DATA='true'
2829 B_USE_LOGGING='true'
2830 # pack the logging data for evals function start/end
2833 create_rotate_logfiles # create/rotate logfiles before we do anything else
2838 debug_data_type='sys'
2841 debug_data_type='xorg'
2844 debug_data_type='disk'
2847 debug_data_type='all'
2850 debug_data_type='all'
2855 debug_data_collector $debug_data_type
2859 error_handler 9 "$OPTARG"
2862 !) # test for various supported methods
2864 1) B_TESTING_1='true'
2866 2) B_TESTING_2='true'
2868 3) B_TESTING_1='true'
2872 if [[ $B_ALLOW_UPDATE == 'true' ]];then
2875 script_self_updater "$SCRIPT_DOWNLOAD_DEV" 'dev server' "$opt $OPTARG"
2878 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_1" 'svn: branch one server' "$opt $OPTARG"
2881 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_2" 'svn: branch two server' "$opt $OPTARG"
2884 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_3" 'svn: branch three server' "$opt $OPTARG"
2887 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_4" 'svn: branch four server' "$opt $OPTARG"
2890 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_BSD" 'svn: branch bsd server' "$opt $OPTARG"
2893 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_GNUBSD" 'svn: branch gnubsd server' "$opt $OPTARG"
2896 script_self_updater "$OPTARG" 'alt server' "$opt <http...>"
2900 error_handler 17 "-$opt $OPTARG"
2913 B_FORCE_DMIDECODE='true'
2916 ALTERNATE_FTP="$OPTARG"
2918 # for weather function, allows user to set an alternate weather location
2920 error_handler 19 "-$opt location=" "-W"
2922 *) error_handler 11 "$OPTARG"
2926 *) error_handler 7 "$1"
2931 ## this must occur here so you can use the debugging flag to show errors
2932 ## Reroute all error messages to the bitbucket (if not debugging)
2933 if [[ $DEBUG -eq 0 ]];then
2936 #((DEBUG)) && exec 2>&1 # This is for debugging konversation
2938 # after all the args have been processed, if no long output args used, run short output
2939 if [[ $use_short == 'true' ]];then
2940 B_SHOW_SHORT_OUTPUT='true'
2942 # just in case someone insists on using -zZ
2943 if [[ $B_OVERRIDE_FILTER == 'true' ]];then
2944 B_OUTPUT_FILTER='false'
2946 # change basic to full if user requested it or if arg overrides it
2947 if [[ $B_SHOW_RAID == 'true' && $B_SHOW_BASIC_RAID == 'true' ]];then
2948 B_SHOW_BASIC_RAID='false'
2955 ## print out help menu, not including Testing or Debugger stuff because it's not needed
2958 local color_scheme_count=$(( ${#A_COLOR_SCHEMES[@]} - 1 ))
2959 local partition_string='partition' partition_string_u='Partition'
2961 if [[ $B_IRC == 'true' ]];then
2962 print_screen_output "Sorry, you can't run the help option in an IRC client."
2965 if [[ -n $BSD_TYPE ]];then
2966 partition_string='slice'
2967 partition_string_u='Slice'
2969 # print_lines_basic "0" "" ""
2970 # print_lines_basic "1" "" ""
2971 # print_lines_basic "2" "" ""
2972 # print_screen_output " "
2973 print_lines_basic "0" "" "$SCRIPT_NAME supports the following options. You can combine them, or list them one by one. Examples: $SCRIPT_NAME^-v4^-c6 OR $SCRIPT_NAME^-bDc^6. If you start $SCRIPT_NAME with no arguments, it will show the short form."
2974 print_screen_output " "
2975 print_lines_basic "0" "" "The following options if used without -F, -b, or -v will show just option line(s): A, B, C, D, G, I, M, N, P, R, S, f, i, m, n, o, p, l, u, r, s, t - you can use these alone or together to show just the line(s) you want to see. If you use them with -v^[level], -b or -F, it will show the full output for that line along with the output for the chosen verbosity level."
2976 print_screen_output "- - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
2977 print_screen_output "Output Control Options:"
2978 print_lines_basic "1" "-A" "Audio/sound card information."
2979 print_lines_basic "1" "-b" "Basic output, short form. Like $SCRIPT_NAME^-v^2, only minus hard disk names ."
2980 print_lines_basic "1" "-B" "Battery info, shows charge, condition, plus extra information (if battery present)."
2981 print_lines_basic "1" "-c" "Color schemes. Scheme number is required. Color selectors run a color selector option prior to $SCRIPT_NAME starting which lets you set the config file value for the selection."
2982 print_lines_basic "1" "" "Supported color schemes: 0-$color_scheme_count Example:^$SCRIPT_NAME^-c^11"
2983 print_lines_basic "1" "" "Color selectors for each type display (NOTE: irc and global only show safe color set):"
2984 # print_screen_output " Supported color schemes: 0-$color_scheme_count Example: $SCRIPT_NAME -c 11"
2985 # print_screen_output " Color selectors for each type display (NOTE: irc and global only show safe color set):"
2986 print_lines_basic "2" "94" "Console, out of X"
2987 print_lines_basic "2" "95" "Terminal, running in X - like xTerm"
2988 print_lines_basic "2" "96" "Gui IRC, running in X - like Xchat, Quassel, Konversation etc."
2989 print_lines_basic "2" "97" "Console IRC running in X - like irssi in xTerm"
2990 print_lines_basic "2" "98" "Console IRC not in X"
2991 print_lines_basic "2" "99" "Global - Overrides/removes all settings. Setting specific removes global."
2992 print_lines_basic "1" "-C" "CPU output, including per CPU clockspeed and max CPU speed (if available)."
2993 print_lines_basic "1" "-d" "Optical drive data. Same as -Dd. See also -x and -xx."
2994 print_lines_basic "1" "-D" "Full hard Disk info, not only model, ie: /dev/sda ST380817AS 80.0GB. See also -x and -xx. Disk total used percentage includes swap partition size(s)."
2995 print_lines_basic "1" "-f" "All cpu flags, triggers -C. Not shown with -F to avoid spamming. ARM cpus show 'features'."
2996 print_lines_basic "1" "-F" "Full output for $SCRIPT_NAME. Includes all Upper Case line letters, plus -s and -n. Does not show extra verbose options like -d -f -l -m -o -p -r -t -u -x"
2997 print_lines_basic "1" "-G" "Graphic card information (card, display server type/version, resolution, glx renderer, version)."
2998 print_lines_basic "1" "-i" "Wan IP address, and shows local interfaces (requires ifconfig
2999 network tool). Same as -Nni. Not shown with -F for user security reasons, you shouldn't paste your local/wan IP."
3000 print_lines_basic "1" "-I" "Information: processes, uptime, memory, irc client (or shell type), $SCRIPT_NAME version."
3001 print_lines_basic "1" "-l" "$partition_string_u labels. Default: short $partition_string -P. For full -p output, use: -pl (or -plu)."
3002 print_lines_basic "1" "-m" "Memory (RAM) data. Physical system memory array(s), capacity, how many devices (slots) supported, and individual memory devices (sticks of memory etc). For devices, shows device locator, size, speed, type (like: DDR3). Also see -x, -xx, -xxx"
3003 print_lines_basic "1" "-M" "Machine data. Motherboard, Bios, and if present, System Builder (Like Lenovo). Older systems/kernels without the required /sys data can use dmidecode instead, run as root. Dmidecode can be forced with -! 33"
3004 print_lines_basic "1" "-n" "Advanced Network card information. Same as -Nn. Shows interface, speed, mac id, state, etc."
3005 print_lines_basic "1" "-N" "Network card information. With -x, shows PCI BusID, Port number."
3006 print_lines_basic "1" "-o" "Unmounted $partition_string information (includes UUID and LABEL if available). Shows file system type if you have file installed, if you are root OR if you have added to /etc/sudoers (sudo v. 1.7 or newer) Example:^<username>^ALL^=^NOPASSWD:^/usr/bin/file^"
3007 print_lines_basic "1" "-p" "Full $partition_string information (-P plus all other detected ${partition_string}s)."
3008 print_lines_basic "1" "-P" "Basic $partition_string information (shows what -v^4 would show, but without extra data). Shows, if detected: / /boot /home /tmp /usr /var. Use -p to see all mounted ${partition_string}s."
3009 print_lines_basic "1" "-r" "Distro repository data. Supported repo types: APT; PACMAN; PISI; PORTAGE; PORTS (BSDs); SLACKPKG; URPMQ; YUM; ZYPP."
3010 print_lines_basic "1" "-R" "RAID data. Shows RAID devices, states, levels, and components, and extra data with -x/-xx. md-raid: If device is resyncing, shows resync progress line as well."
3011 print_lines_basic "1" "-s" "Sensors output (if sensors installed/configured): mobo/cpu/gpu temp; detected fan speeds. Gpu temp only for Fglrx/Nvidia drivers. Nvidia shows screen number for > 1 screens."
3012 print_lines_basic "1" "-S" "System information: host name, kernel, desktop environment (if in X), distro"
3013 print_lines_basic "1" "-t" "Processes. Requires extra options: c^(cpu) m^(memory) cm^(cpu+memory). If followed by numbers 1-20, shows that number of processes for each type (default:^$PS_COUNT; if in irc, max:^5): -t^cm10"
3014 print_lines_basic "1" "" "Make sure to have no space between letters and numbers (-t^cm10 - right, -t^cm^10 - wrong)."
3015 print_lines_basic "1" "-u" "$partition_string_u UUIDs. Default: short $partition_string -P. For full -p output, use: -pu (or -plu)."
3016 print_lines_basic "1" "-v" "Script verbosity levels. Verbosity level number is required. Should not be used with -b or -F"
3017 print_lines_basic "1" "" "Supported levels: 0-$VERBOSITY_LEVELS Example: $SCRIPT_NAME^-v^4"
3018 print_lines_basic "2" "0" "Short output, same as: $SCRIPT_NAME"
3019 print_lines_basic "2" "1" "Basic verbose, -S + basic CPU + -G + basic Disk + -I."
3020 print_lines_basic "2" "2" "Networking card (-N), Machine (-M) data, if present, Battery (-B), basic hard disk data (names only), and, if present, basic raid (devices only, and if inactive, notes that). similar to: $SCRIPT_NAME^-b"
3021 print_lines_basic "2" "3" "Advanced CPU (-C), battery, network (-n) data, and switches on -x advanced data option."
3022 print_lines_basic "2" "4" "$partition_string_u size/filled data (-P) for (if present): /, /home, /var/, /boot. Shows full disk data (-D)."
3023 print_lines_basic "2" "5" "Audio card (-A); sensors^(-s), memory/ram^(-m), $partition_string label^(-l) and UUID^(-u), short form of optical drives, standard raid data (-R)."
3024 print_lines_basic "2" "6" "Full $partition_string (-p), unmounted $partition_string (-o), optical drive (-d), full raid; triggers -xx."
3025 print_lines_basic "2" "7" "Network IP data (-i); triggers -xxx."
3027 # if distro maintainers don't want the weather feature disable it
3028 if [[ $B_ALLOW_WEATHER == 'true' ]];then
3029 print_lines_basic "1" "-w" "Local weather data/time. To check an alternate location, see: -W^<location>. For extra weather data options see -x, -xx, and -xxx."
3030 print_lines_basic "1" "-W" "<location> Supported options for <location>: postal code; city, state/country; latitude, longitude. Only use if you want the weather somewhere other than the machine running $SCRIPT_NAME. Use only ascii characters, replace spaces in city/state/country names with '+'. Example:^$SCRIPT_NAME^-W^new+york,ny"
3032 print_lines_basic "1" "-x" "Adds the following extra data (only works with verbose or line output, not short form):"
3033 print_lines_basic "2" "-B" "Vendor/model, status (if available)"
3034 print_lines_basic "2" "-C" "CPU Flags, Bogomips on Cpu;"
3035 print_lines_basic "2" "-d" "Extra optical drive data; adds rev version to optical drive."
3036 print_lines_basic "2" "-D" "Hdd temp with disk data if you have hddtemp installed, if you are root OR if you have added to /etc/sudoers (sudo v. 1.7 or newer) Example:^<username>^ALL^=^NOPASSWD:^/usr/sbin/hddtemp"
3037 print_lines_basic "2" "-G" "Direct rendering status for Graphics (in X)."
3038 print_lines_basic "2" "-G" "(for single gpu, nvidia driver) screen number gpu is running on."
3039 print_lines_basic "2" "-i" "IPv6 as well for LAN interface (IF) devices."
3040 print_lines_basic "2" "-I" "System GCC, default. With -xx, also show other installed GCC versions. If running in console, not in IRC client, shows shell version number, if detected. Init/RC Type and runlevel (if available)."
3041 print_lines_basic "2" "-m" "Part number; Max memory module size (if available)."
3042 print_lines_basic "2" "-N -A" "Version/port(s)/driver version (if available) for Network/Audio;"
3043 print_lines_basic "2" "-N -A -G" "Network, audio, graphics, shows PCI Bus ID/Usb ID number of card."
3044 print_lines_basic "2" "-R" "md-raid: Shows component raid id. Adds second RAID Info line: raid level; report on drives (like 5/5); blocks; chunk size; bitmap (if present). Resync line, shows blocks synced/total blocks. zfs-raid: Shows raid array full size; available size; portion allocated to RAID"
3045 print_lines_basic "2" "-S" "Desktop toolkit if avaliable (GNOME/XFCE/KDE only); Kernel gcc version"
3046 print_lines_basic "2" "-t" "Memory use output to cpu (-xt c), and cpu use to memory (-xt m)."
3047 if [[ $B_ALLOW_WEATHER == 'true' ]];then
3048 print_lines_basic "2" "-w -W" "Wind speed and time zone (-w only)."
3050 print_lines_basic "1" "-xx" "Show extra, extra data (only works with verbose or line output, not short form):"
3051 print_lines_basic "2" "-A" "Chip vendor:product ID for each audio device."
3052 print_lines_basic "2" "-B" "serial number, voltage (if available)."
3053 print_lines_basic "2" "-C" "Minimum CPU speed, if available."
3054 print_lines_basic "2" "-D" "Disk serial number."
3055 print_lines_basic "2" "-G" "Chip vendor:product ID for each video card."
3056 print_lines_basic "2" "-I" "Other detected installed gcc versions (if present). System default runlevel. Adds parent program (or tty) for shell info if not in IRC (like Konsole or Gterm). Adds Init/RC (if found) version number."
3057 print_lines_basic "2" "-m" "Manufacturer, Serial Number, single/double bank (if found)."
3058 print_lines_basic "2" "-M" "Chassis information, bios rom size (dmidecode only), if data for either is available."
3059 print_lines_basic "2" "-N" "Chip vendor:product ID for each nic."
3060 print_lines_basic "2" "-R" "md-raid: Superblock (if present); algorythm, U data. Adds system info line (kernel support,read ahead, raid events). If present, adds unused device line. Resync line, shows progress bar."
3061 print_lines_basic "2" "-S" "Display manager (dm) in desktop output, if in X (like kdm, gdm3, lightdm)."
3062 if [[ $B_ALLOW_WEATHER == 'true' ]];then
3063 print_lines_basic "2" "-w -W" "Humidity, barometric pressure."
3065 print_lines_basic "2" "-@ 11-14" "Automatically uploads debugger data tar.gz file to ftp.techpatterns.com. EG: $SCRIPT_NAME^-xx@14"
3066 print_lines_basic "1" "-xxx" "Show extra, extra, extra data (only works with verbose or line output, not short form):"
3067 print_lines_basic "2" "-B" "chemistry, cycles, location (if available)."
3068 print_lines_basic "2" "-m" "Width of memory bus, data and total (if present and greater than data); Detail, if present, for Type; module voltage, if available."
3069 print_lines_basic "2" "-S" "Panel/shell information in desktop output, if in X (like gnome-shell, cinnamon, mate-panel)."
3070 if [[ $B_ALLOW_WEATHER == 'true' ]];then
3071 print_lines_basic "2" "-w -W" "Location (uses -z/irc filter), weather observation time, wind chill, heat index, dew point (shows extra lines for data where relevant)."
3073 print_lines_basic "1" "-y" "Required extra option: integer, 80 or greater. Set the output line width max. Overrides IRC/Terminal settings or actual widths. If used with -h, put -y option first. Example:^inxi^-y^130"
3074 print_lines_basic "1" "-z" "Security filters for IP/Mac addresses, location, user home directory name. Default on for irc clients."
3075 print_lines_basic "1" "-Z" "Absolute override for output filters. Useful for debugging networking issues in irc for example."
3076 print_screen_output " "
3077 print_screen_output "Additional Options:"
3078 print_lines_basic "4" "-h --help" "This help menu."
3079 print_lines_basic "4" "-H" "This help menu, plus developer options. Do not use dev options in normal operation!"
3080 print_lines_basic "4" "--recommends" "Checks $SCRIPT_NAME application dependencies + recommends, and directories, then shows what package(s) you need to install to add support for that feature. "
3081 if [[ $B_ALLOW_UPDATE == 'true' ]];then
3082 print_lines_basic "4" "-U" "Auto-update script. Will also install/update man page. Note: if you installed as root, you must be root to update, otherwise user is fine. Man page installs require root user mode."
3084 print_lines_basic "4" "-V --version" "$SCRIPT_NAME version information. Prints information then exits."
3085 print_screen_output " "
3086 print_screen_output "Debugging Options:"
3087 print_lines_basic "1" "-%" "Overrides defective or corrupted data."
3088 print_lines_basic "1" "-@" "Triggers debugger output. Requires debugging level 1-14 (8-10 - logging of data). Less than 8 just triggers $SCRIPT_NAME debugger output on screen."
3089 print_lines_basic "2" "1-7" "On screen debugger output"
3090 print_lines_basic "2" "8" "Basic logging"
3091 print_lines_basic "2" "9" "Full file/sys info logging"
3092 print_lines_basic "2" "10" "Color logging."
3093 print_lines_basic "1" "" "The following create a tar.gz file of system data, plus collecting the inxi output to file. To automatically upload debugger data tar.gz file to ftp.techpatterns.com: inxi^-xx@^<11-14>"
3094 print_lines_basic "1" "" "For alternate ftp upload locations: Example:^inxi^-!^ftp.yourserver.com/incoming^-xx@^14"
3095 print_lines_basic "2" "11" "With data file of xiin read of /sys."
3096 print_lines_basic "2" "12" "With xorg conf and log data, xrandr, xprop, xdpyinfo, glxinfo etc."
3097 print_lines_basic "2" "13" "With data from dev, disks, ${partition_string}s, etc., plus xiin data file."
3098 print_lines_basic "2" "14" "Everything, full data collection."
3099 print_screen_output " "
3100 print_screen_output "Advanced Options:"
3101 print_lines_basic "1" "-! 31" "Turns off hostname in output. Useful if showing output from servers etc."
3102 print_lines_basic "1" "-! 32" "Turns on hostname in output. Overrides global B_SHOW_HOST='false'"
3103 print_lines_basic "1" "-! 33" "Forces use of dmidecode data instead of /sys where relevant (-M)."
3105 if [[ $1 == 'full' ]];then
3106 print_screen_output " "
3107 print_screen_output "Developer and Testing Options (Advanced):"
3108 print_lines_basic "1" "-! 1" "Sets testing flag B_TESTING_1='true' to trigger testing condition 1."
3109 print_lines_basic "1" "-! 2" "Sets testing flag B_TESTING_2='true' to trigger testing condition 2."
3110 print_lines_basic "1" "-! 3" "Sets flags B_TESTING_1='true' and B_TESTING_2='true'."
3111 if [[ $B_ALLOW_UPDATE == 'true' ]];then
3112 print_lines_basic "1" "-! 10" "Triggers an update from the primary dev download server instead of svn."
3113 print_lines_basic "1" "-! 11" "Triggers an update from svn branch one - if present, of course."
3114 print_lines_basic "1" "-! 12" "Triggers an update from svn branch two - if present, of course."
3115 print_lines_basic "1" "-! 13" "Triggers an update from svn branch three - if present, of course."
3116 print_lines_basic "1" "-! 14" "Triggers an update from svn branch four - if present, of course."
3117 print_lines_basic "1" "-! 15" "Triggers an update from svn branch BSD - if present, of course."
3118 print_lines_basic "1" "-! 16" "Triggers an update from svn branch GNUBSD - if present, of course."
3119 print_lines_basic "1" "-! " "<http://......> Triggers an update from whatever server you list."
3120 print_lines_basic "1" "" "Example: inxi^-!^http://yourserver.com/testing/inxi"
3122 print_lines_basic "1" "-! " "<ftp.......> Changes debugging data ftp upload location to whatever you enter here. Only used together with -xx@^11-14, and must be used in front of that."
3123 print_lines_basic "1" "" "Example: inxi^-!^ftp.yourserver.com/incoming^-xx@^14"
3125 print_screen_output " "
3128 # uses $TERM_COLUMNS to set width using $COLS_MAX as max width
3129 # IMPORTANT: minimize use of subshells here or the output is too slow
3130 # IMPORTANT: each text chunk must be a continuous line, no line breaks. For anyone who uses a
3131 # code editor that can't do visual (not hard coded) line wrapping, upgrade to one that can.
3132 # args: $1 - 0 1 2 3 4 for indentation level; $2 -line starter, like -m; $3 - content of block.
3135 local line_width=$COLS_MAX
3136 local print_string='' indent_inner='' indent_full='' indent_x=''
3137 local indent_working='' indent_working_full=''
3138 local line_starter='' line_1_starter='' line_x_starter=''
3139 # note: to create a padded string below
3140 local fake_string=' ' temp_count='' line_count='' spacer=''
3141 local indent_main=6 indent_x='' b_indent_x='true'
3144 # for no options, start at left edge
3150 1) indent_full=$indent_main
3152 if [[ $temp_count -le $indent_full ]];then
3153 indent_working=$indent_full
3155 indent_working=$temp_count #$(( $temp_count + 1 ))
3157 line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_working\}$/& /;ta" <<< $2 )"
3159 # first left pad 2 and 3, then right pad them
3160 2) indent_full=$(( $indent_main + 6 ))
3163 if [[ $temp_count -le $indent_inner ]];then
3164 indent_working=$indent_inner
3165 #indent_working_full=$indent_full
3167 indent_working=$(( $temp_count + 1 ))
3168 #indent_working_full=$(( $indent_full - $indent_inner - 1 ))
3170 line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_working\}$/& /;ta" <<< $2 )"
3171 line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_full\}$/ &/;ta" <<< "$line_1_starter" )"
3173 3) indent_full=$(( $indent_main + 8 ))
3176 if [[ $temp_count -le $indent_inner ]];then
3177 indent_working=$indent_inner
3179 indent_working=$(( $temp_count + 1 ))
3181 line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_working\}$/& /;ta" <<< $2 )"
3182 line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_full\}$/ &/;ta" <<< "$line_1_starter" )"
3185 4) indent_full=$(( $indent_main + 8 ))
3187 if [[ $temp_count -lt $indent_full ]];then
3188 indent_working=$indent_full
3190 indent_working=$temp_count #$(( $temp_count + 1 ))
3192 line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_working\}$/& /;ta" <<< $2 )"
3196 if [[ $b_indent_x == 'true' ]];then
3197 indent_x=$(( $indent_full + 1 ))
3198 line_x_starter="$(printf "%${indent_x}s" '')"
3201 line_count=$(( $line_width - $indent_full ))
3203 # bash loop is slow, only run this if required
3204 if [[ ${#3} -gt $line_count ]];then
3207 temp_string="$print_string$spacer$word"
3209 if [[ ${#temp_string} -lt $line_count ]];then
3210 print_string=$temp_string # lose any white space start/end
3211 # echo -n $(( $line_width - $indent_full ))
3213 if [[ -n $line_1_starter ]];then
3214 line_starter="$line_1_starter"
3217 line_starter="$line_x_starter"
3219 # clean up forced connections, ie, stuff we don't want wrapping
3220 print_string=${print_string//\^/ }
3221 print_screen_output "$line_starter$print_string"
3222 print_string="$word$spacer" # needed to handle second word on new line
3231 # print anything left over
3232 if [[ -n $print_string ]];then
3233 if [[ -n $line_1_starter ]];then
3234 line_starter="$line_1_starter"
3237 line_starter="$line_x_starter"
3239 print_string=${print_string//\^/ }
3240 print_screen_output "$line_starter$print_string"
3243 # print_lines_basic '1' '-m' 'let us teest this string and lots more and stuff and more stuff and x is wy and z is x and fred is dead and gus is alive an yes we have to go now'
3244 # print_lines_basic '2' '7' 'and its substring this string and lots more and stuff and more stuff and x is wy and z is x and fred is dead and gus is alive an yes we have to go now'
3245 # print_lines_basic '2' '12' 'and its sss substring'
3246 # print_lines_basic '3' '12' 'and its sss substring this string and lots more and stuff and more stuff and x is wy and z is x and fred is dead and gus is alive an yes we have to go now'
3249 ## print out version information for -V/--version
3250 print_version_info()
3252 # if not in PATH could be either . or directory name, no slash starting
3253 local script_path=$SCRIPT_PATH script_symbolic_start=''
3254 if [[ $script_path == '.' ]];then
3255 script_path=$( pwd )
3256 elif [[ -z $( grep '^/' <<< "$script_path" ) ]];then
3257 script_path="$( pwd )/$script_path"
3259 # handle if it's a symbolic link, rare, but can happen with script directories in irc clients
3260 # which would only matter if user starts inxi with -! 30 override in irc client
3261 if [[ -L $script_path/$SCRIPT_NAME ]];then
3262 script_symbolic_start=$script_path/$SCRIPT_NAME
3263 script_path=$( readlink $script_path/$SCRIPT_NAME )
3264 script_path=$( dirname $script_path )
3266 local last_modified=$( parse_version_data 'date' )
3267 local year_modified=$( gawk '{print $NF}' <<< "$last_modified" )
3269 print_screen_output "$SCRIPT_NAME $SCRIPT_VERSION_NUMBER-$SCRIPT_PATCH_NUMBER ($last_modified)"
3270 if [[ $B_IRC == 'false' ]];then
3271 print_screen_output "Program Location: $script_path"
3272 if [[ -n $script_symbolic_start ]];then
3273 print_screen_output "Started via symbolic link: $script_symbolic_start"
3275 print_lines_basic "0" "" "Website:^https://github.com/smxi/inxi^or^http://smxi.org/"
3276 print_lines_basic "0" "" "IRC:^irc.oftc.net channel:^#smxi"
3277 print_lines_basic "0" "" "Forums:^http://techpatterns.com/forums/forum-33.html"
3278 print_screen_output " "
3279 print_lines_basic "0" "" "$SCRIPT_NAME - the universal, portable, system information tool for console and irc."
3280 print_screen_output " "
3281 print_lines_basic "0" "" "This program started life as a fork of Infobash 3.02: Copyright^(C)^2005-2007^Michiel^de^Boer^a.k.a.^locsmif."
3282 print_lines_basic "0" "" "Subsequent changes and modifications (after Infobash 3.02): Copyright^(C)^2008-${year_modified%%-*}^Harald^Hope,^Scott^Rogers,^aka^h2^&trash80."
3283 print_screen_output " "
3284 print_lines_basic "0" "" "This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. (http://www.gnu.org/licenses/gpl.html)"
3288 ########################################################################
3290 ########################################################################
3292 #### -------------------------------------------------------------------
3293 #### initial startup stuff
3294 #### -------------------------------------------------------------------
3296 # Determine where inxi was run from, set IRC_CLIENT and IRC_CLIENT_VERSION
3300 local Irc_Client_Path='' irc_client_path_lower='' non_native_konvi='' i=''
3301 local B_Non_Native_App='false' pppid='' App_Working_Name=''
3302 local b_qt4_konvi='false' ps_parent=''
3304 if [[ $B_IRC == 'false' ]];then
3306 unset IRC_CLIENT_VERSION
3307 # elif [[ -n $PPID ]];then
3308 elif [[ -n $PPID && -f /proc/$PPID/exe ]];then
3309 if [[ $B_OVERRIDE_FILTER != 'true' ]];then
3310 B_OUTPUT_FILTER='true'
3312 Irc_Client_Path=$( readlink /proc/$PPID/exe )
3313 # Irc_Client_Path=$( ps -p $PPID | gawk '!/[[:space:]]*PID/ {print $5}' )
3314 # echo $( ps -p $PPID )
3315 irc_client_path_lower=$( tr '[A-Z]' '[a-z]' <<< $Irc_Client_Path )
3316 App_Working_Name=${irc_client_path_lower##*/}
3317 # handles the xchat/sh/bash/dash cases, and the konversation/perl cases, where clients
3318 # report themselves as perl or unknown shell. IE: when konversation starts inxi
3319 # from inside itself, as a script, the parent is konversation/xchat, not perl/bash etc
3320 # note: perl can report as: perl5.10.0, so it needs wildcard handling
3321 case $App_Working_Name in
3322 # bsd will never use this section
3323 bash|dash|sh|python*|perl*) # We want to know who wrapped it into the shell or perl.
3324 if [[ $BSD_TYPE != 'bsd' ]];then
3325 pppid=$( ps -p $PPID -o ppid --no-headers 2>/dev/null | gawk '{print $NF}' )
3327 # without --no-headers we need the second line
3328 pppid=$( ps -p $PPID -o ppid 2>/dev/null | gawk '$1 ~ /^[0-9]+/ {print $5}' )
3330 if [[ -n $pppid && -f /proc/$pppid/exe ]];then
3331 Irc_Client_Path="$( readlink /proc/$pppid/exe )"
3332 irc_client_path_lower=$( tr '[A-Z]' '[a-z]' <<< $Irc_Client_Path )
3333 App_Working_Name=${irc_client_path_lower##*/}
3334 B_Non_Native_App='true'
3338 # sets version number if it can find it
3339 get_irc_client_version
3341 ## lets look to see if qt4_konvi is the parent. There is no direct way to tell, so lets infer it.
3342 ## because $PPID does not work with qt4_konvi, the above case does not work
3343 if [[ $B_OVERRIDE_FILTER != 'true' ]];then
3344 B_OUTPUT_FILTER='true'
3346 b_qt4_konvi=$( is_this_qt4_konvi )
3347 if [[ $b_qt4_konvi == 'true' ]];then
3349 IRC_CLIENT='Konversation'
3350 IRC_CLIENT_VERSION=" $( konversation -v | gawk '
3352 for ( i=2; i<=NF; i++ ) {
3363 # this should handle certain cases where it's ssh or some other startup tool
3364 # that falls through all the other tests. Also bsd irc clients will land here
3365 if [[ $BSD_TYPE != 'bsd' ]];then
3366 App_Working_Name=$(ps -p $PPID --no-headers 2>/dev/null | gawk '{print $NF}' )
3368 # without --no-headers we need the second line
3369 App_Working_Name=$(ps -p $PPID 2>/dev/null | gawk '$1 ~ /^[0-9]+/ {print $5}' )
3372 if [[ -n $App_Working_Name ]];then
3373 Irc_Client_Path=$App_Working_Name
3374 irc_client_path_lower=$( tr '[A-Z]' '[a-z]' <<< $Irc_Client_Path )
3375 App_Working_Name=${irc_client_path_lower##*/}
3376 B_Non_Native_App='false'
3377 get_irc_client_version
3378 if [[ -z $IRC_CLIENT ]];then
3379 IRC_CLIENT=$App_Working_Name
3382 IRC_CLIENT="PPID=\"$PPID\" - empty?"
3383 unset IRC_CLIENT_VERSION
3388 log_function_data "IRC_CLIENT: $IRC_CLIENT :: IRC_CLIENT_VERSION: $IRC_CLIENT_VERSION :: PPID: $PPID"
3391 # note: all variables set in caller so no need to pass
3392 get_irc_client_version()
3395 # replacing loose detection with tight detection, bugs will be handled with app names
3397 case $App_Working_Name in
3398 # check for shell first
3400 unset IRC_CLIENT_VERSION
3401 IRC_CLIENT="Shell wrapper"
3403 # now start on irc clients, alphabetically
3405 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk '
3408 gsub(/[()]|bitchx-/,"",a)
3418 B_CONSOLE_IRC='true'
3422 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
3425 B_CONSOLE_IRC='true'
3429 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
3435 # the hexchat author decided to make --version/-v return a gtk dialogue box, lol...
3436 # so we need to read the actual config file for hexchat. Note that older hexchats
3437 # used xchat config file, so test first for default, then legacy. Because it's possible
3438 # for this file to be use edited, doing some extra checks here.
3439 if [[ -f ~/.config/hexchat/hexchat.conf ]];then
3440 file_data="$( cat ~/.config/hexchat/hexchat.conf )"
3441 elif [[ -f ~/.config/hexchat/xchat.conf ]];then
3442 file_data="$( cat ~/.config/hexchat/xchat.conf )"
3444 if [[ -n $file_data ]];then
3445 IRC_CLIENT_VERSION=$( gawk '
3450 /^[[:space:]]*version/ {
3451 # get rid of the space if present
3452 gsub(/[[:space:]]*/, "", $2 )
3454 exit # usually this is the first line, no point in continuing
3455 }' <<< "$file_data" )
3457 IRC_CLIENT_VERSION=" $IRC_CLIENT_VERSION"
3459 IRC_CLIENT_VERSION=' N/A'
3461 IRC_CLIENT="HexChat"
3464 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
3467 B_CONSOLE_IRC='true'
3471 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
3474 B_CONSOLE_IRC='true'
3477 konversation) ## konvi < 1.2 (qt4)
3478 # this is necessary to avoid the dcop errors from starting inxi as a /cmd started script
3479 if [[ $B_Non_Native_App == 'true' ]];then ## true negative is confusing
3481 else # if native app
3484 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk '
3486 for ( i=2; i<=NF; i++ ) {
3496 T=($IRC_CLIENT_VERSION)
3497 if [[ ${T[0]} == *+* ]];then
3498 # < Sho_> locsmif: The version numbers of SVN versions look like this:
3499 # "<version number of last release>+ #<build number", i.e. "1.0+ #3177" ...
3500 # for releases we remove the + and build number, i.e. "1.0" or soon "1.0.1"
3501 IRC_CLIENT_VERSION=" CVS $IRC_CLIENT_VERSION"
3504 IRC_CLIENT_VERSION=" ${T[0]}"
3507 # Remove any dots except the first, and make sure there are no trailing zeroes,
3508 T2=$( echo "$T2" | gawk '{
3514 # Since Konversation 1.0, the DCOP interface has changed a bit: dcop "$DCPORT" Konversation ..etc
3515 # becomes : dcop "$DCPORT" default ... or dcop "$DCPORT" irc ..etc. So we check for versions smaller
3516 # than 1 and change the DCOP parameter/object accordingly.
3517 if [[ $T2 -lt 1 ]];then
3518 DCOPOBJ="Konversation"
3520 IRC_CLIENT="Konversation"
3523 IRC_CLIENT_VERSION=" $( kopete -v | gawk '
3531 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v 2>&1 | gawk '{
3532 for ( i=2; i<=NF; i++) {
3545 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
3550 # possible failure of wildcard so make it explicit
3552 # sample: quassel -v
3553 ## Qt: 4.5.0 - in Qt4 the output came from src/common/quassel.cpp
3554 # KDE: 4.2.65 (KDE 4.2.65 (KDE 4.3 >= 20090226))
3555 # Quassel IRC: v0.4.0 [+60] (git-22effe5)
3556 # note: early < 0.4.1 quassels do not have -v
3557 ## Qt: 5: sample: quassel -v
3558 # quassel v0.13-pre (0.12.0+5 git-8e2f578)
3559 # because in Qt5 the internal CommandLineParser is used
3560 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v 2>/dev/null | gawk '
3570 /^quassel\s[v]?[0-9]/ {
3574 # this handles pre 0.4.1 cases with no -v
3575 if ( clientVersion == "" ) {
3576 clientVersion = "(pre v0.4.1)?"
3580 # now handle primary, client, and core. quasselcore doesn't actually
3581 # handle scripts with exec, but it's here just to be complete
3582 case $App_Working_Name in
3584 IRC_CLIENT="Quassel [M]"
3587 IRC_CLIENT="Quassel"
3590 IRC_CLIENT="Quassel (core)"
3594 gribble|limnoria|supybot)
3595 IRC_CLIENT_VERSION=" $( get_program_version 'supybot' '^Supybot' '2' )"
3596 if [[ -n $IRC_CLIENT_VERSION ]];then
3597 if [[ -n ${IRC_CLIENT_VERSION/*gribble*/} || $App_Working_Name == 'gribble' ]];then
3598 IRC_CLIENT="Gribble"
3599 elif [[ -n ${IRC_CLIENT_VERSION/*limnoria*/} || $App_Working_Name == 'limnoria' ]];then
3600 IRC_CLIENT="Limnoria"
3602 IRC_CLIENT="Supybot"
3606 weechat|weechat-curses)
3607 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v ) "
3608 B_CONSOLE_IRC='true'
3609 IRC_CLIENT="WeeChat"
3612 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
3615 IRC_CLIENT="X-Chat-Gnome"
3618 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
3623 # then do some perl type searches, do this last since it's a wildcard search
3625 unset IRC_CLIENT_VERSION
3626 # KSirc is one of the possibilities now. KSirc is a wrapper around dsirc, a perl client
3628 for (( i=0; i <= $CMDL_MAX; i++ ))
3630 case ${A_CMDL[i]} in
3633 # Dynamic runpath detection is too complex with KSirc, because KSirc is started from
3634 # kdeinit. /proc/<pid of the grandparent of this process>/exe is a link to /usr/bin/kdeinit
3635 # with one parameter which contains parameters separated by spaces(??), first param being KSirc.
3636 # Then, KSirc runs dsirc as the perl irc script and wraps around it. When /exec is executed,
3637 # dsirc is the program that runs inxi, therefore that is the parent process that we see.
3638 # You can imagine how hosed I am if I try to make inxi find out dynamically with which path
3639 # KSirc was run by browsing up the process tree in /proc. That alone is straightjacket material.
3640 # (KSirc sucks anyway ;)
3641 IRC_CLIENT_VERSION=" $( ksirc -v | gawk '
3650 B_CONSOLE_IRC='true'
3651 set_perl_python_client_data "$App_Working_Name"
3654 # B_CONSOLE_IRC='true' # are there even any python type console irc clients? check.
3655 set_perl_python_client_data "$App_Working_Name"
3657 # then unset, set unknown data
3659 IRC_CLIENT="Unknown : ${Irc_Client_Path##*/}"
3660 unset IRC_CLIENT_VERSION
3663 if [[ $SHOW_IRC -lt 2 ]];then
3664 unset IRC_CLIENT_VERSION
3668 # args: $1 - App_Working_Name
3669 set_perl_python_client_data()
3671 if [[ -z $IRC_CLIENT_VERSION ]];then
3673 # this is a hack to try to show konversation if inxi is running but started via /cmd
3674 # OR via script shortcuts, both cases in fact now
3675 if [[ $B_RUNNING_IN_DISPLAY == 'true' && -z ${Ps_aux_Data/*konversation*/} ]];then
3676 IRC_CLIENT='Konversation'
3677 version=$( get_program_version 'konversation' '^konversation' '2' )
3678 B_CONSOLE_IRC='false'
3679 ## NOTE: supybot only appears in ps aux using 'SHELL' command; the 'CALL' command
3680 ## gives the user system irc priority, and you don't see supybot listed, so use SHELL
3681 elif [[ $B_RUNNING_IN_DISPLAY == 'false' && -z ${Ps_aux_Data/*supybot*/} ]];then
3682 version=$( get_program_version 'supybot' '^Supybot' '2' )
3683 if [[ -n $version ]];then
3684 IRC_CLIENT_VERSION=" $version"
3685 if [[ -z ${version/*gribble*/} ]];then
3686 IRC_CLIENT='Gribble'
3687 elif [[ -z ${version/*limnoria*/} ]];then
3688 IRC_CLIENT='Limnoria'
3690 IRC_CLIENT='Supybot'
3693 IRC_CLIENT='Supybot'
3694 # currently all use the same actual app name, this will probably change.
3696 B_CONSOLE_IRC='true'
3698 IRC_CLIENT="Unknown $1 client"
3700 if [[ -n $version ]];then
3701 IRC_CLIENT_VERSION=" $version"
3706 ## try to infer the use of Konversation >= 1.2, which shows $PPID improperly
3707 ## no known method of finding Kovni >= 1.2 as parent process, so we look to see if it is running,
3708 ## and all other irc clients are not running. As of 2014-03-25 this isn't used in my cases
3711 local konvi_qt4_client='' konvi_dbus_exist='' konvi_pid='' konvi_home_dir=''
3712 local konvi='' b_is_qt4=''
3714 # fringe cases can throw error, always if untested app, use 2>/dev/null after testing if present
3715 if [[ $B_QDBUS == 'true' ]];then
3716 konvi_dbus_exist=$( qdbus 2>/dev/null | grep "org.kde.konversation" )
3718 # sabayon uses /usr/share/apps/konversation as path
3719 if [[ -n $konvi_dbus_exist ]] && [[ -e /usr/share/kde4/apps/konversation || -e /usr/share/apps/konversation ]]; then
3720 konvi_pid=$( ps -A | gawk 'BEGIN{IGNORECASE=1} /konversation/ { print $1 }' )
3721 konvi_home_dir=$( readlink /proc/$konvi_pid/exe )
3722 konvi=$( echo $konvi_home_dir | sed "s/\// /g" )
3725 if [[ ${konvi[2]} == 'konversation' ]];then
3726 # note: we need to change this back to a single dot number, like 1.3, not 1.3.2
3727 konvi_qt4_client=$( konversation -v | grep -i 'konversation' | \
3728 gawk '{ print $2 }' | cut -d '.' -f 1,2 )
3729 if [[ $konvi_qt4_client > 1.1 ]]; then
3737 log_function_data "b_is_qt4: $b_is_qt4"
3739 ## for testing this module
3740 #qdbus org.kde.konversation /irc say $1 $2 "getpid_dir: $konvi_qt4 qt4_konvi: $konvi_qt4_ver verNum: $konvi_qt4_ver_num pid: $konvi_pid ppid: $PPID konvi_home_dir: ${konvi[2]}"
3743 # This needs some cleanup and comments, not quite understanding what is happening, although generally output is known
3744 # Parse the null separated commandline under /proc/<pid passed in $1>/cmdline
3751 if [[ ! -e /proc/$ppid/cmdline ]];then
3755 ##print_screen_output "Marker"
3756 ##print_screen_output "\$ppid='$ppid' -=- $(< /proc/$ppid/cmdline)"
3758 ## note: need to figure this one out, and ideally clean it up and make it readable
3759 while read -d $'\0' L && [[ $i -lt 32 ]]
3761 A_CMDL[i++]="$L" ## note: make sure this is valid - What does L mean? ##
3762 done < /proc/$ppid/cmdline
3763 ##print_screen_output "\$i='$i'"
3764 if [[ $i -eq 0 ]];then
3765 A_CMDL[0]=$(< /proc/$ppid/cmdline)
3766 if [[ -n ${A_CMDL[0]} ]];then
3771 log_function_data "CMDL_MAX: $CMDL_MAX"
3775 #### -------------------------------------------------------------------
3777 #### -------------------------------------------------------------------
3778 ## create array of sound cards installed on system, and if found, use asound data as well
3782 local i='' alsa_data='' audio_driver='' device_count='' a_temp=''
3785 # this first step handles the drivers for cases where the second step fails to find one
3786 device_count=$( echo "$Lspci_v_Data" | grep -iEc '(multimedia audio controller|audio device)' )
3787 if [[ $device_count -eq 1 ]] && [[ $B_ASOUND_DEVICE_FILE == 'true' ]];then
3788 audio_driver=$( gawk -F ']: ' '
3792 # filtering out modems and usb devices like webcams, this might get a
3793 # usb audio card as well, this will take some trial and error
3794 $0 !~ /modem|usb|webcam/ {
3795 driver=gensub( /^(.+)( - )(.+)$/, "\\1", 1, $2 )
3796 gsub(/^ +| +$/,"",driver)
3797 if ( driver != "" ){
3800 }' $FILE_ASOUND_DEVICE )
3801 log_function_data 'cat' "$FILE_ASOUND_DEVICE"
3804 # this is to safeguard against line breaks from results > 1, which if inserted into following
3805 # array will create a false array entry. This is a hack, not a permanent solution.
3806 audio_driver=$( echo $audio_driver )
3807 # now we'll build the main audio data, card name, driver, and port. If no driver is found,
3808 # and if the first method above is not null, and one card is found, it will use that instead.
3809 A_AUDIO_DATA=( $( echo "$Lspci_v_Data" | gawk -F ': ' -v audioDriver="$audio_driver" '
3813 /multimedia audio controller|audio device/ {
3814 audioCard=gensub(/^[0-9a-f:\.]+ [^:]+: (.+)$/,"\\1","g",$0)
3815 # The doublequotes are necessary because of the pipes in the variable.
3816 gsub(/'"$BAN_LIST_NORMAL"'/, "", audioCard)
3817 gsub(/'"$BAN_LIST_ARRAY"'/, " ", audioCard)
3818 gsub(/^ +| +$/, "", audioCard)
3819 gsub(/ [ \t]+/, " ", audioCard)
3820 aPciBusId[audioCard] = gensub(/(^[0-9a-f:\.]+) [^:]+: .+$/,"\\1","g",$0)
3823 # loop until you get to the end of the data block
3824 while (getline && !/^$/) {
3825 gsub(/'"$BAN_LIST_ARRAY"'/, "", $0 )
3826 if (/driver in use/) {
3827 drivers[audioCard] = drivers[audioCard] gensub( /(.*): (.*)/ ,"\\2", "g" ,$0 ) ""
3829 else if (/kernel modules:/) {
3830 modules[audioCard] = modules[audioCard] gensub( /(.*): (.*)/ ,"\\2" ,"g" ,$0 ) ""
3832 else if (/^[[:space:]]*I\/O/) {
3833 portsTemp = gensub(/\t*I\/O ports at ([a-z0-9]+)(| \[.*\])/,"\\1","g",$0)
3834 ports[audioCard] = ports[audioCard] portsTemp " "
3849 if (drivers[i] != "") {
3850 useDrivers=drivers[i]
3855 # little trick here to try to catch the driver if there is
3856 # only one card and it was null, from the first test of asound/cards
3857 if (drivers[i] != "") {
3858 useDrivers=drivers[i]
3860 else if ( audioDriver != "" ) {
3861 useDrivers=audioDriver
3864 if (ports[i] != "") {
3867 if (modules[i] != "" ) {
3868 useModules = modules[i]
3870 if ( aPciBusId[i] != "" ) {
3871 usePciBusId = aPciBusId[i]
3873 # create array primary item for master array
3874 sub( / $/, "", usePorts ) # clean off trailing whitespace
3875 print a[j] "," useDrivers "," usePorts "," useModules "," usePciBusId
3880 # in case of failure of first check do this instead
3881 if [[ ${#A_AUDIO_DATA[@]} -eq 0 ]] && [[ $B_ASOUND_DEVICE_FILE == 'true' ]];then
3882 A_AUDIO_DATA=( $( gawk -F ']: ' '
3886 $1 !~ /modem/ && $2 !~ /modem/ {
3887 card=gensub( /^(.+)( - )(.+)$/, "\\3", 1, $2 )
3888 driver=gensub( /^(.+)( - )(.+)$/, "\\1", 1, $2 )
3892 }' $FILE_ASOUND_DEVICE ) )
3896 # handle cases where card detection fails, like in PS3, where lspci gives no output, or headless boxes..
3897 if [[ ${#A_AUDIO_DATA[@]} -eq 0 ]];then
3898 A_AUDIO_DATA[0]='Failed to Detect Sound Card!'
3900 a_temp=${A_AUDIO_DATA[@]}
3901 log_function_data "A_AUDIO_DATA: $a_temp"
3905 # alsa usb detection by damentz
3907 get_audio_usb_data()
3910 local usb_proc_file='' array_count='' usb_data='' usb_id='' lsusb_data=''
3914 if type -p lsusb &>/dev/null;then
3915 lsusb_data=$( lsusb 2>/dev/null )
3917 log_function_data 'raw' "usb_data:\n$lsusb_data"
3918 if [[ -n $lsusb_data && -d /proc/asound/ ]];then
3919 # for every sound card symlink in /proc/asound - display information about it
3920 for usb_proc_file in /proc/asound/*
3922 # If the file is a symlink, and contains an important usb exclusive file: continue
3923 if [[ -L $usb_proc_file && -e $usb_proc_file/usbid ]]; then
3924 # find the contents of usbid in lsusb and print everything after the 7th word on the
3925 # corresponding line. Finally, strip out commas as they will change the driver :)
3926 usb_id=$( cat $usb_proc_file/usbid )
3927 usb_data=$( grep "$usb_id" <<< "$lsusb_data" )
3928 if [[ -n $usb_data && -n $usb_id ]];then
3936 gsub(/'"$BAN_LIST_ARRAY"'/, " ", $0 )
3937 gsub(/'"$BAN_LIST_NORMAL"'/, "", $0)
3938 gsub(/ [ \t]+/, " ", $0)
3939 for ( i=7; i<= NF; i++ ) {
3940 string = string separator $i
3945 print string ",USB Audio,,," $2 "-" $4 "," $6
3947 }' <<< "$usb_data" )
3949 # this method is interesting, it shouldn't work but it does
3950 #A_AUDIO_DATA=( "${A_AUDIO_DATA[@]}" "$usb_data,USB Audio,," )
3951 # but until we learn why the above worked, I'm using this one, which is safer
3952 if [[ -n $usb_data ]];then
3953 array_count=${#A_AUDIO_DATA[@]}
3954 A_AUDIO_DATA[$array_count]="$usb_data"
3960 a_temp=${A_AUDIO_DATA[@]}
3961 log_function_data "A_AUDIO_DATA: $a_temp"
3966 get_audio_alsa_data()
3969 local alsa_data='' a_temp=''
3971 # now we'll get the alsa data if the file exists
3972 if [[ $B_ASOUND_VERSION_FILE == 'true' ]];then
3981 # some alsa strings have the build date in (...)
3982 # remove trailing . and remove possible second line if compiled by user
3984 gsub(/Driver | [(].*[)]|\.$/,"",$0 )
3985 gsub(/'"$BAN_LIST_ARRAY"'/, " ", $0)
3986 gsub(/^ +| +$/, "", $0)
3987 gsub(/ [ \t]+/, " ", $0)
3988 sub(/Advanced Linux Sound Architecture/, "ALSA", $0)
3989 if ( $1 == "ALSA" ){
3993 print alsa "," version
3994 }' $FILE_ASOUND_VERSION ) )
3996 log_function_data 'cat' "$FILE_ASOUND_VERSION"
3998 a_temp=${A_ALSA_DATA[@]}
3999 log_function_data "A_ALSA_DATA: $a_temp"
4006 local a_temp='' id_file='' count=0
4007 local id_dir='/sys/class/power_supply/'
4008 local ids=$( ls $id_dir 2>/dev/null ) battery_file=''
4010 # ids='BAT0 BAT1 BAT2'
4011 if [[ -n $ids && $B_FORCE_DMIDECODE == 'false' ]];then
4014 battery_file=$id_dir$idx'/uevent'
4015 if [[ -r $battery_file ]];then
4016 # echo $battery_file
4017 count=$(( $count + 1 ))
4028 voltage_min_design=""
4031 charge_full_design=""
4043 gsub(/'"$BAN_LIST_NORMAL"'|,|battery|unknown/, "", $2)
4044 gsub(/^ +| +$/, "", $2)
4046 $1 ~ /^POWER_SUPPLY_NAME$/ {
4049 $1 ~ /^POWER_SUPPLY_STATUS$/ {
4052 $1 ~ /^POWER_SUPPLY$/ {
4055 $1 ~ /^POWER_SUPPLY_TECHNOLOGY$/ {
4058 $1 ~ /^POWER_SUPPLY_CYCLE_COUNT$/ {
4061 $1 ~ /^POWER_SUPPLY_VOLTAGE_MIN_DESIGN$/ {
4062 voltage_min_design = $NF / 1000000
4063 voltage_min_design = sprintf( "%.1f", voltage_min_design )
4065 $1 ~ /^POWER_SUPPLY_VOLTAGE_NOW$/ {
4066 voltage_now = $NF / 1000000
4067 voltage_now = sprintf( "%.1f", voltage_now )
4069 $1 ~ /^POWER_SUPPLY_POWER_NOW$/ {
4072 $1 ~ /^POWER_SUPPLY_ENERGY_FULL_DESIGN$/ {
4073 charge_full_design = $NF / 1000000
4075 $1 ~ /^POWER_SUPPLY_ENERGY_FULL$/ {
4076 charge_full = $NF / 1000000
4078 $1 ~ /^POWER_SUPPLY_ENERGY_NOW$/ {
4079 charge_now = $NF / 1000000
4080 charge_now = sprintf( "%.1f", charge_now )
4082 $1 ~ /^POWER_SUPPLY_CHARGE_FULL_DESIGN$/ {
4083 charge_full_design = $NF / 100000
4085 $1 ~ /^POWER_SUPPLY_CHARGE_FULL$/ {
4086 charge_full = $NF / 100000
4088 $1 ~ /^POWER_SUPPLY_CHARGE_NOW$/ {
4089 charge_now = $NF / 100000
4091 $1 ~ /^POWER_SUPPLY_CAPACITY$/ {
4096 $1 ~ /^POWER_SUPPLY_CAPACITY_LEVEL$/ {
4099 $1 ~ /^POWER_SUPPLY_MODEL_NAME$/ {
4102 $1 ~ /^POWER_SUPPLY_MANUFACTURER$/ {
4105 $1 ~ /^POWER_SUPPLY_SERIAL_NUMBER$/ {
4109 if (charge_now != "" && charge_full != "" ){
4110 capacity = 100*charge_now/charge_full
4111 capacity = sprintf( "%.1f%", capacity )
4113 if (charge_full_design != "" && charge_full != "" ){
4114 of_orig=100*charge_full/charge_full_design
4115 of_orig = sprintf( "%.0f%", of_orig )
4117 if (charge_now != "" ){
4118 charge_now = sprintf( "%.1f", charge_now )
4120 if (charge_full_design != "" ){
4121 charge_full_design = sprintf( "%.1f", charge_full_design )
4123 if ( charge_full != "" ){
4124 charge_full = sprintf( "%.1f", charge_full )
4126 entry = name "," status "," present "," chemistry "," cycles "," voltage_min_design "," voltage_now ","
4127 entry = entry power_now "," charge_full_design "," charge_full "," charge_now "," capacity ","
4128 entry = entry capacity_level "," of_orig "," model "," company "," serial "," location
4130 }' < $battery_file )
4133 A_BATTERY_DATA[$count]=$battery_data
4137 elif [[ $B_FORCE_DMIDECODE == 'true' ]] || [[ ! -d $id_dir && -z $ids ]];then
4139 if [[ -n $DMIDECODE_DATA ]];then
4140 if [[ $DMIDECODE_DATA == 'dmidecode-error-'* ]];then
4141 A_BATTERY_DATA[0]=$DMIDECODE_DATA
4142 # please note: only dmidecode version 2.11 or newer supports consistently the -s flag
4145 # NOTE: this logic has a flaw, which is multiple batteries, which won't work without
4146 # gawk arrays, but sorry, too much of a pain given how little useful data from dmidecode
4147 A_BATTERY_DATA=( $( gawk -F ':' '
4155 voltage_min_design=""
4158 charge_full_design=""
4171 gsub(/'"$BAN_LIST_NORMAL"'|,|battery|unknown/, "", $2)
4172 gsub(/^ +| +$/, "", $1)
4173 gsub(/^ +| +$/, "", $2)
4175 /^Portable Battery/ {
4176 while ( getline && !/^$/ ) {
4177 if ( $1 ~ /^Location/ ) { location=$2 }
4178 if ( $1 ~ /^Manufacturer/ ) { company=$2 }
4179 if ( $1 ~ /^Serial/ ) { serial=$2 }
4180 if ( $1 ~ /^Name/ ) { model=$2 }
4181 if ( $1 ~ /^Design Capacity/ ) {
4182 sub(/^[[:space:]]*mwh/, "", $2)
4183 charge_full_design = $NF / 1000
4184 charge_full_design = sprintf( "%.1f", charge_full_design )
4186 if ( $1 ~ /^Design Voltage/ ) {
4187 sub(/^[[:space:]]*mv/, "", $2)
4188 voltage_min_design = $NF / 1000
4189 voltage_min_design = sprintf( "%.1f", voltage_min_design )
4191 if ( $1 ~ /^SBDS Chemistry/ ) { chemistry=$2 }
4193 testString=company serial model charge_full_design voltage_min_design
4194 if ( testString != "" ) {
4196 exit # exit loop, we are not handling > 1 batteries
4200 if ( bItemFound == "true" ) {
4202 if (charge_now != "" && charge_full != "" ){
4203 capacity = 100*charge_now/charge_full
4204 capacity = sprintf( "%.1f%", capacity )
4206 if (charge_full_design != "" && charge_full != "" ){
4207 of_orig=100*charge_full/charge_full_design
4208 of_orig = sprintf( "%.0f%", of_orig )
4210 entry = name "," status "," present "," chemistry "," cycles "," voltage_min_design "," voltage_now ","
4211 entry = entry power_now "," charge_full_design "," charge_full "," charge_now "," capacity ","
4212 entry = entry capacity_level "," of_orig "," model "," company "," serial "," location
4215 }' <<< "$DMIDECODE_DATA" ) )
4220 # echo $array_string
4222 #echo ${#A_BATTERY_DATA[@]}
4223 a_temp=${A_BATTERY_DATA[@]}
4226 log_function_data "A_BATTERY_DATA: $a_temp"
4230 ## create A_CPU_CORE_DATA, currently with two values: integer core count; core string text
4231 ## return value cpu core count string, this helps resolve the multi redundant lines of old style output
4232 get_cpu_core_count()
4235 local cpu_physical_count='' cpu_core_count='' cpu_type='' cpu_alpha_count='' cores_per_cpu=''
4238 if [[ $B_CPUINFO_FILE == 'true' ]]; then
4239 # load the A_CPU_TYPE_PCNT_CCNT core data array
4240 get_cpu_ht_multicore_smp_data
4241 ## Because of the upcoming release of cpus with core counts over 6, a count of cores is given after Deca (10)
4242 # count the number of processors given
4243 cpu_physical_count=${A_CPU_TYPE_PCNT_CCNT[1]}
4244 cpu_core_count=${A_CPU_TYPE_PCNT_CCNT[2]}
4245 cpu_type=${A_CPU_TYPE_PCNT_CCNT[0]}
4247 # match the numberic value to an alpha value
4248 cpu_alpha_count=$( get_cpu_core_count_alpha "$cpu_core_count" )
4250 # create array, core count integer; core count string
4251 # A_CPU_CORE_DATA=( "$cpu_core_count" "$cpu_alpha_count Core$cpu_type" )
4252 array_data="$cpu_physical_count,$cpu_alpha_count,$cpu_type,$cpu_core_count"
4254 A_CPU_CORE_DATA=( $array_data )
4256 elif [[ -n $BSD_TYPE ]];then
4259 if [[ $BSD_VERSION == 'openbsd' ]];then
4262 cpu_core_count=$( gawk -F "$gawk_fs" -v bsdVersion="$BSD_VERSION" '
4263 # note: on openbsd can also be hw.ncpufound so exit after first
4270 /^machdep.cpu.core_count/ {
4275 }' <<< "$Sysctl_a_Data" )
4276 cores_per_cpu=$( gawk -F "$gawk_fs" '
4277 /^machdep.cpu.cores_per_package/ {
4279 }' <<< "$Sysctl_a_Data" )
4281 if [[ -n $( grep -E '^[0-9]+$' <<< "$cpu_core_count" ) ]];then
4282 cpu_alpha_count=$( get_cpu_core_count_alpha "$cpu_core_count" )
4283 if [[ $cpu_core_count -gt 1 ]];then
4289 if [[ -n $cores_per_cpu ]];then
4290 cpu_physical_count=$(( $cpu_core_count / $cores_per_cpu ))
4291 if [[ $cores_per_cpu -gt 1 ]];then
4294 # do not guess here, only use phys count if it actually exists, otherwise handle in print_cpu..
4295 # this 1 value should not be used for output, and is just to avoid math errors
4297 cpu_physical_count=1
4299 array_data="$cpu_physical_count,$cpu_alpha_count,$cpu_type,$cpu_core_count"
4301 A_CPU_CORE_DATA=( $array_data )
4304 a_temp=${A_CPU_CORE_DATA[@]}
4305 # echo $a_temp :: ${#A_CPU_CORE_DATA[@]}
4306 log_function_data "A_CPU_CORE_DATA: $a_temp"
4310 # args: $1 - integer core count
4311 get_cpu_core_count_alpha()
4314 local cpu_alpha_count=''
4317 1) cpu_alpha_count='Single';;
4318 2) cpu_alpha_count='Dual';;
4319 3) cpu_alpha_count='Triple';;
4320 4) cpu_alpha_count='Quad';;
4321 5) cpu_alpha_count='Penta';;
4322 6) cpu_alpha_count='Hexa';;
4323 7) cpu_alpha_count='Hepta';;
4324 8) cpu_alpha_count='Octa';;
4325 9) cpu_alpha_count='Ennea';;
4326 10) cpu_alpha_count='Deca';;
4327 *) cpu_alpha_count='Multi';;
4330 echo $cpu_alpha_count
4335 ## main cpu data collector
4339 local i='' j='' cpu_array_nu='' a_cpu_working='' multi_cpu='' bits='' a_temp=''
4340 local bsd_cpu_flags='' min_speed='' max_speed=''
4342 if [[ -f /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq ]];then
4343 max_speed=$(cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq)
4344 if [[ -f /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq ]];then
4345 min_speed=$(cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq)
4349 if [[ $B_CPUINFO_FILE == 'true' ]];then
4350 # stop script for a bit to let cpu slow down before parsing cpu /proc file
4354 gawk -v cpuMin="$min_speed" -v cpuMax="$max_speed" -F': ' '
4357 # need to prime nr for arm cpus, which do not have processor number output in some cases
4361 # ARM cpus are erratic in /proc/cpuinfo this hack can sometimes resolve it. Linux only.
4362 sysSpeed="'$(get_cpu_speed_hack)'"
4367 # TAKE STRONGER NOTE: \t+ does NOT always work, MUST be [ \t]+
4368 # TAKE NOTE: \t+ will work for $FILE_CPUINFO, but SOME ARBITRARY FILE used for TESTING might contain SPACES!
4369 # Therefore PATCH to use [ \t]+ when TESTING!
4370 /^processor[ \t]+:/ {
4371 gsub(/'"$BAN_LIST_ARRAY"'/, " ", $NF)
4372 gsub(/^ +| +$/, "", $NF)
4373 if ( $NF ~ "^[0-9]+$" ) {
4377 if ( $NF ~ "^ARM" ) {
4382 cpu[nr, "model"] = $NF
4385 /^model name|^cpu\t+:/ {
4386 gsub(/'"$BAN_LIST_NORMAL"'/, "", $NF )
4387 gsub(/'"$BAN_LIST_CPU"'/, "", $NF )
4388 gsub(/'"$BAN_LIST_ARRAY"'/, " ", $NF)
4389 gsub(/^ +| +$/, "", $NF)
4390 gsub(/ [ \t]+/, " ", $NF)
4391 cpu[nr, "model"] = $NF
4392 if ( $NF ~ "^ARM" ) {
4396 /^cpu MHz|^clock\t+:/ {
4408 gsub(/MHZ/,"",$NF) ## clears out for cell cpu
4409 gsub(/.00[0]+$/,".00",$NF) ## clears out excessive zeros
4410 cpu[nr, "speed"] = $NF
4413 cpu[nr, "cache"] = $NF
4415 /^flags|^features/ {
4416 cpu[nr, "flags"] = $NF
4417 # not all ARM cpus show ARM in model name
4418 if ( $1 ~ /^features/ ) {
4423 cpu[nr, "bogomips"] = $NF
4426 gsub(/genuine|authentic/,"",$NF)
4427 cpu[nr, "vendor"] = tolower( $NF )
4430 #if (!nr) { print ",,,"; exit } # <- should this be necessary or should bash handle that
4431 for ( i = 0; i <= nr; i++ ) {
4432 # note: assuming bogomips for arm at 1 x clock
4433 # http://en.wikipedia.org/wiki/BogoMips ARM could change so watch this
4434 # maybe add: && bArm == "true" but I think most of the bogomips roughly equal cpu speed if not amd/intel
4435 # 2014-04-08: trying to use sysSpeed hack first, that is more accurate anyway.
4436 if ( ( cpu[i, "speed"] == "" && sysSpeed != "" ) || \
4437 ( cpu[i, "speed"] == "" && cpu[i, "bogomips"] != "" && cpu[i, "bogomips"] < 50 ) ) {
4438 cpu[i, "speed"] = sysSpeed
4440 else if ( cpu[i, "bogomips"] != "" && cpu[i, "speed"] == "" ) {
4441 cpu[i, "speed"] = cpu[i, "bogomips"]
4443 print cpu[i, "model"] "," cpu[i, "speed"] "," cpu[i, "cache"] "," cpu[i, "flags"] "," cpu[i, "bogomips"] "," cpu[nr, "vendor"] "," bArm
4451 # create last array index, to be used for min/max output
4452 sub(/\.[0-9]+$/,"",max)
4453 sub(/\.[0-9]+$/,"",speed)
4454 sub(/\.[0-9]+$/,"",min)
4456 print "N/A," min "," max
4459 print speed "," min "," max
4465 log_function_data 'cat' "$FILE_CPUINFO"
4466 elif [[ -n $BSD_TYPE ]];then
4470 a_temp=${A_CPU_DATA[@]}
4471 log_function_data "A_CPU_DATA: $a_temp"
4472 # echo ta: ${a_temp[@]}
4474 # echo getMainCpu: ${[@]}
4476 # this triggers in one and only one case, ARM cpus that have fake bogomips data
4477 get_cpu_speed_hack()
4479 local speed=$( cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq 2>/dev/null )
4481 if [[ -n $speed ]];then
4482 speed=${speed%[0-9][0-9][0-9]} # trim off last 3 digits
4491 local bsd_cpu_flags=$( get_cpu_flags_bsd )
4492 local gawk_fs=': ' cpu_max=''
4494 if [[ $BSD_VERSION == 'openbsd' ]];then
4497 # avoid setting this for systems where you have no read/execute permissions
4498 # might be cases where the dmesg boot file was readable but sysctl perms failed
4499 if [[ -n $Sysctl_a_Data || -n $bsd_cpu_flags ]];then
4500 if [[ -n $Dmesg_Boot_Data ]];then
4501 cpu_max=$( gawk -F ':' '
4505 # NOTE: freebsd may say: 2300-MHz, so check for dash as well
4506 $1 ~ /^(CPU|cpu0)$/ {
4507 if ( $NF ~ /[^0-9\.][0-9\.]+[\-[:space:]]*[MG]Hz/) {
4508 max=gensub(/.*[^0-9\.]([0-9\.]+[\-[:space:]]*[MG]Hz).*/,"\\1",1,$NF)
4510 sub(/[-[:space:]]*MHz/,"",max)
4513 sub(/[-[:space:]]*GHz/,"",max)
4519 }' <<< "$Dmesg_Boot_Data" )
4523 gawk -F "$gawk_fs" -v bsdVersion=$BSD_VERSION -v cpuFlags="$bsd_cpu_flags" -v cpuMax="$cpu_max" '
4535 /^hw.model/ && ( bsdVersion != "darwin" ) {
4536 gsub(/'"$BAN_LIST_NORMAL"'/, "", $NF )
4537 gsub(/'"$BAN_LIST_CPU"'/, "", $NF )
4538 gsub(/'"$BAN_LIST_ARRAY"'/," ",$NF)
4539 sub(/[a-z]+-core/, "", $NF )
4540 gsub(/^ +| +$|\"/, "", $NF)
4541 gsub(/ [ \t]+/, " ", $NF)
4542 # cut L2 cache/cpu max speed out of model string, if available
4543 if ( $NF ~ /[0-9]+[[:space:]]*[KM]B[[:space:]]+L2 cache/) {
4544 cpuCache=gensub(/.*[^0-9]([0-9]+[[:space:]]*[KM]B)[[:space:]]+L2 cach.*/,"\\1",1,$NF)
4546 if ( $NF ~ /[^0-9\.][0-9\.]+[\-[:space:]]*[MG]Hz/) {
4547 max=gensub(/.*[^0-9\.]([0-9\.]+[\-[:space:]]*[MG]Hz).*/,"\\1",1,$NF)
4549 sub(/[\-[:space:]]*MHz/,"",max)
4552 sub(/[\-[:space:]]*GHz/,"",max)
4557 sub(/[[:space:]]*\(.*\)$/,"",$NF)
4560 # if ( cpuClock != "" ) {
4566 # if ( cpuModel != "" ) {
4570 /^hw.cpufrequency/ {
4571 cpuClock = $NF / 1000000
4578 cpuCache=cpuCache " kB"
4580 /^machdep.cpu.vendor/ {
4583 # Freebsd does some voltage hacking to actually run at lowest listed frequencies.
4584 # The cpu does not actually support all the speeds output here but works in freebsd.
4585 /^dev.cpu.0.freq_levels/ {
4586 gsub(/^[[:space:]]+|\/[0-9]+|[[:space:]]+$/,"",$NF)
4587 if ( $NF ~ /[0-9]+[[:space:]]+[0-9]+/ ) {
4588 min=gensub(/.*[[:space:]]([0-9]+)$/,"\\1",1,$NF)
4589 max=gensub(/^([0-9]+)[[:space:]].*/,"\\1",1,$NF)
4592 /^machdep.cpu.brand_string/ {
4593 gsub(/'"$BAN_LIST_NORMAL"'/, "", $NF )
4594 gsub(/'"$BAN_LIST_CPU"'/, "", $NF )
4595 gsub(/'"$BAN_LIST_ARRAY"'/," ",$NF)
4596 sub(/[a-z]+-core/, "", $NF )
4597 gsub(/^ +| +$|\"/, "", $NF)
4598 gsub(/ [ \t]+/, " ", $NF)
4599 sub(/[[:space:]]*@.*/,"",$NF)
4603 if ( max == 0 && cpuMax != "" ) {
4606 if ( cpuClock == "" ) {
4609 sub(/\.[0-9]+/,"",cpuClock)
4610 sub(/\.[0-9]+/,"",min)
4611 sub(/\.[0-9]+/,"",max)
4612 print cpuModel "," cpuClock "," cpuCache "," cpuFlags "," cpuBogomips "," cpuVendor
4613 # triggers print case
4614 print cpuClock "," min "," max
4615 }' <<< "$Sysctl_a_Data" ) )
4629 if [[ -n $Dmesg_Boot_Data ]];then
4630 cpu_flags=$( gawk -v bsdVersion="$BSD_VERSION" -F ":" '
4636 while ( getline && !/memory|real mem/ ) {
4637 if ( $1 ~ /Features/ || ( bsdVersion == "openbsd" && $0 ~ /^cpu0.*[[:space:]][a-z][a-z][a-z][[:space:]][a-z][a-z][a-z][[:space:]]/ ) ) {
4638 # clean up odd stuff like <b23>
4639 gsub(/<[a-z0-9]+>/,"", $2)
4640 # all the flags are contained within < ... > on freebsd at least
4641 gsub(/.*<|>.*/,"", $2)
4642 gsub(/'"$BAN_LIST_ARRAY"'/," ", $2)
4643 cpuFlags = cpuFlags " " $2
4646 cpuFlags=tolower(cpuFlags)
4649 }' <<< "$Dmesg_Boot_Data" )
4650 elif [[ -n $Sysctl_a_Data ]];then
4651 if [[ $BSD_VERSION == 'openbsd' ]];then
4654 cpu_flags=$( gawk -F "$gawk_fs" '
4658 /^machdep.cpu.features/ {
4659 cpuFlags=tolower($NF)
4662 }' <<< "$Sysctl_a_Data" )
4665 log_function_data "$cpu_flags"
4669 ## this is for counting processors and finding HT types
4670 get_cpu_ht_multicore_smp_data()
4676 # note: known bug with xeon intel, they show a_core_id/physical_id as 0 for ht 4 core
4677 if [[ $B_CPUINFO_FILE == 'true' ]]; then
4678 A_CPU_TYPE_PCNT_CCNT=( $(
4684 num_of_processors = 0
4685 num_of_physical_cpus = 0
4688 # these 3 arrays cannot be declared because that sets the first element
4689 # but leaving this here so that we avoid doing that in the future
4691 # a_processor_id = ""
4692 # a_physical_id = ""
4694 # note: we need separate iterators because some cpuinfo data has only
4695 # processor, no core id or phys id
4697 core_iter = "" # set from actual NF data
4698 phys_iter = "" # set from actual NF data
4699 # needed to handle arm cpu, no processor number cases
4705 # hack to handle xeons which can have buggy /proc/cpuinfo files
4706 /^model name/ && ( $0 ~ /Xeon/ ) {
4709 # only do this once since sibling count does not change.
4710 /^siblings/ && ( bXeon == "true" ) && ( siblings == 0 ) {
4711 gsub(/[^0-9]/,"",$NF)
4716 # array of logical processors, both HT and physical
4718 gsub(/'"$BAN_LIST_ARRAY"'/, " ", $NF)
4719 gsub(/^ +| +$/, "", $NF)
4720 if ( $NF ~ "^[0-9]+$" ) {
4721 a_processor_id[proc_iter] = $NF
4725 # note, for dual core, this can be off by one because the first
4726 # line says: Processor : Arm.. but subsequent say: processor : 0 and so on as usual
4727 if ( $NF ~ "^ARM" ) {
4732 # note: do not iterate because new ARM syntax puts cpu in processsor : 0 syntax
4733 a_processor_id[proc_iter] = nr
4736 # array of physical cpu ids, note, this will be unset for vm cpus in many cases
4737 # because they have no physical cpu, so we cannot assume this will be here.
4740 a_physical_id[phys_iter] = $NF
4742 # array of core ids, again, here we may have HT, so we need to create an array of the
4743 # actual core ids. As With physical, we cannot assume this will be here in a vm
4746 a_core_id[core_iter] = $NF
4748 # this will be used to fix an intel glitch if needed, cause, intel
4749 # sometimes reports core id as the same number for each core,
4750 # so if cpu cores shows greater value than number of cores, use this.
4752 cpu_core_count = $NF
4755 ## Look thru the array and filter same numbers.
4756 ## only unique numbers required
4757 ## this is to get an accurate count
4758 ## we are only concerned with array length
4760 ## count unique processors ##
4761 # note, this fails for intel cpus at times
4762 for ( i in a_processor_id ) {
4766 ## count unique physical cpus ##
4767 for ( i in a_physical_id ) {
4768 num_of_physical_cpus++
4771 ## count unique cores ##
4772 for ( i in a_core_id ) {
4775 # xeon may show wrong core / physical id count, if it does, fix it. A xeon
4776 # may show a repeated core id : 0 which gives a fake num_of_cores=1
4777 if ( bXeon == "true" && num_of_cores == 1 && siblings > 1 ) {
4778 num_of_cores = siblings/2
4780 # final check, override the num of cores value if it clearly is wrong
4781 # and use the raw core count and synthesize the total instead of real count
4782 if ( ( num_of_cores == 0 ) && ( cpu_core_count * num_of_physical_cpus > 1 ) ) {
4783 num_of_cores = cpu_core_count * num_of_physical_cpus
4785 # last check, seeing some intel cpus and vms with intel cpus that do not show any
4786 # core id data at all, or siblings.
4787 if ( num_of_cores == 0 && num_of_processors > 0 ) {
4788 num_of_cores = num_of_processors
4790 # ARM/vm cpu fix, if no physical or core found, use count of 1 instead
4791 if ( num_of_physical_cpus == 0 ) {
4792 num_of_physical_cpus = 1
4794 # print "NoCpu: " num_of_physical_cpus
4795 # print "NoCores: " num_of_cores
4796 # print "NoProc:" num_of_processors
4797 # print "CpuCoreCount:" cpu_core_count
4798 ####################################################################
4800 # if > 1 processor && processor id (physical id) == core id then Hyperthreaded (HT)
4801 # if > 1 processor && processor id (physical id) != core id then Multi-Core Processors (MCP)
4802 # if > 1 processor && processor ids (physical id) > 1 then Multiple Processors (SMP)
4803 # if = 1 processor then single core/processor Uni-Processor (UP)
4804 if ( num_of_processors > 1 || ( bXeon == "true" && siblings > 0 ) ) {
4806 if ( num_of_processors == (num_of_cores * 2) ) {
4807 cpu_type = cpu_type "HT-"
4809 else if ( bXeon == "true" && siblings > 1 ) {
4810 cpu_type = cpu_type "HT-"
4812 # non-HT multi-core or HT multi-core
4813 if (( num_of_processors == num_of_cores) || ( num_of_physical_cpus < num_of_cores)) {
4814 cpu_type = cpu_type "MCP-"
4816 # >1 cpu sockets active
4817 if ( num_of_physical_cpus > 1 ) {
4818 cpu_type = cpu_type "SMP-"
4822 cpu_type = cpu_type "UP-"
4825 print cpu_type " " num_of_physical_cpus " " num_of_cores
4829 a_temp=${A_CPU_TYPE_PCNT_CCNT[@]}
4830 log_function_data "A_CPU_TYPE_PCNT_CCNT: $a_temp"
4834 # Detect desktop environment in use, initial rough logic from: compiz-check
4835 # http://forlong.blogage.de/entries/pages/Compiz-Check
4836 # NOTE $XDG_CURRENT_DESKTOP envvar is not reliable, but it shows certain desktops better.
4837 # most desktops are not using it as of 2014-01-13 (KDE, UNITY, LXDE. Not Gnome)
4838 get_desktop_environment()
4842 # set the default, this function only runs in X, if null, don't print data out
4843 local desktop_environment='' xprop_root='' version2=''
4844 local version='' version_data='' version2_data='' toolkit=''
4846 # works on 4, assume 5 will id the same, why not, no need to update in future
4847 # KDE_SESSION_VERSION is the integer version of the desktop
4848 # NOTE: as of plasma 5, the tool: about-distro MAY be available, that will show
4849 # actual desktop data, so once that's in debian/ubuntu, if it gets in, add that test
4850 if [[ $XDG_CURRENT_DESKTOP == 'KDE' || -n $KDE_SESSION_VERSION ]]; then
4851 # note the command is actually like, kded4 --version, so we construct it
4852 # this was supposed to extend to 5, but 5 changed it, so it uses the more reliable way
4853 if [[ $KDE_SESSION_VERSION -le 4 ]];then
4854 version_data=$( kded$KDE_SESSION_VERSION --version 2>/dev/null )
4855 version=$( grep -si '^KDE Development Platform:' <<< "$version_data" | gawk '{print $4}' )
4857 # NOTE: this command string is almost certain to change, and break, with next major plasma desktop, ie, 6
4858 # version=$( qdbus org.kde.plasmashell /MainApplication org.qtproject.Qt.QCoreApplication.applicationVersion 2>/dev/null )
4860 #KDE Frameworks: 5.11.0
4862 # for QT, and Frameworks if we use it
4863 if type -p kf$KDE_SESSION_VERSION-config &>/dev/null;then
4864 version_data=$( kf$KDE_SESSION_VERSION-config --version 2>/dev/null )
4865 # version=$( grep -si '^KDE Frameworks:' <<< "$version_data" | gawk '{print $NF}' )
4867 # plasmashell 5.3.90
4868 if type -p plasmashell &>/dev/null;then
4869 version2_data=$( plasmashell --version 2>/dev/null )
4870 version=$( grep -si '^plasmashell' <<< "$version2_data" | gawk '{print $NF}' )
4873 if [[ -z $version ]];then
4874 version=$KDE_SESSION_VERSION
4876 if [[ $B_EXTRA_DATA == 'true' && -n $version_data ]];then
4877 toolkit=$( grep -si '^Qt:' <<< "$version_data" | gawk '{print $2}' )
4878 if [[ -n $toolkit ]];then
4879 version="$version (Qt $toolkit)"
4882 desktop_environment="KDE Plasma"
4883 # KDE_FULL_SESSION property is only available since KDE 3.5.5.
4884 # src: http://humanreadable.nfshost.com/files/startkde
4885 elif [[ $KDE_FULL_SESSION == 'true' ]]; then
4886 version_data=$( kded --version 2>/dev/null )
4887 version=$( grep -si '^KDE:' <<< "$version_data" | gawk '{print $2}' )
4888 # version=$( get_program_version 'kded' '^KDE:' '2' )
4889 if [[ -z $version ]];then
4892 if [[ $B_EXTRA_DATA == 'true' ]];then
4893 toolkit=$( grep -si '^Qt:' <<< "$version_data" | gawk '{print $2}' )
4894 if [[ -n $toolkit ]];then
4895 version="$version (Qt $toolkit)"
4898 desktop_environment="KDE"
4899 elif [[ $XDG_CURRENT_DESKTOP == 'Unity' ]];then
4900 version=$( get_program_version 'unity' '^unity' '2' )
4901 # not certain will always have version, so keep output right if not
4902 if [[ -n $version ]];then
4905 if [[ $B_EXTRA_DATA == 'true' ]];then
4906 toolkit=$( get_de_gtk_data )
4907 if [[ -n $toolkit ]];then
4908 version="$version(Gtk $toolkit)"
4911 desktop_environment="Unity"
4912 elif [[ $XDG_CURRENT_DESKTOP == 'LXQt' ]];then
4913 # if type -p lxqt-about &>/dev/null;then
4914 # version=$( get_program_version 'lxqt-about' '^lxqt-about' '2' )
4916 if [[ $B_EXTRA_DATA == 'true' ]];then
4917 if kded$KDE_SESSION_VERSION &>/dev/null;then
4918 version_data=$( kded$KDE_SESSION_VERSION --version 2>/dev/null )
4919 toolkit=$( grep -si '^Qt:' <<< "$version_data" | gawk '{print $2}' )
4920 elif type -p qtdiag &>/dev/null;then
4921 toolkit=$( get_program_version 'qtdiag' '^qt' '2' )
4923 if [[ -n $toolkit ]];then
4924 version="$version (Qt $toolkit)"
4927 desktop_environment='LXQt'
4928 # note, X-Cinnamon value strikes me as highly likely to change, so just search for the last part
4929 elif [[ -n $XDG_CURRENT_DESKTOP && -z ${XDG_CURRENT_DESKTOP/*innamon*/} ]];then
4930 version=$( get_program_version 'cinnamon' '^cinnamon' '2' )
4931 # not certain cinn will always have version, so keep output right if not
4932 if [[ -n $version ]];then
4935 if [[ $B_EXTRA_DATA == 'true' ]];then
4936 toolkit=$( get_de_gtk_data )
4937 if [[ -n $toolkit ]];then
4938 version="$version(Gtk $toolkit)"
4941 desktop_environment="Cinnamon"
4943 # did we find it? If not, start the xprop tests
4944 if [[ -z $desktop_environment ]];then
4945 if type -p xprop &>/dev/null;then
4946 xprop_root="$( xprop -root 2>/dev/null )"
4948 # note that cinnamon split from gnome, and and can now be id'ed via xprop,
4949 # but it will still trigger the next gnome true case, so this needs to go before gnome test
4950 # eventually this needs to be better organized so all the xprop tests are in the same
4951 # section, but this is good enough for now.
4952 if [[ -n $xprop_root && -n $( grep -is '^_MUFFIN' <<< "$xprop_root" ) ]];then
4953 version=$( get_program_version 'cinnamon' '^cinnamon' '2' )
4954 # not certain cinn will always have version, so keep output right if not
4955 if [[ -n $version ]];then
4958 if [[ $B_EXTRA_DATA == 'true' ]];then
4959 toolkit=$( get_de_gtk_data )
4960 if [[ -n $toolkit ]];then
4961 version="$version(Gtk $toolkit)"
4964 desktop_environment="Cinnamon"
4965 elif [[ $XDG_CURRENT_DESKTOP == 'MATE' ]] || [[ -n $xprop_root && -n $( grep -is '^_MARCO' <<< "$xprop_root" ) ]];then
4966 version=$( get_program_version 'mate-about' '^MATE[[:space:]]DESKTOP' 'NF' )
4967 # not certain cinn/mate will always have version, so keep output right if not
4968 if [[ -n $version ]];then
4971 if [[ $B_EXTRA_DATA == 'true' ]];then
4972 toolkit=$( get_de_gtk_data )
4973 if [[ -n $toolkit ]];then
4974 version="$version(Gtk $toolkit)"
4977 desktop_environment="MATE"
4978 # note, GNOME_DESKTOP_SESSION_ID is deprecated so we'll see how that works out
4979 # https://bugzilla.gnome.org/show_bug.cgi?id=542880
4980 elif [[ -n $GNOME_DESKTOP_SESSION_ID || $XDG_CURRENT_DESKTOP == 'GNOME' ]]; then
4981 if type -p gnome-shell &>/dev/null;then
4982 version=$( get_program_version 'gnome-shell' 'gnome' '3' )
4983 elif type -p gnome-about &>/dev/null;then
4984 version=$( get_program_version 'gnome-about' 'gnome' '3' )
4986 if [[ $B_EXTRA_DATA == 'true' ]];then
4987 toolkit=$( get_de_gtk_data )
4988 if [[ -n $toolkit ]];then
4989 version="$version (Gtk $toolkit)"
4992 desktop_environment="Gnome"
4994 if [[ -z $desktop_environment ]];then
4995 # now that the primary ones have been handled, next is to find the ones with unique
4996 # xprop detections possible
4997 if [[ -n $xprop_root ]];then
4998 # String: "This is xfdesktop version 4.2.12"
4999 # alternate: xfce4-about --version > xfce4-about 4.10.0 (Xfce 4.10)
5000 if [[ -n $( grep -Eis '\"xfce4\"' <<< "$xprop_root" ) ]];then
5001 version=$( get_program_version 'xfdesktop' 'xfdesktop[[:space:]]version' '5' )
5002 # arch linux reports null, so use alternate if null
5003 if [[ -z $version ]];then
5004 version=$( get_program_version 'xfce4-panel' '^xfce4-panel' '2' )
5005 if [[ -z $version ]];then
5009 if [[ $B_EXTRA_DATA == 'true' ]];then
5010 toolkit=$( get_program_version 'xfdesktop' 'Built[[:space:]]with[[:space:]]GTK' '4' )
5011 if [[ -n $toolkit ]];then
5012 version="$version (Gtk $toolkit)"
5015 desktop_environment="Xfce"
5016 # when 5 is released, the string may need updating
5017 elif [[ -n $( grep -is '\"xfce5\"' <<< "$xprop_root" ) ]];then
5018 version=$( get_program_version 'xfdesktop' 'xfdesktop[[:space:]]version' '5' )
5019 # arch linux reports null, so use alternate if null
5020 if [[ -z $version ]];then
5021 version=$( get_program_version 'xfce5-panel' '^xfce5-panel' '2' )
5022 if [[ -z $version ]];then
5026 if [[ $B_EXTRA_DATA == 'true' ]];then
5027 toolkit=$( get_program_version 'xfdesktop' 'Built[[:space:]]with[[:space:]]GTK' '4' )
5028 if [[ -n $toolkit ]];then
5029 version="$version (Gtk $toolkit)"
5032 desktop_environment="Xfce"
5033 # case where no xfce number exists, just xfce
5034 elif [[ -n $( grep -is 'xfce' <<< "$xprop_root" ) ]];then
5035 version=$( get_program_version 'xfdesktop' 'xfdesktop[[:space:]]version' '5' )
5036 # arch linux reports null, so use alternate if null
5037 if [[ -z $version ]];then
5038 version=$( get_program_version 'xfce4-panel' '^xfce5-panel' '2' )
5039 if [[ -z $version ]];then
5040 # version=$( get_program_version 'xfce5-panel' '^xfce5-panel' '2' )
5041 #if [[ -z $version ]];then
5047 if [[ $B_EXTRA_DATA == 'true' ]];then
5048 toolkit=$( get_program_version 'xfdesktop' 'Built[[:space:]]with[[:space:]]GTK' '4' )
5049 if [[ -n $toolkit ]];then
5050 version="$version (Gtk $toolkit)"
5053 desktop_environment="Xfce"
5054 elif [[ -n $( grep -is 'BLACKBOX_PID' <<< "$xprop_root" ) ]];then
5055 if [[ -n $( grep -is 'fluxbox' <<< "$Ps_aux_Data" ) ]];then
5056 version=$( get_program_version 'fluxbox' '^fluxbox' '2' )
5057 desktop_environment='Fluxbox'
5059 desktop_environment='Blackbox'
5061 elif [[ -n $( grep -is 'OPENBOX_PID' <<< "$xprop_root" ) ]];then
5062 # note: openbox-lxde --version may be present, but returns openbox data
5063 version=$( get_program_version 'openbox' '^openbox' '2' )
5064 if [[ $XDG_CURRENT_DESKTOP == 'LXDE' || \
5065 -n $( grep -is '/lxsession' <<< "$Ps_aux_Data" ) ]];then
5066 if [[ -n $version ]];then
5067 version="(Openbox $version)"
5069 desktop_environment='LXDE'
5070 elif [[ $XDG_CURRENT_DESKTOP == 'Razor' || $XDG_CURRENT_DESKTOP == 'LXQt' ]] || \
5071 [[ -n $( grep -Eis '(razor-desktop|lxqt-session)' <<< "$Ps_aux_Data" ) ]];then
5072 if [[ -n $( grep -is 'lxqt-session' <<< "$Ps_aux_Data" ) ]];then
5073 desktop_environment='LXQt'
5074 elif [[ -n $( grep -is 'razor-desktop' <<< "$Ps_aux_Data" ) ]];then
5075 desktop_environment='Razor-Qt'
5077 desktop_environment='LX-Qt-Variant'
5079 if [[ -n $version ]];then
5080 version="(Openbox $version)"
5083 desktop_environment='Openbox'
5085 elif [[ -n $( grep -is 'ICEWM' <<< "$xprop_root" ) ]];then
5086 version=$( get_program_version 'icewm' '^icewm' '2' )
5087 desktop_environment='IceWM'
5088 elif [[ -n $( grep -is 'ENLIGHTENMENT' <<< "$xprop_root" ) ]];then
5089 # no -v or --version but version is in xprop -root
5090 # ENLIGHTENMENT_VERSION(STRING) = "Enlightenment 0.16.999.49898"
5091 version=$( grep -is 'ENLIGHTENMENT_VERSION' <<< "$xprop_root" | cut -d '"' -f 2 | gawk '{print $2}' )
5092 desktop_environment='Enlightenment'
5093 elif [[ -n $( grep -is '^I3_' <<< "$xprop_root" ) ]];then
5094 version=$( get_program_version 'i3' '^i3' '3' )
5095 desktop_environment='i3'
5096 elif [[ -n $( grep -is 'WINDOWMAKER' <<< "$xprop_root" ) ]];then
5097 version=$( get_program_version 'wmaker' '^Window[[:space:]]*Maker' 'NF' )
5098 if [[ -n $version ]];then
5101 desktop_environment="WindowMaker"
5102 elif [[ -n $( grep -is '^_WM2' <<< "$xprop_root" ) ]];then
5103 # note; there isn't actually a wm2 version available but error handling should cover it and return null
5104 # maybe one day they will add it?
5105 version=$( get_program_version 'wm2' '^wm2' 'NF' )
5106 # not certain will always have version, so keep output right if not
5107 if [[ -n $version ]];then
5110 desktop_environment="WM2"
5111 elif [[ -n $( grep -is 'herbstluftwm' <<< "$xprop_root" ) ]];then
5112 version=$( get_program_version 'herbstluftwm' '^herbstluftwm' 'NF' )
5113 if [[ -n $version ]];then
5116 desktop_environment="herbstluftwm"
5119 # a few manual hacks for things that don't id with xprop, these are just good guesses
5120 # note that gawk is going to exit after first occurance of search string, so no need for extra
5121 if [[ -z $desktop_environment ]];then
5122 if [[ -n $( grep -is 'fvwm-crystal' <<< "$Ps_aux_Data" ) ]];then
5123 version=$( get_program_version 'fvwm' '^fvwm' '2' )
5124 desktop_environment='FVWM-Crystal'
5125 elif [[ -n $( grep -is 'fvwm' <<< "$Ps_aux_Data" ) ]];then
5126 version=$( get_program_version 'fvwm' '^fvwm' '2' )
5127 desktop_environment='FVWM'
5128 elif [[ -n $( grep -is 'pekwm' <<< "$Ps_aux_Data" ) ]];then
5129 version=$( get_program_version 'pekwm' '^pekwm' '3' )
5130 desktop_environment='pekwm'
5131 elif [[ -n $( grep -is 'awesome' <<< "$Ps_aux_Data" ) ]];then
5132 version=$( get_program_version 'awesome' '^awesome' '2' )
5133 desktop_environment='Awesome'
5134 elif [[ -n $( grep -is 'scrotwm' <<< "$Ps_aux_Data" ) ]];then
5135 version=$( get_program_version 'scrotwm' '^welcome.*scrotwm' '4' )
5136 desktop_environment='Scrotwm' # no --version for this one
5137 elif [[ -n $( grep -is 'spectrwm' <<< "$Ps_aux_Data" ) ]];then
5138 version=$( get_program_version 'spectrwm' '^spectrwm.*welcome.*spectrwm' '5' )
5139 desktop_environment='Spectrwm' # no --version for this one
5140 elif [[ -n $( grep -Eis '([[:space:]]|/)twm' <<< "$Ps_aux_Data" ) ]];then
5141 desktop_environment='Twm' # no --version for this one
5142 elif [[ -n $( grep -Eis '([[:space:]]|/)dwm' <<< "$Ps_aux_Data" ) ]];then
5143 version=$( get_program_version 'dwm' '^dwm' '1' )
5144 desktop_environment='dwm'
5145 elif [[ -n $( grep -is 'wmii2' <<< "$Ps_aux_Data" ) ]];then
5146 version=$( get_program_version 'wmii2' '^wmii2' '1' )
5147 desktop_environment='wmii2'
5148 # note: in debian at least, wmii is actuall wmii3
5149 elif [[ -n $( grep -is 'wmii' <<< "$Ps_aux_Data" ) ]];then
5150 version=$( get_program_version 'wmii' '^wmii' '1' )
5151 desktop_environment='wmii'
5152 elif [[ -n $( grep -Eis '([[:space:]]|/)jwm' <<< "$Ps_aux_Data" ) ]];then
5153 version=$( get_program_version 'jwm' '^jwm' '2' )
5154 desktop_environment='JWM'
5159 if [[ -n $version ]];then
5162 log_function_data "desktop_environment version: $desktop_environment$version"
5163 echo "$desktop_environment$version"
5167 # note: gawk doesn't support white spaces in search string, gave errors, so use [[:space:]] instead
5168 # args: $1 - desktop/app command for --version; $2 - search string; $3 - gawk print number
5169 get_program_version()
5171 local version_data='' version='' get_version='--version'
5173 # mate-about -v = MATE Desktop Environment 1.4.0
5175 dwm|jwm|mate-about|wmii|wmii2)
5179 get_version='version'
5184 # note, some wm/apps send version info to stderr instead of stdout
5185 dwm|ksh|scrotwm|spectrwm)
5186 version_data="$( $1 $get_version 2>&1 )"
5189 version_data="$( tcsh $get_version 2>/dev/null )"
5191 # quick debian/buntu hack until I find a universal way to get version for these
5193 if type -p dpkg &>/dev/null;then
5194 version_data="$( dpkg -l $1 2>/dev/null )"
5198 version_data="$( $1 $get_version 2>/dev/null )"
5201 log_function_data "version data: $version_data"
5202 if [[ -n $version_data ]];then
5208 # sample: dwm-5.8.2, ©.. etc, why no space? who knows. Also get rid of v in number string
5209 # xfce, and other, output has , in it, so dump all commas and parentheses
5210 gsub(/(,|dwm-|wmii2-|wmii-|v|V|\(|\))/, "",$'$3')
5212 exit # quit after first match prints
5213 }' <<< "$version_data" )
5215 log_function_data "program version: $version"
5219 get_desktop_extra_data()
5222 local de_data=$( ps -A | gawk '
5228 /(gnome-shell|gnome-panel|kicker|lxpanel|mate-panel|plasma-desktop|plasma-netbook|xfce4-panel)$/ {
5229 # only one entry per type, can be multiple
5230 if ( desktops !~ $NF ) {
5231 desktops = desktops separator $NF
5239 log_function_data "de_data: $de_data"
5251 # this is a hack, and has to be changed with every toolkit version change, and only dev systems
5252 # have this installed, but it's a cross distro command so let's test it first
5253 if type -p pkg-config &>/dev/null;then
5254 toolkit=$( pkg-config --modversion gtk+-4.0 2>/dev/null )
5255 # note: opensuse gets null output here, we need the command to get version and output sample
5256 if [[ -z $toolkit ]];then
5257 toolkit=$( pkg-config --modversion gtk+-3.0 2>/dev/null )
5259 if [[ -z $toolkit ]];then
5260 toolkit=$( pkg-config --modversion gtk+-2.0 2>/dev/null )
5263 # now let's go to more specific version tests, this will never cover everything and that's fine.
5264 if [[ -z $toolkit ]];then
5265 # we'll try some known package managers next. dpkg will handle a lot of distros
5266 # this is the most likely order as of: 2014-01-13. Not going to try to support all package managers
5267 # too much work, just the very biggest ones.
5268 if type -p dpkg &>/dev/null;then
5269 toolkit=$( dpkg -s libgtk-3-0 2>/dev/null | gawk -F ':' '/^[[:space:]]*Version/ {print $2}' )
5270 # just guessing on gkt 4 package name
5271 if [[ -z $toolkit ]];then
5272 toolkit=$( dpkg -s libgtk-4-0 2>/dev/null | gawk -F ':' '/^[[:space:]]*Version/ {print $2}' )
5274 if [[ -z $toolkit ]];then
5275 toolkit=$( dpkg -s libgtk2.0-0 2>/dev/null | gawk -F ':' '/^[[:space:]]*Version/ {print $2}' )
5277 elif type -p pacman &>/dev/null;then
5278 toolkit=$( pacman -Qi gtk3 2>/dev/null | gawk -F ':' '/^[[:space:]]*Version/ {print $2}' )
5279 # just guessing on gkt 4 package name
5280 if [[ -z $toolkit ]];then
5281 toolkit=$( pacman -Qi gtk4 2>/dev/null | gawk -F ':' '/^[[:space:]]*Version/ {print $2}' )
5283 if [[ -z $toolkit ]];then
5284 toolkit=$( pacman -Qi gtk2 2>/dev/null | gawk -F ':' '/^[[:space:]]*Version/ {print $2}' )
5288 elif type -p rpm &>/dev/null;then
5289 toolkit=$( rpm -qi libgtk-3-0 2>/dev/null | gawk -F ':' '
5290 /^[[:space:]]*Version/ {
5291 gsub(/^[[:space:]]+|[[:space:]]+$/,"",$2)
5294 if [[ -z $toolkit ]];then
5295 toolkit=$( rpm -qi libgtk-4-0 2>/dev/null | gawk -F ':' '
5296 /^[[:space:]]*Version/ {
5297 gsub(/^[[:space:]]+|[[:space:]]+$/,"",$2)
5301 if [[ -z $toolkit ]];then
5302 toolkit=$( rpm -qi libgtk-2-0 2>/dev/null | gawk -F ':' '
5303 /^[[:space:]]*Version/ {
5304 gsub(/^[[:space:]]+|[[:space:]]+$/,"",$2)
5310 log_function_data "toolkit: $toolkit"
5317 # see which dm has started if any
5318 get_display_manager()
5321 # ldm - LTSP display manager. Note that sddm does not appear to have a .pid extension in Arch
5322 # note: to avoid positives with directories, test for -f explicitly, not -e
5323 local dm_id_list='entranced.pid gdm.pid gdm3.pid kdm.pid ldm.pid lightdm.pid lxdm.pid mdm.pid nodm.pid sddm.pid sddm slim.lock tint2.pid wdm.pid xdm.pid'
5324 local dm_id='' dm='' separator=''
5325 # note we don't need to filter grep if we do it this way
5326 local x_is_running=$( grep '/usr.*/X' <<< "$Ps_aux_Data" | grep -iv '/Xprt' )
5328 for dm_id in $dm_id_list
5330 # note: ${dm_id%.*}/$dm_id will create a dir name out of the dm id, then test if pid is in that
5331 # note: sddm, in an effort to be unique and special, do not use a pid/lock file, but rather a random
5332 # string inside a directory called /run/sddm/ so assuming the existence of the pid inside a directory named
5333 # from the dm. Hopefully this change will not have negative results.
5334 if [[ -f /run/$dm_id || -d /run/${dm_id%.*}/ || -f /var/run/$dm_id || \
5335 -d /var/run/${dm_id%.*}/ ]];then
5336 # just on the off chance that two dms are running, good info to have in that case, if possible
5337 dm=$dm$separator${dm_id%.*}
5341 # might add this in, but the rate of new dm's makes it more likely it's an unknown dm, so
5342 # we'll keep output to N/A
5343 if [[ -n $x_is_running && -z $dm ]];then
5344 if [[ -n $( grep 'startx$' <<< "$Ps_aux_Data" ) ]];then
5350 log_function_data "display manager: $dm"
5355 # for more on distro id, please reference this python thread: http://bugs.python.org/issue1322
5356 ## return distro name/id if found
5360 local i='' j='' distro='' distro_file='' a_distro_glob='' a_temp='' b_osr='false'
5362 # may need modification if archbsd / debian can be id'ed with /etc files
5363 if [[ -n $BSD_TYPE ]];then
5364 if [[ $BSD_VERSION != 'darwin' ]];then
5365 distro=$( uname -sr )
5367 if [[ -f /System/Library/CoreServices/SystemVersion.plist ]];then
5368 distro=$( grep -A1 -E '(ProductName|ProductVersion)' /System/Library/CoreServices/SystemVersion.plist | grep '<string>' | sed -E 's/<[\/]?string>//g' )
5369 distro=$( echo $distro )
5371 if [[ -z $distro ]];then
5376 log_function_data "distro: $distro"
5381 # get the wild carded array of release/version /etc files if present
5384 # note: always exceptions, so wild card after release/version: /etc/lsb-release-crunchbang
5385 # wait to handle since crunchbang file is one of the few in the world that uses this method
5386 a_distro_glob=(*[-_]{release,version})
5390 a_temp=${a_distro_glob[@]}
5391 log_function_data "a_distro_glob: $a_temp"
5393 if [[ ${#a_distro_glob[@]} -eq 1 ]];then
5394 distro_file="$a_distro_glob"
5395 # use the file if it's in the known good lists
5396 elif [[ ${#a_distro_glob[@]} -gt 1 ]];then
5397 for i in $DISTROS_DERIVED $DISTROS_PRIMARY
5399 # Only echo works with ${var[@]}, not print_screen_output() or script_debugger()
5400 # This is a known bug, search for the word "strange" inside comments
5401 # echo "i='$i' a_distro_glob[@]='${a_distro_glob[@]}'"
5402 if [[ " ${a_distro_glob[@]} " == *" $i "* ]];then
5403 # Now lets see if the distro file is in the known-good working-lsb-list
5404 # if so, use lsb-release, if not, then just use the found file
5405 # this is for only those distro's with self named release/version files
5406 # because Mint does not use such, it must be done as below
5407 ## this if statement requires the spaces and * as it is, else it won't work
5409 if [[ " $DISTROS_LSB_GOOD " == *" $i "* ]] && [[ $B_LSB_FILE == 'true' ]];then
5410 distro_file='lsb-release'
5411 elif [[ " $DISTROS_OS_RELEASE_GOOD " == *" $i "* ]] && [[ $B_OS_RELEASE_FILE == 'true' ]];then
5412 distro_file='os-release'
5420 log_function_data "distro_file: $distro_file"
5421 # first test for the legacy antiX distro id file
5422 if [[ -e /etc/antiX ]];then
5423 distro="$( grep -Eoi 'antix.*\.iso' <<< $( remove_erroneous_chars '/etc/antiX' ) | sed 's/\.iso//' )"
5424 # this handles case where only one release/version file was found, and it's lsb-release. This would
5425 # never apply for ubuntu or debian, which will filter down to the following conditions. In general
5426 # if there's a specific distro release file available, that's to be preferred, but this is a good backup.
5427 elif [[ -n $distro_file && $B_LSB_FILE == 'true' && " $DISTROS_LSB_GOOD" == *" $distro_file "* ]];then
5428 distro=$( get_distro_lsb_os_release_data 'lsb-file' )
5429 elif [[ $distro_file == 'lsb-release' ]];then
5430 distro=$( get_distro_lsb_os_release_data 'lsb-file' )
5431 elif [[ $distro_file == 'os-release' ]];then
5432 distro=$( get_distro_lsb_os_release_data 'os-release-file' )
5434 # then if the distro id file was found and it's not in the exluded primary distro file list, read it
5435 elif [[ -n $distro_file && -s /etc/$distro_file && " $DISTROS_EXCLUDE_LIST " != *" $distro_file "* ]];then
5436 # new opensuse uses os-release, but older ones may have a similar syntax, so just use the first line
5437 if [[ $distro_file == 'SuSE-release' ]];then
5438 # leaving off extra data since all new suse have it, in os-release, this file has line breaks, like os-release
5439 # but in case we want it, it's: CODENAME = Mantis | VERSION = 12.2
5440 # for now, just take first occurance, which should be the first line, which does not use a variable type format
5441 distro=$( grep -i -m 1 'suse' /etc/$distro_file )
5443 distro=$( remove_erroneous_chars "/etc/$distro_file" )
5445 # otherwise try the default debian/ubuntu /etc/issue file
5446 elif [[ -f /etc/issue ]];then
5447 # os-release/lsb gives more manageable and accurate output than issue, but mint should use issue for now
5448 # some bashism, boolean must be in parenthesis to work correctly, ie [[ $(boolean) ]] not [[ $boolean ]]
5449 if [[ $B_OS_RELEASE_FILE == 'true' ]] && [[ -z $( grep -i 'mint' /etc/issue ) ]];then
5450 distro=$( get_distro_lsb_os_release_data 'os-release-file' )
5452 elif [[ $B_LSB_FILE == 'true' ]] && [[ -z $( grep -i 'mint' /etc/issue ) ]];then
5453 distro=$( get_distro_lsb_os_release_data 'lsb-file' )
5461 gsub(/'"$BAN_LIST_ARRAY"'/, " ")
5463 gsub(/ [ \t]+/, " ")
5467 # this handles an arch bug where /etc/arch-release is empty and /etc/issue is corrupted
5468 # only older arch installs that have not been updated should have this fallback required, new ones use
5470 if [[ -n $( grep -i 'arch linux' <<< $distro ) ]];then
5475 # a final check. If a long value, before assigning the debugger output, if os-release
5476 # exists then let's use that if it wasn't tried already. Maybe that will be better.
5477 if [[ ${#distro} -gt 80 ]] && [[ $B_HANDLE_CORRUPT_DATA != 'true' ]];then
5478 if [[ $B_OS_RELEASE_FILE == 'true' && $b_osr == 'false' ]];then
5479 distro=$( get_distro_lsb_os_release_data 'os-release-file' )
5481 if [[ ${#distro} -gt 80 ]];then
5482 distro="${RED}/etc/$distro_file corrupted, use -% to override${NORMAL}"
5485 ## note: would like to actually understand the method even if it's not used
5486 # : ${distro:=Unknown distro o_O}
5487 ## test for /etc/lsb-release as a backup in case of failure, in cases where > one version/release file
5488 ## were found but the above resulted in null distro value
5489 # Because os-release is now more common, we'll test for it first.
5490 if [[ -z $distro ]] && [[ $B_OS_RELEASE_FILE == 'true' ]];then
5491 distro=$( get_distro_lsb_os_release_data 'os-release-file' )
5493 if [[ -z $distro ]] && [[ $B_LSB_FILE == 'true' ]];then
5494 distro=$( get_distro_lsb_os_release_data 'lsb-file' )
5497 # now some final null tries
5498 if [[ -z $distro ]];then
5499 # if the file was null but present, which can happen in some cases, then use the file name itself to
5500 # set the distro value. Why say unknown if we have a pretty good idea, after all?
5501 if [[ -n $distro_file ]] && [[ " $DISTROS_DERIVED $DISTROS_PRIMARY " == *" $distro_file "* ]];then
5502 distro=$( sed $SED_RX -e 's/[-_]//' -e 's/(release|version)//' <<< $distro_file | sed $SED_RX 's/^([a-z])/\u\1/' )
5504 ## finally, if all else has failed, give up
5505 if [[ -z $distro ]];then
5509 # final step cleanup of unwanted information
5510 # opensuse has the x86 etc type string in names, not needed as redundant since -S already shows that
5516 sub(/ *\(*(x86_64|i486|i586|i686|686|586|486)\)*/, "", $0)
5520 log_function_data "distro: $distro"
5524 # args: $1 - lsb-file/lsb-app/os-release-file
5525 get_distro_lsb_os_release_data()
5532 if [[ $B_LSB_FILE == 'true' ]];then
5533 distro=$( gawk -F '=' '
5537 # clean out unwanted characters
5539 gsub(/\\|\"|[:\47]/,"", $0 )
5540 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2 )
5541 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $1 )
5543 # note: adding the spacing directly to variable to make sure distro output is null if not found
5545 # this is needed because grep for "arch" is too loose to be safe
5546 if ( $2 == "arch" ) {
5547 distroId = "Arch Linux"
5549 else if ( $2 != "n/a" ) {
5553 /^DISTRIB_RELEASE/ {
5554 if ( $2 != "n/a" ) {
5555 distroRelease = $2 " "
5558 /^DISTRIB_CODENAME/ {
5559 if ( $2 != "n/a" ) {
5560 distroCodename = $2 " "
5563 # sometimes some distros cannot do their lsb-release files correctly, so here is
5564 # one last chance to get it right.
5565 /^DISTRIB_DESCRIPTION/ {
5566 if ( $2 != "n/a" ) {
5567 distroDescription = $2
5572 if ( distroId == "" && distroRelease == "" && distroCodename == "" && distroDescription != "" ){
5573 fullString = distroDescription
5576 fullString = distroId distroRelease distroCodename
5580 ' $FILE_LSB_RELEASE )
5581 log_function_data 'cat' "$FILE_LSB_RELEASE"
5585 # this is HORRIBLY slow, not using
5586 if type -p lsb_release &>/dev/null;then
5587 distro=$( echo "$( lsb_release -irc )" | gawk -F ':' '
5591 # clean out unwanted characters
5593 gsub(/\\|\"|[:\47]/,"", $0 )
5594 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2 )
5595 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $1 )
5607 print distroId " " distroRelease " (" distroCodename ")"
5612 if [[ $B_OS_RELEASE_FILE == 'true' ]];then
5613 distro=$( gawk -F '=' '
5622 # clean out unwanted characters
5624 gsub(/\\|\"|[:\47]/,"", $0 )
5625 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2 )
5626 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $1 )
5628 # note: adding the spacing directly to variable to make sure distro output is null if not found
5630 if ( $2 != "n/a" ) {
5635 if ( $2 != "n/a" ) {
5640 if ( $2 != "n/a" && $1 == "VERSION" ) {
5643 else if ( $2 != "n/a" && $1 == "VERSION_ID" ) {
5648 if ( prettyName != "" ) {
5649 distroName = prettyName
5651 else if ( regularName != "" ) {
5652 distroName = regularName
5653 if ( versionName != "" ) {
5654 distroName = distroName " " versionName
5656 else if ( versionId != "" ) {
5657 distroName = distroName " " versionId
5663 ' $FILE_OS_RELEASE )
5664 log_function_data 'cat' "$FILE_OS_RELEASE"
5669 log_function_data "distro: $distro"
5673 get_dmidecode_data()
5677 local dmiData="" b_debugger='false'
5679 if [[ $B_DMIDECODE_SET != 'true' ]];then
5680 dmidecodePath=$( type -p dmidecode 2>/dev/null )
5681 if [[ -z $dmidecodePath ]];then
5682 DMIDECODE_DATA='dmidecode-error-not-installed'
5684 # note stripping out these lines: Handle 0x0016, DMI type 17, 27 bytes
5685 # but NOT deleting them, in case the dmidecode data is missing empty lines which will be
5686 # used to separate results. Then we remove the doubled empty lines to keep it clean and
5687 # strip out all the stuff we don't want to see in the results. We want the error data in
5688 # stdout for error handling
5689 if [[ $b_debugger == 'true' && $HOSTNAME == 'yawn' ]];then
5690 dmiData="$( cat ~/bin/scripts/inxi/svn/misc/data/dmidecode/dmidecode-memory-variants-2.txt )"
5692 dmiData="$( $dmidecodePath 2>&1 )"
5694 # these tests first, because bsd error messages like this (note how many : are in the string)
5695 # inxi: line 4928: /usr/local/sbin/dmidecode: Permission denied
5696 if [[ ${#dmiData} -lt 200 ]];then
5697 if [[ -z ${dmiData/*Permission denied*/} ]];then
5698 # if [[ -n $( grep -i 'Permission denied' <<< "$dmiData" ) ]];then
5699 DMIDECODE_DATA='dmidecode-error-requires-root'
5700 # this handles very old systems, like Lenny 2.6.26, with dmidecode, but no data
5701 elif [[ -n $( grep -i 'no smbios ' <<< "$dmiData" ) ]];then
5702 DMIDECODE_DATA='dmidecode-error-no-smbios-dmi-data'
5704 DMIDECODE_DATA='dmidecode-error-unknown-error'
5707 DMIDECODE_DATA="$( echo "$dmiData" | gawk -F ':' '
5715 # no idea why, but freebsd gawk does not do this right
5718 if ( twoData != "" ) {
5724 if ( $0 ~ /^\tDMI type/ ) {
5725 sub(/^\tDMI type.*/, "", $0)
5728 gsub(/'"$BAN_LIST_NORMAL"'/, "", twoData)
5729 gsub(/'"$BAN_LIST_ARRAY"'/, " ", twoData)
5730 # clean out Handle line
5731 # sub(/^Handle.*/,"", $0)
5732 sub(/^[[:space:]]*Inactive.*/,"",twoData)
5733 # yes, there is a typo in a user data set, unknow
5734 # Base Board Version|Base Board Serial Number
5735 # Chassis Manufacturer|Chassis Version|Chassis Serial Number
5736 # System manufacturer|System Product Name|System Version
5737 # To Be Filled By O.E.M.
5738 # strip out starting white space so that the following stuff will clear properly
5739 sub(/^[[:space:]]+/, "", twoData)
5740 sub(/^Base Board .*|^Chassis .*|empty|.*O\.E\.M\..*|.*OEM.*|^Not .*|^System .*|.*unknow.*|.*N\/A.*|none|^To be filled.*|^0x[0]+$|\[Empty\]|<Bad Index>|^\.\.$/, "", twoData)
5741 sub(/.*(AssetTagNum|Manufacturer| Or Motherboard|PartNum.*|SerNum).*/, "", twoData)
5742 gsub(/bios|acpi/, "", twoData)
5743 sub(/http:\/\/www.abit.com.tw\//, "Abit", twoData)
5745 # for double indented values replace with ~ so later can test for it, we are trusting that
5746 # indentation will be tabbed in this case
5747 # special case, dmidecode 2.2 has an extra tab and a DMI type line
5748 if ( cutExtraTab == "true" ) {
5749 sub(/^\t\t\t+/, "~", oneData)
5752 sub(/^\t\t+/, "~", oneData)
5754 gsub(/ [ \t]+/, " ", twoData)
5755 gsub(/^[[:space:]]+|[[:space:]]+$/, "", twoData)
5756 gsub(/^[[:space:]]+|[[:space:]]+$/, "", oneData)
5758 # reconstructing the line for processing so gawk can use -F : again
5759 if ( oneData != "" && twoHolder == "true" ) {
5760 print oneData ":" twoData
5763 # make sure all null lines have no spaces in them!
5764 gsub(/^[[:space:]]+|[[:space:]]+$/,"",$0)
5774 # echo ":${DMIDECODE_DATA}:"
5775 log_function_data "DMIDECODE_DATA (PRE): $DMIDECODE_DATA"
5778 B_DMIDECODE_SET='true'
5779 log_function_data "DMIDECODE_DATA (POST): $DMIDECODE_DATA"
5784 # get_dmidecode_data;echo "$DMIDECODE_DATA";exit
5787 get_dmesg_boot_data()
5791 local dmsg_boot_data=''
5793 if [[ $B_DMESG_BOOT_FILE == 'true' ]];then
5794 # replace all indented items with ~ so we can id them easily while processing
5795 # note that if user, may get error of read permissions
5796 # for some weird reason, real mem and avail mem are use a '=' separator, who knows why, the others are ':'
5797 dmsg_boot_data="$( cat $FILE_DMESG_BOOT 2>/dev/null | gawk '
5799 sub(/[[:space:]]*=[[:space:]]*|:[[:space:]]*/,":", $0)
5800 gsub(/'"$BAN_LIST_ARRAY"'/," ", $0)
5802 gsub(/[[:space:]][[:space:]]/, " ", $0)
5806 echo "$dmsg_boot_data"
5807 # log_function_data "$dmsg_boot_data"
5811 get_gcc_system_version()
5814 local separator='' gcc_installed='' gcc_list='' gcc_others='' a_temp=''
5815 local gcc_version=$(
5816 gcc --version 2>/dev/null | sed $SED_RX 's/\([^\)]*\)//g' | gawk '
5824 # can't use xargs -L basename because not all systems support thats
5825 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
5826 gcc_others=$( ls /usr/bin/gcc-* 2>/dev/null )
5827 if [[ -n $gcc_others ]];then
5828 for item in $gcc_others
5831 gcc_installed=$( gawk -F '-' '
5835 if [[ -n $gcc_installed && -z $( grep "^$gcc_installed" <<< $gcc_version ) ]];then
5836 gcc_list=$gcc_list$separator$gcc_installed
5842 if [[ -n $gcc_version ]];then
5843 A_GCC_VERSIONS=( "$gcc_version" $gcc_list )
5845 a_temp=${A_GCC_VERSIONS[@]}
5846 log_function_data "A_GCC_VERSIONS: $a_temp"
5852 local gpu_temp='' gpu_fan='' screens='' screen_nu='' gpu_temp_looper=''
5854 # we'll try for nvidia/ati, then add if more are shown
5855 if type -p nvidia-settings &>/dev/null;then
5856 # first get the number of screens. This only work if you are in X
5857 if [[ $B_RUNNING_IN_DISPLAY == 'true' ]];then
5858 screens=$( nvidia-settings -q screens | gawk '
5860 screens=screens gensub(/(.*)(:[0-9]\.[0-9])(.*)/, "\\2", "1", $0) " "
5867 # do a guess, this will work for most users, it's better than nothing for out of X
5870 # now we'll get the gpu temp for each screen discovered. The print out function
5871 # will handle removing screen data for single gpu systems
5872 for screen_nu in $screens
5874 gpu_temp_looper=$( nvidia-settings -c $screen_nu -q GPUCoreTemp 2>/dev/null | gawk -F ': ' '
5880 /Attribute (.*)[0-9]+\.$/ {
5882 if ( $2 ~ /^[0-9]+$/ ) {
5883 gpuTemp=gpuTemp $2 "C "
5889 screen_nu=$( cut -d ':' -f 2 <<< $screen_nu )
5890 gpu_temp="$gpu_temp$screen_nu:$gpu_temp_looper "
5892 elif type -p aticonfig &>/dev/null;then
5893 # gpu_temp=$( aticonfig --adapter=0 --od-gettemperature | gawk -F ': ' '
5894 gpu_temp=$( aticonfig --adapter=all --od-gettemperature | gawk -F ': ' '
5900 /Sensor (.*)[0-9\.]+ / {
5901 gpuTempWorking=gensub(/(.*) ([0-9\.]+) (.*)/, "\\2", "1", $2)
5902 if ( gpuTempWorking ~ /^[0-9\.]+$/ ) {
5903 gpuTemp=gpuTemp gpuTempWorking "C "
5909 # this handles some newer cases of free driver temp readouts, will require modifications as
5910 # more user data appears.
5911 elif [[ -n $Sensors_Data ]];then
5919 /^('"$SENSORS_GPU_SEARCH"')-pci/ {
5920 while ( getline && !/^$/ ) {
5922 sub(/^[[:alnum:]]*.*:/, "", $0 ) # clear out everything to the :
5923 gsub(/[\+ \t°]/, "", $1) # ° is a special case, like a space for gawk
5924 gpuTemp=gpuTemp separator $1
5931 }' <<< "$Sensors_Data" )
5934 if [[ -n $gpu_temp ]];then
5939 ## for possible future data, not currently used
5940 get_graphics_agp_data()
5945 if [[ $B_MODULES_FILE == 'true' ]];then
5946 ## not used currently
5947 agp_module=$( gawk '
5948 /agp/ && !/agpgart/ && $3 > 0 {
5949 print(gensub(/(.*)_agp.*/,"\\1","g",$1))
5951 log_function_data 'cat' "$FILE_MODULES"
5953 log_function_data "agp_module: $agp_module"
5957 ## create array of gfx cards installed on system
5958 get_graphics_card_data()
5961 local i='' a_temp=''
5964 A_GRAPHICS_CARD_DATA=( $( gawk -F': ' '
5970 # not using 3D controller yet, needs research: |3D controller |display controller
5971 # note: this is strange, but all of these can be either a separate or the same
5972 # card. However, by comparing bus id, say: 00:02.0 we can determine that the
5973 # cards are either the same or different. We want only the .0 version as a valid
5974 # card. .1 would be for example: Display Adapter with bus id x:xx.1, not the right one
5975 /vga compatible controller|3D controller|Display controller/ {
5976 gsub(/'"$BAN_LIST_NORMAL"'/, "", $NF)
5977 gsub(/'"$BAN_LIST_ARRAY"'/, " ", $NF)
5978 gsub(/^ +| +$/, "", $NF)
5979 gsub(/ [ \t]+/, " ", $NF)
5980 busId=gensub(/^([0-9a-f:\.]+) (.+)$/,"\\1","",$1)
5981 trueCard=gensub(/(.*)\.([0-9]+)$/,"\\2","",busId)
5982 if ( trueCard == 0 ) {
5985 }' <<< "$Lspci_v_Data" ) )
5987 # for (( i=0; i < ${#A_GRAPHICS_CARD_DATA[@]}; i++ ))
5989 # A_GRAPHICS_CARD_DATA[i]=$( sanitize_characters BAN_LIST_NORMAL "${A_GRAPHICS_CARD_DATA[i]}" )
5992 # GFXMEM is UNUSED at the moment, because it shows AGP aperture size, which is not necessarily equal to GFX memory..
5993 # GFXMEM="size=[$(echo "$Lspci_v_Data" | gawk '/VGA/{while (!/^$/) {getline;if (/size=[0-9][0-9]*M/) {size2=gensub(/.*\[size=([0-9]+)M\].*/,"\\1","g",$0);if (size<size2){size=size2}}}}END{print size2}')M]"
5994 a_temp=${A_GRAPHICS_CARD_DATA[@]}
5995 log_function_data "A_GRAPHICS_CARD_DATA: $a_temp"
5999 get_graphics_driver()
6003 # list is from sgfxi plus non-free drivers
6004 local driver_list='amdgpu|apm|ark|ati|chips|cirrus|cyrix|fbdev|fglrx|glint|i128|i740|intel|i810|imstt|mach64|mga|neomagic|nsc|nvidia|nv|openchrome|nouveau|radeon|radeonhd|rendition|s3virge|s3|savage|siliconmotion|sisusb|sis|tdfx|tga|trident|tseng|unichrome|vboxvideo|vesa|vga|via|voodoo|vmware|v4l'
6005 local driver='' driver_string='' xorg_log_data='' status='' a_temp=''
6007 if [[ $B_XORG_LOG == 'true' ]];then
6008 A_GRAPHIC_DRIVERS=( $(
6015 # note that in file names, driver is always lower case
6016 /[[:space:]]Loading.*('"$driver_list"')_drv.so$/ {
6017 driver=gensub(/.*[[:space:]]Loading.*('"$driver_list"')_drv.so/, "\\1", 1, $0 )
6018 # we get all the actually loaded drivers first, we will use this to compare the
6019 # failed/unloaded, which have not always actually been truly loaded
6020 aDrivers[driver]="loaded"
6022 # openbsd uses UnloadModule:
6023 /(Unloading[[:space:]]|UnloadModule).*('"$driver_list"')(\"||_drv.so)$/ {
6025 driver=gensub(/(.*)(Unloading[[:space:]]|UnloadModule).*('"$driver_list"')(\"||_drv.so)$/, "\\3", 1, $0 )
6026 # we need to make sure that the driver has already been truly loaded, not just discussed
6027 if ( driver in aDrivers ) {
6028 aDrivers[driver]="unloaded"
6031 /Failed.*('"$driver_list"')_drv.so|Failed.*\"('"$driver_list"')\"/ {
6032 driver=gensub(/(.*)Failed.*('"$driver_list"')_drv.so/, "\\2", 1, $0 )
6033 if ( driver == $0 ) {
6034 driver=gensub(/(.*)Failed.*\"('"$driver_list"')\".*|fred/, "\\2", 1, $0 )
6036 # we need to make sure that the driver has already been truly loaded, not just discussed
6037 if ( driver != $0 && driver in aDrivers ) {
6038 aDrivers[driver]="failed"
6041 # verify that the driver actually started the desktop, even with false failed messages which can occur
6042 # this is the driver that is actually driving the display
6043 /.*\([0-9]+\):[[:space:]]Depth.*framebuffer/ {
6044 driver=gensub(/.*('"$driver_list"')\([0-9]+\):[[:space:]]Depth.*framebuffer.*/, "\\1", 1, $0 )
6045 # we need to make sure that the driver has already been truly loaded, not just discussed, also
6046 # set driver to lower case because sometimes it will show as RADEON or NVIDIA in the actual x start
6047 driver=tolower(driver)
6048 if ( driver != $0 && driver in aDrivers ) {
6049 aDrivers[driver]="loaded"
6053 for ( driver in aDrivers ) {
6054 print driver "," aDrivers[driver]
6056 }' < $FILE_XORG_LOG ) )
6058 a_temp=${A_GRAPHIC_DRIVERS[@]}
6059 log_function_data "A_GRAPHIC_DRIVERS: $a_temp"
6064 ## create array of glx data
6065 get_graphics_glx_data()
6069 if [[ $B_SHOW_DISPLAY_DATA == 'true' && $B_ROOT != 'true' ]];then
6071 A_GLX_DATA=( $( glxinfo | gawk -F ': ' '
6072 # note: function declarations go before BEGIN? It appears so, confirm.
6073 # the real question here though is why this function is even here, seems
6074 # just to be a complicated way to pack/print a variable, but maybe the
6075 # original idea was to handle > 1 cases of detections I guess
6076 function join( arr, sep ) {
6092 gsub(/'"$BAN_LIST_NORMAL"'/, "", $2)
6093 gsub(/ [ \t]+/, " ", $2) # get rid of the created white spaces
6094 gsub(/^ +| +$/, "", $2)
6095 if ( $2 ~ /mesa/ ) {
6097 # if ( $2 ~ / r[3-9][0-9][0-9] / ) {
6099 # this counter failed in one case, a bug, and is not needed now
6107 # dropping all conditions from this test to just show full mesa information
6108 # there is a user case where not f and mesa apply, atom mobo
6109 # /opengl version/ && ( f || $2 !~ /mesa/ ) {
6111 # fglrx started appearing with this extra string, does not appear to communicate anything of value
6112 sub(/Compatibility Profile Context/, "- CPC", $2 )
6113 gsub(/ [ \t]+/, " ", $2) # get rid of the created white spaces
6114 gsub(/^ +| +$/, "", $2)
6117 /direct rendering/ {
6121 printf( "%s\n%s\n%s\n", join( a, ", " ), join( b, ", " ), join( c, ", " ) )
6125 # GLXR=$(glxinfo | gawk -F ': ' 'BEGIN {IGNORECASE=1} /opengl renderer/ && $2 !~ /mesa/ {seen[$2]++} END {for (i in seen) {printf("%s ",i)}}')
6126 # GLXV=$(glxinfo | gawk -F ': ' 'BEGIN {IGNORECASE=1} /opengl version/ && $2 !~ /mesa/ {seen[$2]++} END {for (i in seen) {printf("%s ",i)}}')
6128 a_temp=${A_GLX_DATA[@]}
6129 log_function_data "A_GLX_DATA: $a_temp"
6133 ## return screen resolution / tty resolution
6134 get_graphics_res_data()
6137 local screen_resolution='' xdpy_data='' screens_count=0 tty_session=''
6139 if [[ $B_SHOW_DISPLAY_DATA == 'true' && $B_ROOT != 'true' ]];then
6140 # Added the two ?'s , because the resolution is now reported without spaces around the 'x', as in
6141 # 1400x1050 instead of 1400 x 1050. Change as of X.org version 1.3.0
6142 xdpy_data="$( xdpyinfo )"
6143 xdpy_count=$( grep -c 'dimensions' <<< "$xdpy_data" )
6144 # we get a bit more info from xrandr than xdpyinfo, but xrandr fails to handle
6145 # multiple screens from different video cards
6146 if [[ $xdpy_count -eq 1 ]];then
6147 screen_resolution=$( xrandr | gawk '
6149 res[++m] = gensub(/^.* ([0-9]+) ?x ?([0-9]+)[_ ].* ([0-9\.]+)\*.*$/,"\\1x\\2@\\3hz","g",$0)
6153 if (res[n] ~ /^[[:digit:]]+x[[:digit:]]+/) {
6154 line = line ? line ", " res[n] : res[n]
6162 if [[ -z $screen_resolution || $xdpy_count -gt 1 ]];then
6163 screen_resolution=$( gawk '
6170 screens = screens separator # first time, this is null, next, has comma last
6171 screens = screens $2 # then tack on the new value for nice comma list
6176 }' <<< "$xdpy_data" )
6179 if [[ $B_PROC_DIR == 'true' && -z $BSD_TYPE ]];then
6180 screen_resolution=$( stty -F $( readlink /proc/$PPID/fd/0 ) size | gawk '{
6183 # note: this works fine for all systems but keeping the above for now since
6184 # the above is probably more accurate for linux systems.
6186 if [[ $B_CONSOLE_IRC != 'true' ]];then
6187 screen_resolution=$( stty -a | gawk -F ';' '
6189 gsub(/[[:space:]]*(rows|columns)[[:space:]]*/,"",$0)
6190 gsub(/[[:space:]]*/,"",$2)
6191 gsub(/[[:space:]]*/,"",$3)
6195 if [[ -n $BSD_TYPE ]];then
6196 tty_session=$( get_tty_console_irc )
6197 # getting information for tty that owns the irc client
6198 screen_resolution="$( stty -f /dev/pts/$tty_session size | gawk '{print $2"x"$1}' )"
6203 echo "$screen_resolution"
6204 log_function_data "screen_resolution: $screen_resolution"
6208 ## create array of display server vendor/version data
6209 get_graphics_display_server_data()
6212 local vendor='' version='' a_temp='' xdpy_info='' a_display_vendor_working=''
6214 if [[ $B_SHOW_DISPLAY_DATA == 'true' && $B_ROOT != 'true' ]];then
6215 # X vendor and version detection.
6216 # new method added since radeon and X.org and the disappearance of <X server name> version : ...etc
6217 # Later on, the normal textual version string returned, e.g. like: X.Org version: 6.8.2
6218 # A failover mechanism is in place. (if $version is empty, the release number is parsed instead)
6219 # xdpy_info="$( xdpyinfo )"
6221 a_display_vendor_working=( $( xdpyinfo | gawk -F': +' '
6229 gsub(/the|inc|foundation|project|corporation/, "", $2)
6230 gsub(/'"$BAN_LIST_ARRAY"'/, " ", $2)
6231 gsub(/^ +| +$/, "", $2)
6232 gsub(/ [ \t]+/, " ", $2)
6238 /vendor release number/ {
6244 print vendorString "," version "," vendorRelease
6246 vendor=${a_display_vendor_working[0]}
6247 version=${a_display_vendor_working[1]}
6249 # this gives better output than the failure last case, which would only show:
6250 # for example: X.org: 1.9 instead of: X.org: 1.9.0
6251 if [[ -z $version ]];then
6252 version=$( get_graphics_display_server_version )
6254 if [[ -z $version ]];then
6255 version=${a_display_vendor_working[2]}
6258 # some distros, like fedora, report themselves as the xorg vendor, so quick check
6259 # here to make sure the vendor string includes Xorg in string
6260 if [[ -z $( grep -E '(X|xorg|x\.org)' <<< $vendor ) ]];then
6261 vendor="$vendor X.org"
6264 A_DISPLAY_SERVER_DATA[0]="$vendor"
6265 A_DISPLAY_SERVER_DATA[1]="$version"
6267 version=$( get_graphics_display_server_version )
6268 if [[ -n $version ]];then
6270 A_DISPLAY_SERVER_DATA[0]="$vendor"
6271 A_DISPLAY_SERVER_DATA[1]="$version"
6274 a_temp=${A_DISPLAY_SERVER_DATA[@]}
6275 log_function_data "A_DISPLAY_SERVER_DATA: $a_temp"
6279 # if other tests fail, try this one, this works for root, out of X also
6280 get_graphics_display_server_version()
6283 local version='' x_data=''
6284 # note that some users can have /usr/bin/Xorg but not /usr/bin/X
6285 if type -p X &>/dev/null;then
6286 # note: MUST be this syntax: X -version 2>&1
6287 # otherwise X -version overrides everything and this comes out null.
6288 # two knowns id strings: X.Org X Server 1.7.5 AND X Window System Version 1.7.5
6289 #X -version 2>&1 | gawk '/^X Window System Version/ { print $5 }'
6290 x_data="$( X -version 2>&1 )"
6291 elif type -p Xorg &>/dev/null;then
6292 x_data="$( Xorg -version 2>&1)"
6294 if [[ -n $x_data ]];then
6304 /^X Window System Version/ {
6310 log_function_data " version: $version"
6314 # this gets just the raw data, total space/percent used and disk/name/per disk capacity
6315 get_hdd_data_basic()
6318 local hdd_used='' a_temp='' df_string=''
6319 local hdd_data='' df_test='' swap_size=0
6321 if [[ -z $BSD_TYPE ]];then
6322 ## NOTE: older df do not have --total (eg: v: 6.10 2008)
6323 ## keep in mind the only value of use with --total is 'used' in blocks, which
6324 ## we can use later to calculate the real percentags based on disk sizes, not
6325 ## mounted partitions. Not using --total because it's more reliable to exclude non /dev
6326 df_string="df -P -T --exclude-type=aufs --exclude-type=devfs --exclude-type=devtmpfs
6327 --exclude-type=fdescfs --exclude-type=iso9660 --exclude-type=linprocfs --exclude-type=nfs
6328 --exclude-type=nfs3 --exclude-type=nfs4 --exclude-type=nfs5 --exclude-type=procfs --exclude-type=smbfs
6329 --exclude-type=squashfs --exclude-type=sysfs --exclude-type=tmpfs --exclude-type=unionfs"
6330 if swapon -s &>/dev/null;then
6331 swap_size=$( swapon -s 2>/dev/null | gawk '
6336 ( $2 == "partition" ) && ( $3 ~ /^[0-9]+$/ ) {
6337 total += ( 1000 / 1024 ) * $3
6340 # result in kB, change to 1024 Byte blocks
6341 total = total * 1000 / 1024
6342 total = sprintf( "%.1f", total )
6347 # default size is 512, , so use -k for 1024 -H only for size in human readable format
6348 # older bsds don't support -T, pain, so we'll use partial output there
6349 if df -k -T &>/dev/null;then
6350 df_string='df -k -T'
6354 if swapctl -l -k &>/dev/null;then
6355 swap_size=$( swapctl -l -k 2>/dev/null | gawk '
6360 ( $1 ~ /^\/dev/ ) && ( $2 ~ /^[0-9]+$/ ) {
6364 # result in blocks already
6369 # echo ss: $swap_size
6370 hdd_data="$( eval $df_string )"
6371 # eval $df_string | awk 'BEGIN{tot=0} !/total/ {tot+=$4} END{print tot}'
6372 log_function_data 'raw' "hdd_data:\n$hdd_data"
6373 hdd_used=$( echo "$hdd_data" | gawk -v bsdType="$BSD_TYPE" -v swapSize="$swap_size" '
6375 # this is used for specific cases where bind, or incorrect multiple mounts to same partitions,
6376 # is present. The value is searched for an earlier appearance of that partition and if it is
6377 # present, the data is not added into the partition used size.
6379 # this handles a case where the same dev item is mounted twice to different points
6385 # using $1, not $2, because older bsd df do not have -T, filesystem type
6386 ( bsdType != "" ) && $1 ~ /^(aufs|devfs|devtmpfs|fdescfs|filesystem|iso9660|linprocfs|nfs|nfs3|nfs4|nfs5|procfs|squashfs|smbfs|sysfs|tmpfs|type|unionfs)$/ {
6387 # note use next, not getline or it does not work right
6390 # also handles odd dm-1 type, from lvm, and mdraid, and some other bsd partition syntax
6391 # note that linux 3.2.45-grsec-9th types kernels have this type of partition name: /dev/xvdc (no number, letter)
6392 # note: btrfs does not seem to use partition integers, just the primary /dev/sdx identifier
6393 # df can also show /dev/disk/(by-label|by-uuid etc)
6394 /^\/dev\/(disk\/|mapper\/|[hsv]d[a-z]+[0-9]*|dm[-]?[0-9]+|(ada|mmcblk|nvme[0-9]+n)[0-9]+p[0-9]+.*|(ad|sd|wd)[0-9]+[a-z]|md[0-9]+|[aw]d[0-9]+s.*|xvd[a-z]+)|^ROOT/ {
6395 # this handles the case where the first item is too long
6396 # and makes df wrap output to next line, so here we advance
6397 # it to the next line for that single case. Using df -P should
6398 # make this unneeded but leave it in just in case
6399 if ( NF < 6 && $0 !~ /.*%/ ) {
6400 devSet = devSet "~" $1 "~"
6403 # if the first item caused a wrap, use one less than standard
6404 # testing for the field with % in it, ie: 34%, then go down from there
6405 # this also protects against cases where the mount point has a space in the
6406 # file name, thus breaking going down from $NF directly.
6407 # some bsds will also have only 6 items
6409 devWorking="~" $1 "~"
6410 mountWorking="~" $6 "~"
6411 if ( partitionsSet !~ mountWorking && devSet !~ devWorking ) {
6414 partitionsSet = partitionsSet mountWorking
6415 # make sure to only include bsd real lines here, ie, short df output
6416 if ( $1 ~ /^\/dev\// ) {
6417 devSet = devSet devWorking
6420 # otherwise use standard
6421 else if ( $6 ~ /.*%/ ) {
6422 devWorking="~" $1 "~"
6423 mountWorking="~" $7 "~"
6424 if ( partitionsSet !~ mountWorking && devSet !~ devWorking ) {
6427 partitionsSet = partitionsSet mountWorking
6428 devSet = devSet devWorking
6430 # and if this is not detected, give up, we need user data to debug
6436 used=used + swapSize
6437 used = sprintf( "%.1f", used )
6440 # echo hdu:$hdd_used
6441 if [[ -z $hdd_used ]];then
6444 log_function_data "hdd_used: $hdd_used"
6445 # create the initial array strings:
6446 # disk-dev, capacity, name, usb or not
6447 # final item is the total of the disk
6450 if [[ $B_PARTITIONS_FILE == 'true' ]];then
6452 gawk -v hddUsed=$hdd_used '
6453 /([hsv]d[a-z]+|(ada|mmcblk|nvme[0-9]+n)[0-9]+)$/ {
6454 driveSize = $(NF - 1)*1024/1000**3
6455 gsub(/'"$BAN_LIST_ARRAY"'/, " ", driveSize)
6456 gsub(/^ +| +$/, "", driveSize)
6457 printf( $NF",%.1fGB,,\n", driveSize )
6459 # See http://lanana.org/docs/device-list/devices-2.6+.txt for major numbers used below
6460 # $1 ~ /^(3|22|33|8)$/ && $2 % 16 == 0 {
6463 # special case from this data: 8 0 156290904 sda
6464 # note: vm has 252/253/254 known starter, grsec has 202
6465 $1 ~ /^(3|8|22|33|202|252|253|254)$/ && $NF ~ /[hsv]d[a-z]+$/ && ( $2 % 16 == 0 || $2 % 16 == 8 ) {
6469 size = size*1024/1000**3 # calculate size in GB size
6470 workingUsed = hddUsed*1024/1000**3 # calculate workingUsed in GB used
6471 # this handles a special case with livecds where no hdd_used is detected
6472 if ( size > 0 && hddUsed == "na" ) {
6473 size = sprintf( "%.1f", size )
6474 print size "GB,-,,.."
6476 else if ( size > 0 && workingUsed > 0 ) {
6477 diskUsed = workingUsed*100/size # calculate used percentage
6478 diskUsed = sprintf( "%.1f", diskUsed )
6479 if ( int(diskUsed) > 100 ) {
6480 diskUsed = "Used Error!"
6483 diskUsed = diskUsed "% used"
6485 size = sprintf( "%.1f", size )
6486 print size "GB," diskUsed ",,.."
6489 print "NA,-,,.." # print an empty array, this will be further handled in the print out function
6491 }' $FILE_PARTITIONS ) )
6492 log_function_data 'cat' "$FILE_PARTITIONS"
6494 if [[ -n $BSD_TYPE ]];then
6495 get_hard_drive_data_bsd "$hdd_used"
6499 a_temp=${A_HDD_DATA[@]}
6501 log_function_data "A_HDD_DATA: $a_temp"
6505 ## fills out the A_HDD_DATA array with disk names
6506 get_hard_drive_data_advanced()
6509 local a_temp_working='' a_temp_scsi='' temp_holder='' temp_name='' i='' j=''
6510 local sd_ls_by_id='' ls_disk_by_id='' ls_disk_by_path='' usb_exists='' a_temp=''
6511 local firewire_exists='' thunderbolt_exists='' thunderbolt_exists='' hdd_temp hdd_serial=''
6513 ## check for all ide type drives, non libata, only do it if hdx is in array
6514 ## this is now being updated for new /sys type paths, this may handle that ok too
6515 if [[ -n $( grep -E 'hd[a-z]' <<< ${A_HDD_DATA[@]} ) ]];then
6516 # remember, we're using the last array item to store the total size of disks
6517 for (( i=0; i < ${#A_HDD_DATA[@]} - 1; i++ ))
6520 a_temp_working=( ${A_HDD_DATA[i]} )
6522 if [[ -n $( grep -E '^hd[a-z]' <<< ${a_temp_working[0]} ) ]];then
6523 if [[ -e /proc/ide/${a_temp_working[0]}/model ]];then
6524 a_temp_working[2]="$( remove_erroneous_chars /proc/ide/${a_temp_working[0]}/model )"
6526 a_temp_working[2]="Name n/a"
6528 # these loops are to easily extend the cpu array created in the gawk script above with more fields per cpu.
6529 for (( j=0; j < ${#a_temp_working[@]}; j++ ))
6531 if [[ $j -gt 0 ]];then
6532 A_HDD_DATA[i]="${A_HDD_DATA[i]},${a_temp_working[$j]}"
6534 A_HDD_DATA[i]="${a_temp_working[$j]}"
6541 ## then handle libata names
6542 # first get the ata device names, put them into an array
6544 if [[ $B_SCSI_FILE == 'true' ]]; then
6545 a_temp_scsi=( $( gawk '
6555 if (b[i] ~ / *type: *direct-access.*/) {
6556 #c=gensub(/^ *vendor: (.+) +model: (.+) +rev: (.+)$/,"\\1 \\2 \\3","g",a[i])
6557 #c=gensub( /^ *vendor: (.+) +model: (.+) +rev:.*$/,"\\1 \\2","g",a[i] )
6558 # the vendor: string is useless, and is a bug, ATA is not a vendor for example
6559 c=gensub( /^ *vendor: (.+) +model: (.+) +rev:.*$/, "\\2", "g", a[i] )
6560 gsub(/'"$BAN_LIST_ARRAY"'/, " ", c)
6561 gsub(/^ +| +$/, "", c)
6562 gsub(/ [ \t]+/, " ", c)
6564 # we actually want this data, so leaving this off for now
6565 # if (c ~ /\<flash\>|\<pendrive\>|memory stick|memory card/) {
6572 log_function_data 'cat' "$FILE_SCSI"
6576 ## then we'll loop through that array looking for matches.
6577 if [[ -n $( grep -E 'sd[a-z]' <<< ${A_HDD_DATA[@]} ) ]];then
6578 # first pack the main ls variable so we don't have to keep using ls /dev...
6579 # not all systems have /dev/disk/by-id
6580 ls_disk_by_id="$( ls -l /dev/disk/by-id 2>/dev/null )"
6581 ls_disk_by_path="$( ls -l /dev/disk/by-path 2>/dev/null )"
6582 for (( i=0; i < ${#A_HDD_DATA[@]} - 1; i++ ))
6584 if [[ -n $( grep -E '^sd[a-z]' <<< ${A_HDD_DATA[$i]} ) ]];then
6586 a_temp_working=( ${A_HDD_DATA[$i]} )
6588 # /sys/block/[sda,hda]/device/model
6589 # this is handles the new /sys data types first
6590 if [[ -e /sys/block/${a_temp_working[0]}/device/model ]];then
6591 temp_name="$( remove_erroneous_chars /sys/block/${a_temp_working[0]}/device/model )"
6592 temp_name=$( cut -d '-' -f 1 <<< ${temp_name// /_} )
6593 elif [[ ${#a_temp_scsi[@]} -gt 0 ]];then
6594 for (( j=0; j < ${#a_temp_scsi[@]}; j++ ))
6596 ## ok, ok, it's incomprehensible, search /dev/disk/by-id for a line that contains the
6597 # discovered disk name AND ends with the correct identifier, sdx
6598 # get rid of whitespace for some drive names and ids, and extra data after - in name
6599 temp_name=$( cut -d '-' -f 1 <<< ${a_temp_scsi[$j]// /_} )
6600 sd_ls_by_id=$( grep -Em1 ".*$temp_name.*${a_temp_working[0]}$" <<< "$ls_disk_by_id" )
6601 if [[ -n $sd_ls_by_id ]];then
6602 temp_name=${a_temp_scsi[$j]}
6605 # test to see if we can get a better name output when null
6606 if [[ -n $temp_name ]];then
6607 temp_name=$temp_name
6613 if [[ -z $temp_name ]];then
6614 temp_name="Name n/a"
6615 # maybe remove this from the conditional, detection of usb may not depend on the name
6617 usb_exists=$( grep -Em1 "usb-.*$temp_name.*${a_temp_working[0]}$" <<< "$ls_disk_by_id" )
6618 firewire_exists=$( grep -Em1 "ieee1394-.*$temp_name.*${a_temp_working[0]}$" <<< "$ls_disk_by_id" )
6619 # thunderbolt_exists=$( grep -Em1 "ieee1394-.*$temp_name.*${a_temp_working[0]}$" <<< "$ls_disk_by_id" )
6620 # note: sometimes with wwn- numbering usb does not appear in by-id but it does in by-path
6621 if [[ -z $usb_exists ]];then
6622 usb_exists=$( grep -Em1 "usb-.*${a_temp_working[0]}$" <<< "$ls_disk_by_path" )
6624 if [[ -n $usb_exists ]];then
6625 a_temp_working[3]='USB'
6627 if [[ -z $firewire_exists ]];then
6628 firewire_exists=$( grep -Em1 "ieee1394-.*${a_temp_working[0]}$" <<< "$ls_disk_by_path" )
6630 if [[ -n $firewire_exists ]];then
6631 a_temp_working[3]='FireWire'
6634 a_temp_working[2]=$temp_name
6635 # these loops are to easily extend the cpu array created in the gawk script above with more fields per cpu.
6636 for (( j=0; j < ${#a_temp_working[@]}; j++ ))
6638 if [[ $j -gt 0 ]];then
6639 A_HDD_DATA[i]="${A_HDD_DATA[i]},${a_temp_working[$j]}"
6641 A_HDD_DATA[i]="${a_temp_working[$j]}"
6645 if [[ $B_EXTRA_DATA == 'true' ]];then
6647 a_temp_working=( ${A_HDD_DATA[i]} )
6648 # echo "a:" ${a_temp_working[@]}
6652 if [[ -n ${a_temp_working[1]} ]];then
6653 hdd_temp=$( get_hdd_temp_data "/dev/${a_temp_working[0]}" )
6655 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
6656 hdd_serial=$( get_hdd_serial_number "${a_temp_working[0]}" )
6658 A_HDD_DATA[i]="${a_temp_working[0]},${a_temp_working[1]},${a_temp_working[2]},${a_temp_working[3]},$hdd_serial,$hdd_temp"
6659 # echo b: ${A_HDD_DATA[i]}
6663 a_temp=${A_HDD_DATA[@]}
6664 log_function_data "A_HDD_DATA: $a_temp"
6668 # args: $1 ~ hdd_used
6669 get_hard_drive_data_bsd()
6675 if [[ -n $Dmesg_Boot_Data ]];then
6677 A_HDD_DATA=( $( gawk -v hddUsed="$1" -F ':' '
6683 $1 ~ /^(ad|ada|mmcblk|nvme[0-9]+n|sd|wd)[0-9]+(|[[:space:]]at.*)$/ {
6684 diskId=gensub(/^((ad|ada|mmcblk|nvme[0-9]+n|sd|wd)[0-9]+)[^0-9].*/,"\\1",1,$1)
6685 # note: /var/run/dmesg.boot may repeat items since it is not created
6686 # fresh every boot, this way, only the last items will be used per disk id
6687 if (aIds[diskId] == "" ) {
6689 if ( $0 !~ /raid/) {
6693 aDisks[diskId, "id"] = diskId
6694 if ($0 ~ /[^0-9][0-9\.]+[[:space:]]*[MG]B/ && $0 !~ /MB\/s/) {
6695 workingSize=gensub(/.*[^0-9]([0-9\.]+[[:space:]]*[MG]B).*/,"\\1",1,$0)
6696 if (workingSize ~ /GB/ ) {
6697 sub(/[[:space:]]*GB/,"",workingSize)
6698 workingSize=workingSize*1000
6700 else if (workingSize ~ /MB/ ) {
6701 sub(/[[:space:]]*MB/,"",workingSize)
6702 workingSize=workingSize
6704 aDisks[diskId, "size"] = workingSize
6705 if ( bSetSize == "true" ) {
6706 if ( workingSize != "" ){
6707 size=size+workingSize
6712 if ( $NF ~ /<.*>/ ){
6713 gsub(/.*<|>.*/,"",$NF)
6714 aDisks[diskId, "model"] = $NF
6716 if ( $NF ~ /serial number/ ){
6717 sub(/serial[[:space:]]+number[[:space:]]*/,"",$NF)
6718 aDisks[diskId, "serial"] = $NF
6722 # sde,3.9GB,STORE_N_GO,USB,C200431546D3CF49-0:0,0
6723 # sdd,250.1GB,ST3250824AS,,9ND08GKX,45
6724 # multi dimensional pseudo arrays are sorted at total random, not in order of
6725 # creation, so force a sort of the aIds, which deletes the array index but preserves
6729 for ( key in aIds ) {
6730 # we are not adding to size above for raid, and we do not print it for raid
6731 # this is re openbsd raid, which uses sd0 for raid array, even though sd is for scsi
6732 if ( aDisks[aIds[key], "model"] !~ /raid/ ) {
6733 workingSize = aDisks[aIds[key], "size"]/1000
6734 workingSize = sprintf( "%.1fGB", workingSize )
6735 print aDisks[aIds[key], "id"] "," workingSize "," aDisks[aIds[key], "model"] "," "," aDisks[aIds[key], "serial"] ","
6738 size = size/1000 # calculate size in GB size
6740 workingUsed = hddUsed*1024/1000**3 # calculate workingUsed in GB used
6741 # this handles a special case with livecds where no hdd_used is detected
6742 if ( size > 0 && hddUsed == "na" ) {
6743 size = sprintf( "%.1f", size )
6744 print size "GB,-,,.."
6746 else if ( size > 0 && workingUsed > 0 ) {
6747 diskUsed = workingUsed*100/size # calculate used percentage
6748 diskUsed = sprintf( "%.1f", diskUsed )
6749 if ( int(diskUsed) > 100 ) {
6750 diskUsed = "Used Error!"
6753 diskUsed = diskUsed "% used"
6755 size = sprintf( "%.1f", size )
6756 print size "GB," diskUsed ",,.."
6759 print "NA,-,,.." # print an empty array, this will be further handled in the print out function
6761 }' <<< "$Dmesg_Boot_Data" ) )
6765 a_temp=${A_HDD_DATA[@]}
6767 log_function_data "A_HDD_DATA: $a_temp"
6772 # args: $1 - which drive to get serial number of
6773 get_hdd_serial_number()
6779 get_partition_dev_data 'id'
6781 # lrwxrwxrwx 1 root root 9 Apr 26 09:32 scsi-SATA_ST3160827AS_5MT2HMH6 -> ../../sdc
6782 # exit on the first instance
6783 hdd_serial=$( gawk '
6785 serial=gensub( /^(.+)_([^_]+)$/, "\\2", 1, $9 )
6788 }' <<< "$DEV_DISK_ID" )
6791 log_function_data "hdd serial: $hdd_serial"
6795 # a few notes, normally hddtemp requires root, but you can set user rights in /etc/sudoers.
6796 # args: $1 - /dev/<disk> to be tested for
6800 local hdd_temp='' sudo_command=''
6802 if [[ $B_HDDTEMP_TESTED != 'true' ]];then
6803 B_HDDTEMP_TESTED='true'
6804 HDDTEMP_PATH=$( type -p hddtemp )
6806 if [[ $B_SUDO_TESTED != 'true' ]];then
6807 B_SUDO_TESTED='true'
6808 SUDO_PATH=$( type -p sudo )
6811 if [[ -n $HDDTEMP_PATH && -n $1 ]];then
6812 # only use sudo if not root, -n option requires sudo -V 1.7 or greater. sudo will just error out
6813 # which is the safest course here for now, otherwise that interactive sudo password thing is too annoying
6814 # important: -n makes it non interactive, no prompt for password
6815 if [[ $B_ROOT != 'true' && -n $SUDO_PATH ]];then
6816 sudo_command='sudo -n '
6818 # this will fail if regular user and no sudo present, but that's fine, it will just return null
6819 hdd_temp=$( eval $sudo_command $HDDTEMP_PATH -nq -u C $1 )
6820 if [[ -n $hdd_temp && -n $( grep -E '^([0-9\.]+)$' <<< $hdd_temp ) ]];then
6831 local init_type='' init_version='' rc_type='' rc_version='' a_temp=''
6832 local ls_run='' strings_init_version=''
6833 local runlevel=$( get_runlevel_data )
6834 local default_runlevel=$( get_runlevel_default )
6836 # this test is pretty solid, if pid 1 is owned by systemd, it is systemd
6837 # otherwise that is 'init', which covers the rest of the init systems, I think anyway.
6838 # more data may be needed for other init systems.
6839 if [[ -e /proc/1/comm && -n $( grep -s 'systemd' /proc/1/comm ) ]];then
6841 if type -p systemd &>/dev/null;then
6842 init_version=$( get_program_version 'systemd' '^systemd' '2' )
6844 if [[ -z $init_version ]];then
6845 if type -p systemctl &>/dev/null;then
6846 init_version=$( get_program_version 'systemctl' '^systemd' '2' )
6851 # note: upstart-file-bridge.pid upstart-socket-bridge.pid upstart-udev-bridge.pid
6852 if [[ -n $( /sbin/init --version 2>/dev/null | grep 'upstart' ) ]];then
6854 # /sbin/init --version == init (upstart 1.12.1)
6855 init_version=$( get_program_version 'init' 'upstart' '3' )
6856 elif [[ -e /proc/1/comm && -n $( grep -s 'epoch' /proc/1/comm ) ]];then
6858 # epoch version == Epoch Init System 1.0.1 "Sage"
6859 init_version=$( get_program_version 'epoch' '^Epoch' '4' )
6860 # missing data: note, runit can install as a dependency without being the init system
6861 # http://smarden.org/runit/sv.8.html
6862 # NOTE: the proc test won't work on bsds, so if runit is used on bsds we will need more data
6863 elif [[ -e /proc/1/comm && -n $( grep -s 'runit' /proc/1/comm ) ]];then
6864 # elif [[ -e /sbin/runit-init || -e /etc/runit || -n $( type -p sv ) ]];then
6865 init_type='runit' # lower case
6866 # no data on version yet
6868 elif type -p launchctl &>/dev/null;then
6870 # / launchd/ version.plist /etc/launchd.conf
6871 # init_version=$( get_program_version 'Launchd' '^Launchd' '4' )
6872 elif [[ -f /etc/inittab ]];then
6873 init_type='SysVinit'
6874 if type -p strings &>/dev/null;then
6875 strings_init_version="$( strings /sbin/init | grep -E 'version[[:space:]]+[0-9]' )"
6877 if [[ -n $strings_init_version ]];then
6878 init_version=$( gawk '{print $2}' <<< "$strings_init_version" )
6880 elif [[ -f /etc/ttys ]];then
6881 init_type='init (bsd)'
6883 if [[ -n $( grep 'openrc' <<< "$ls_run" ) ]];then
6885 # /sbin/openrc --version == openrc (OpenRC) 0.13
6886 if type -p openrc &>/dev/null;then
6887 rc_version=$( get_program_version 'openrc' '^openrc' '3' )
6888 # /sbin/rc --version == rc (OpenRC) 0.11.8 (Gentoo Linux)
6889 elif type -p rc &>/dev/null;then
6890 rc_version=$( get_program_version 'rc' '^rc' '3' )
6892 if [[ -e /run/openrc/softlevel ]];then
6893 runlevel=$( cat /run/openrc/softlevel 2>/dev/null )
6894 elif [[ -e /var/run/openrc/softlevel ]];then
6895 runlevel=$( cat /var/run/openrc/softlevel 2>/dev/null )
6896 elif type -p rc-status &>/dev/null;then
6897 runlevel=$( rc-status -r 2>/dev/null )
6899 ## assume sysvrc, but this data is too buggy and weird and inconsistent to have meaning
6900 # leaving this off for now
6901 # elif [[ -f /etc/inittab ]];then
6903 # # this is a guess that rc and init are same versions, may need updates / fixes
6904 # rc_version=$init_version
6915 "$default_runlevel" )
6919 a_temp=${A_INIT_DATA[@]}
6920 log_function_data "A_INIT_DATA: $a_temp"
6925 get_kernel_compiler_version()
6927 # note that we use gawk to get the last part because beta, alpha, git versions can be non-numeric
6928 local compiler_version='' compiler_type=''
6930 if [[ -e /proc/version ]];then
6931 compiler_version=$( grep -Eio 'gcc[[:space:]]*version[[:space:]]*([^ \t]*)' /proc/version 2>/dev/null | gawk '{print $3}' )
6932 if [[ -n $compiler_version ]];then
6936 if [[ $BSD_VERSION == 'darwin' ]];then
6937 if type -p gcc &>/dev/null;then
6938 compiler_version=$( get_program_version 'gcc' 'Apple[[:space:]]LLVM' '4' )
6939 if [[ -n $compiler_version ]];then
6940 compiler_type='LLVM-GCC'
6944 if [[ -f /etc/src.conf ]];then
6945 compiler_type=$( grep '^CC' /etc/src.conf | cut -d '=' -f 2 )
6946 elif [[ -f /etc/make.conf ]];then
6947 compiler_type=$( grep '^CC' /etc/make.conf | cut -d '=' -f 2 )
6949 if [[ -n $compiler_type ]];then
6950 if type -p $compiler_type &>/dev/null;then
6951 if [[ $compiler_type == 'gcc' ]];then
6952 compiler_version=$( get_program_version 'gcc' '^gcc' '3' )
6953 elif [[ $compiler_type == 'clang' ]];then
6954 # FreeBSD clang version 3.0 (tags/RELEASE_30/final 145349) 20111210
6955 compiler_version=$( get_program_version 'clang' 'clang' '4' )
6961 if [[ -n $compiler_version ]];then
6962 compiler_version="$compiler_type^$compiler_version"
6964 echo $compiler_version
6968 get_kernel_version()
6972 local kernel_version='' ksplice_kernel_version=''
6974 kernel_version=$( uname -rm )
6975 if [[ $BSD_VERSION == 'darwin' ]];then
6976 kernel_version="Darwin $kernel_version"
6978 if [[ -n $( type -p uptrack-uname ) && -n $kernel_version ]];then
6979 ksplice_kernel_version=$( uptrack-uname -rm )
6980 if [[ $kernel_version != $ksplice_kernel_version ]];then
6981 kernel_version="$ksplice_kernel_version (ksplice)"
6984 log_function_data "kernel_version: $kernel_version - ksplice_kernel_version: $ksplice_kernel_version"
6986 echo $kernel_version
6997 if [[ $B_LSPCI == 'true' ]];then
6998 lspci_data="$( lspci -$1 | gawk '{
6999 gsub(/\(prog-if[^)]*\)/,"")
7000 sub(/^0000:/, "", $0) # seen case where the 0000: is prepended, rare, but happens
7006 log_function_data 'raw' "lspci_data $1:\n$lspci_data"
7022 }' <<< "$Lspci_n_Data" )
7032 local a_temp='' separator='' id_file='' file_data='' array_string=''
7033 local id_dir='/sys/class/dmi/id/' dmi_data=''
7034 local machine_files="
7035 sys_vendor product_name product_version product_serial product_uuid
7036 board_vendor board_name board_version board_serial
7037 bios_vendor bios_version bios_date
7039 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
7040 machine_files="$machine_files
7041 chassis_vendor chassis_type chassis_version chassis_serial
7044 if [[ -d $id_dir && $B_FORCE_DMIDECODE == 'false' ]];then
7045 for id_file in $machine_files
7048 if [[ -r $id_dir$id_file ]];then
7054 gsub(/'"$BAN_LIST_NORMAL"'/, "", $0)
7055 gsub(/'"$BAN_LIST_ARRAY"'/, " ", $0)
7056 # yes, there is a typo in a user data set, unknow
7057 # Base Board Version|Base Board Serial Number
7058 # Chassis Manufacturer|Chassis Version|Chassis Serial Number
7059 # System manufacturer|System Product Name|System Version
7060 # To Be Filled By O.E.M.
7061 sub(/^Base Board .*|^Chassis .*|.*O\.E\.M\..*|.*OEM.*|^Not .*|^System .*|.*unknow.*|.*N\/A.*|none|^To be filled.*/, "", $0)
7062 gsub(/bios|acpi/, "", $0)
7063 sub(/http:\/\/www.abit.com.tw\//, "Abit", $0)
7064 gsub(/^ +| +$/, "", $0)
7065 gsub(/ [ \t]+/, " ", $0)
7067 }' < $id_dir$id_file )
7069 array_string="$array_string$separator$file_data"
7074 if [[ -n $DMIDECODE_DATA ]];then
7075 if [[ $DMIDECODE_DATA == 'dmidecode-error-'* ]];then
7076 array_string=$DMIDECODE_DATA
7077 # please note: only dmidecode version 2.11 or newer supports consistently the -s flag
7079 array_string=$( gawk -F ':' '
7082 baseboardManufacturer=""
7083 baseboardProductName=""
7084 baseboardSerialNumber=""
7087 biosRevision="" # only available from dmidecode
7088 biosRomSize="" # only available from dmidecode
7091 chassisManufacturer=""
7092 chassisSerialNumber=""
7095 systemManufacturer=""
7096 systemProductName=""
7098 systemSerialNumber=""
7100 bItemFound="" # we will only output if at least one item was found
7108 /^Bios Information/ {
7109 while ( getline && !/^$/ ) {
7110 if ( $1 ~ /^Release Date/ ) { biosReleaseDate=$2 }
7111 if ( $1 ~ /^BIOS Revision/ ) { biosRevision=$2 }
7112 if ( $1 ~ /^ROM Size/ ) { biosRomSize=$2 }
7113 if ( $1 ~ /^Vendor/ ) { biosVendor=$2 }
7114 if ( $1 ~ /^Version/ ) { biosVersion=$2 }
7116 testString=biosReleaseDate biosRevision biosRomSize biosVendor biosVersion
7117 if ( testString != "" ) {
7122 /^Base Board Information/ {
7123 while ( getline && !/^$/ ) {
7124 if ( $1 ~ /^Manufacturer/ ) { baseboardManufacturer=$2 }
7125 if ( $1 ~ /^Product Name/ ) { baseboardProductName=$2 }
7126 if ( $1 ~ /^Serial Number/ ) { baseboardSerialNumber=$2 }
7128 testString=baseboardManufacturer baseboardProductName baseboardSerialNumber
7129 if ( testString != "" ) {
7134 /^Chassis Information/ {
7135 while ( getline && !/^$/ ) {
7136 if ( $1 ~ /^Manufacturer/ ) { chassisManufacturer=$2 }
7137 if ( $1 ~ /^Serial Number/ ) { chassisSerialNumber=$2 }
7138 if ( $1 ~ /^Type/ ) { chassisType=$2 }
7139 if ( $1 ~ /^Version/ ) { chassisVersion=$2 }
7141 testString=chassisManufacturer chassisSerialNumber chassisType chassisVersion
7142 if ( testString != "" ) {
7147 /^System Information/ {
7148 while ( getline && !/^$/ ) {
7149 if ( $1 ~ /^Manufacturer/ ) { systemManufacturer=$2 }
7150 if ( $1 ~ /^Product Name/ ) { systemProductName=$2 }
7151 if ( $1 ~ /^Version/ ) { systemVersion=$2 }
7152 if ( $1 ~ /^Serial Number/ ) { systemSerialNumber=$2 }
7153 if ( $1 ~ /^UUID/ ) { systemUuid=$2 }
7155 testString=systemManufacturer systemProductName systemVersion systemSerialNumber systemUuid
7156 if ( testString != "" ) {
7161 ( bSys == "true" && bCha="true" && bBio == "true" && bBas == "true" ) {
7162 exit # stop the loop
7165 # sys_vendor product_name product_version product_serial product_uuid
7166 # board_vendor board_name board_version board_serial
7167 # bios_vendor bios_version bios_date
7168 if ( bItemFound == "true" ) {
7169 fullString = systemManufacturer "," systemProductName "," systemVersion "," systemSerialNumber
7170 fullString = fullString "," systemUuid "," baseboardManufacturer "," baseboardProductName
7171 fullString = fullString "," baseboardVersion "," baseboardSerialNumber "," biosVendor
7172 fullString = fullString "," biosVersion "," biosReleaseDate "," chassisManufacturer
7173 fullString = fullString "," chassisType "," chassisVersion "," chassisSerialNumber
7174 fullString = fullString "," biosRevision "," biosRomSize
7178 }' <<< "$DMIDECODE_DATA" )
7182 # echo $array_string
7184 A_MACHINE_DATA=( $array_string )
7186 # echo ${A_MACHINE_DATA[5]}
7187 a_temp=${A_MACHINE_DATA[@]}
7189 log_function_data "A_MACHINE_DATA: $a_temp"
7192 # B_ROOT='true';get_machine_data;exit
7193 ## return memory used/installed
7197 local memory='' memory_full='' used_memory=''
7198 if [[ $B_MEMINFO_FILE == 'true' ]];then
7203 /^(MemFree|Buffers|Cached):/ {
7207 used = tot - notused
7208 printf("%.1f/%.1fMB\n", used/1024, tot/1024)
7210 log_function_data 'cat' "$FILE_MEMINFO"
7211 elif [[ $B_SYSCTL == 'true' && -n $Sysctl_a_Data ]];then
7213 # darwin sysctl is broken and uses both : and = and repeats these items
7214 if [[ $BSD_VERSION == 'openbsd' ]];then
7217 # use this for all bsds, maybe we can get some useful data on other ones
7218 if [[ -n $( type -p vmstat) ]];then
7219 # avail mem:2037186560 (1942MB)
7220 used_memory=$( vmstat 2>/dev/null | tail -n 1 | gawk '
7222 # procs memory page disks traps cpu
7223 # r b w avm fre flt re pi po fr sr wd0 wd1 int sys cs us sy id
7224 # 0 0 0 55256 1484092 171 0 0 0 0 0 2 0 12 460 39 3 1 96
7226 # procs memory page disks faults cpu
7227 # r b w avm fre flt re pi po fr sr ad0 ad1 in sy cs us sy id
7228 # 0 0 0 21880M 6444M 924 32 11 0 822 827 0 0 853 832 463 8 3 88
7230 # procs memory page disks faults cpu
7231 # r b w avm fre flt re pi po fr sr ad0 ad1 in sy cs us sy id
7232 # 0 0 0 0 84060 30273993 2845 12742 1164 407498171 320960902 0 0 424453025 1645645889 1254348072 35 38 26
7243 else if ($4 ~ /G/ ){
7249 # dragonfly can have 0 avm, but they may fix that so make test dynamic
7261 # for dragonfly, we will use free mem, not used because free is 0
7262 memory=$( grep -i 'mem' <<< "$Sysctl_a_Data" | gawk -v usedMemory="$used_memory" -F "$gawk_fs" '
7267 # freebsd seems to use bytes here
7268 /^hw.physmem/ && ( realMemory == "" ) {
7269 gsub(/^[^0-9]+|[^0-9]+$/,"",$2)
7270 realMemory = $2/1024
7271 if ( freeMemory != "" ) {
7275 # But, it uses K here. Openbsd does not seem to have this item
7276 # this can be either: Free Memory OR Free Memory Pages
7277 $1 ~ /^Free Memory/ {
7278 gsub(/[^0-9]/,"",$NF)
7280 if ( realMemory != "" ) {
7285 # hack: temp fix for openbsd/darwin: in case no free mem was detected but we have physmem
7286 if ( freeMemory == "" && realMemory != "" ) {
7287 # use openbsd/dragonfly avail mem data if available
7288 if (usedMemory != "" ) {
7289 if (usedMemory !~ /^avm-0-/ ) {
7290 printf("%.1f/%.1fMB\n", usedMemory/1024, realMemory/1024)
7293 sub(/avm-0-/,"",usedMemory)
7295 # using free mem, not used for dragonfly
7296 usedMemory = realMemory - usedMemory
7297 printf("%.1f/%.1fMB\n", usedMemory/1024, realMemory/1024)
7301 printf("NA/%.1fMB\n", realMemory/1024)
7304 else if ( freeMemory != "" && realMemory != "" ) {
7305 used = realMemory - freeMemory
7306 printf("%.1f/%.1fMB\n", used/1024, realMemory/1024)
7311 log_function_data "memory: $memory"
7315 # process and return module version data
7316 get_module_version_number()
7319 local module_version=''
7321 if [[ $B_MODINFO_TESTED != 'true' ]];then
7322 B_MODINFO_TESTED='true'
7323 MODINFO_PATH=$( type -p modinfo )
7326 if [[ -n $MODINFO_PATH ]];then
7327 module_version=$( $MODINFO_PATH $1 2>/dev/null | gawk '
7332 gsub(/'"$BAN_LIST_ARRAY"'/, " ", $2)
7333 gsub(/^ +| +$/, "", $2)
7334 gsub(/ [ \t]+/, " ", $2)
7340 echo "$module_version"
7341 log_function_data "module_version: $module_version"
7346 ## create array of network cards
7347 get_networking_data()
7351 local B_USB_NETWORKING='false' a_temp=''
7355 echo "$Lspci_v_Data" | gawk '
7356 # NOTE: see version 2.1.28 or earlier for old logic if for some reason it is needed again
7357 # that used a modified string made from nic name for index, why, I have no idea, makes no sense and leads
7358 # to wrong ordered output as well. get_audio_data uses the old logic for now too.
7363 /^[0-9a-f:\.]+ ((ethernet|network) (controller|bridge)|infiniband)/ || /^[0-9a-f:\.]+ [^:]+: .*(ethernet|infiniband|network).*$/ {
7364 aNic[counter]=gensub(/^[0-9a-f:\.]+ [^:]+: (.+)$/,"\\1","g",$0)
7365 #gsub(/realtek semiconductor/, "Realtek", aNic[counter])
7366 #gsub(/davicom semiconductor/, "Davicom", aNic[counter])
7367 # The doublequotes are necessary because of the pipes in the variable.
7368 gsub(/'"$BAN_LIST_NORMAL"'/, "", aNic[counter])
7369 gsub(/'"$BAN_LIST_ARRAY"'/, " ", aNic[counter])
7370 gsub(/^ +| +$/, "", aNic[counter])
7371 gsub(/ [ \t]+/, " ", aNic[counter])
7372 aPciBusId[counter] = gensub(/(^[0-9a-f:\.]+) [^:]+: .+$/,"\\1","g",$0)
7373 while ( getline && !/^$/ ) {
7374 gsub(/'"$BAN_LIST_ARRAY"'/, "", $0)
7375 if ( /^[[:space:]]*I\/O/ ) {
7376 aPorts[counter] = aPorts[counter] $4 " "
7378 if ( /driver in use/ ) {
7379 aDrivers[counter] = aDrivers[counter] gensub( /(.*): (.*)/ ,"\\2" ,"g" ,$0 ) ""
7381 else if ( /kernel modules/ ) {
7382 aModules[counter] = aModules[counter] gensub( /(.*): (.*)/ ,"\\2" ,"g" ,$0 ) ""
7388 for (i=0;i<counter;i++) {
7395 ## note: this loses the plural ports case, is it needed anyway?
7396 if ( aPorts[i] != "" ) {
7397 usePorts = aPorts[i]
7399 if ( aDrivers[i] != "" ) {
7400 useDrivers = aDrivers[i]
7402 if ( aModules[i] != "" ) {
7403 useModules = aModules[i]
7405 if ( aNic[i] != "" ) {
7408 if ( aPciBusId[i] != "" ) {
7409 usePciBusId = aPciBusId[i]
7411 # create array primary item for master array
7412 sub( / $/, "", usePorts ) # clean off trailing whitespace
7413 print useNic "," useDrivers "," usePorts "," useModules, "," usePciBusId
7417 get_networking_usb_data
7418 if [[ $B_SHOW_ADVANCED_NETWORK == 'true' || $B_USB_NETWORKING == 'true' ]];then
7419 if [[ -z $BSD_TYPE ]];then
7420 get_network_advanced_data
7423 a_temp=${A_NETWORK_DATA[@]}
7424 log_function_data "A_NETWORK_DATA: $a_temp"
7429 get_network_advanced_data()
7432 local a_network_adv_working='' if_data='' working_path='' working_uevent_path='' dir_path=''
7433 local if_id='' speed='' duplex='' mac_id='' oper_state='' chip_id='' b_path_made='true'
7434 local usb_data='' usb_vendor='' usb_product='' product_path='' driver_test='' array_counter=0
7436 # we need to change to holder since we are updating the main array
7438 local a_main_working=(${A_NETWORK_DATA[@]})
7441 for (( i=0; i < ${#a_main_working[@]}; i++ ))
7444 a_network_adv_working=( ${a_main_working[i]} )
7446 # reset these every go round
7454 working_uevent_path=''
7455 if [[ -z $( grep '^usb-' <<< ${a_network_adv_working[4]} ) ]];then
7456 # note although this may exist technically don't use it, it's a virtual path
7457 # and causes weird cat errors when there's a missing file as well as a virtual path
7458 # /sys/bus/pci/devices/0000:02:02.0/net/eth1
7459 # real paths are: /sys/devices/pci0000:00/0000:00:1e/0/0000:02:02.0/net/eth1/uevent
7460 # and on older debian kernels: /sys/devices/pci0000:00/0000:02:02.0/net:eth1/uevent
7461 # but broadcom shows this sometimes, and older kernels maybe:
7462 # /sys/devices/pci0000:00/0000:00:01.0/0000:05:00.0/net/eth0/
7463 # /sys/devices/pci0000:00/0000:00:03.0/0000:03:00.0/ssb0:0/uevent:['DRIVER=b43', 'MODALIAS=ssb:v4243id0812rev0D']:
7464 # echo a ${a_network_adv_working[4]}
7465 if [[ -d /sys/bus/pci/devices/ ]];then
7466 working_path="/sys/bus/pci/devices/0000:${a_network_adv_working[4]}"
7467 elif [[ -d /sys/devices/pci0000:00/ ]];then
7468 working_path="/sys/devices/pci0000:00/0000:00:01.0/0000:${a_network_adv_working[4]}"
7470 #echo wp ${a_network_adv_working[4]} $i
7471 # now we want the real one, that xiin also displays, without symbolic links.
7472 if [[ -n $working_path && -e $working_path ]];then
7473 working_path=$( readlink -f $working_path 2>/dev/null )
7475 working_path=$( find -P /sys/ -type d -name "*:${a_network_adv_working[4]}" 2>/dev/null )
7476 # just on off chance we get two returns, just one one
7477 working_path=${working_path%% *}
7479 # sometimes there is another directory between the path and /net
7480 if [[ -n $working_path && ! -e $working_path/net ]];then
7481 # using find here, probably will need to also use it in usb part since the grep
7482 # method seems to not be working now. Slice off the rest, which leaves the basic path
7483 working_path=$( find $working_path/*/net/*/uevent 2>/dev/null | \
7486 # working_path=$( ls /sys/devices/pci*/*/0000:${a_network_adv_working[4]}/net/*/uevent )
7488 # now we'll use the actual vendor:product string instead
7489 usb_data=${a_network_adv_working[10]}
7490 usb_vendor=$( cut -d ':' -f 1 <<< $usb_data )
7491 usb_product=$( cut -d ':' -f 2 <<< $usb_data )
7492 # this grep returns the path plus the contents of the file, with a colon separator, so slice that off
7493 # /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/idVendor
7494 working_path=$( grep -s "$usb_vendor" /sys/devices/pci*/*/usb*/*/*/idVendor | \
7495 sed -e "s/idVendor:$usb_vendor//" -e '/driver/d' )
7496 # try an alternate path if first one doesn't work
7497 # /sys/devices/pci0000:00/0000:00:0b.1/usb1/1-1/idVendor
7498 if [[ -z $working_path ]];then
7499 working_path=$( grep -s "$usb_vendor" /sys/devices/pci*/*/usb*/*/idVendor | \
7500 sed -e "s/idVendor:$usb_vendor//" -e '/driver/d' )
7501 product_path=$( grep -s "$usb_product" /sys/devices/pci*/*/usb*/*/idProduct | \
7502 sed -e "s/idProduct:$usb_product//" -e '/driver/d' )
7504 product_path=$( grep -s "$usb_product" /sys/devices/pci*/*/usb*/*/*/idProduct | \
7505 sed -e "s/idProduct:$usb_product//" -e '/driver/d' )
7507 # make sure it's the right product/vendor match here, it will almost always be but let's be sure
7508 if [[ -n $working_path && -n $product_path ]] && [[ $working_path == $product_path ]];then
7509 #if [[ -n $working_path ]];then
7510 # now ls that directory and get the numeric starting sub directory and that should be the full path
7511 # to the /net directory part
7512 dir_path=$( ls $working_path 2>/dev/null | grep -sE '^[0-9]' )
7513 working_uevent_path="$working_path$dir_path"
7516 # /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/uevent grep for DRIVER=
7517 # /sys/devices/pci0000:00/0000:00:0b.1/usb1/1-1/1-1:1.0/uevent
7518 if [[ -n $usb_data ]];then
7519 driver_test=$( grep -si 'DRIVER=' $working_uevent_path/uevent | cut -d '=' -f 2 )
7520 if [[ -n $driver_test ]];then
7521 a_network_adv_working[1]=$driver_test
7524 #echo wp: $working_path
7525 log_function_data "PRE: working_path: $working_path\nworking_uevent_path: $working_uevent_path"
7526 # this applies in two different cases, one, default, standard, two, for usb, this is actually
7527 # the short path, minus the last longer numeric directory name, ie:
7528 # from debian squeeze 2.6.32-5-686:
7529 # /sys/devices/pci0000:00/0000:00:0b.1/usb1/1-1/net/wlan0/address
7530 if [[ -e $working_path/net ]];then
7531 # in cases like infiniband dual port devices, there can be two ids, like ib0 ib1,
7532 # with line break in output
7533 if_data=$( ls $working_path/net 2>/dev/null )
7535 # this is the normal usb detection if the first one didn't work
7536 elif [[ -n $usb_data && -e $working_uevent_path/net ]];then
7537 if_data=$( ls $working_uevent_path/net 2>/dev/null )
7538 working_path=$working_uevent_path/net/$if_data
7539 # 2.6.32 debian lenny kernel shows not: /net/eth0 but /net:eth0
7540 elif [[ -n ${working_path/\/sys*/} ]];then
7541 if_data=$( ls $working_path 2>/dev/null | grep 'net:' )
7542 if [[ -n $if_data ]];then
7543 working_path=$working_path/$if_data
7544 # we won't be using this for path any more, just the actual if id output
7545 # so prep it for the loop below
7546 if_data=$( cut -d ':' -f 2 <<< "$if_data" )
7549 # just in case we got a failed path, like /net or /, clear it out for tests below
7550 if [[ -n ${working_path/\/sys*/} ]];then
7554 log_function_data "POST: working_path: $working_path\nif_data: $if_data - if_id: $if_id"
7555 # there are virtual devices that will have no if data but which we still want in the array
7556 # as it loops. These will also have null working_path as well since no **/net is found
7557 # echo if_data: $if_data
7558 if [[ -z $if_data ]];then
7559 if_data='null-if-id'
7561 ## note: in cases of dual ports with different ids, this loop will create extra array items
7562 for if_item in $if_data
7571 # strip out trailing spaces
7572 if_item=${if_item%% }
7573 #echo wp1: $working_path
7574 if [[ $working_path != '' ]];then
7576 if [[ $b_path_made == 'false' ]];then
7577 full_path=$working_path/net/$if_item
7579 full_path=$working_path
7581 if [[ -r $full_path/speed ]];then
7582 speed=$( cat $full_path/speed 2>/dev/null )
7584 if [[ -r $full_path/duplex ]];then
7585 duplex=$( cat $full_path/duplex 2>/dev/null )
7587 if [[ -r $full_path/address ]];then
7588 mac_id=$( cat $full_path/address 2>/dev/null )
7590 if [[ -r $full_path/operstate ]];then
7591 oper_state=$( cat $full_path/operstate 2>/dev/null )
7593 if [[ -n ${a_network_adv_working[10]} ]];then
7594 chip_id=${a_network_adv_working[10]}
7598 #echo fp: $full_path
7600 # echo "$if_data ii: $if_item $array_counter i: $i"
7601 A_NETWORK_DATA[$array_counter]=${a_network_adv_working[0]}","${a_network_adv_working[1]}","${a_network_adv_working[2]}","${a_network_adv_working[3]}","${a_network_adv_working[4]}","$if_id","$oper_state","$speed","$duplex","$mac_id","$chip_id
7606 a_temp=${A_NETWORK_DATA[@]}
7607 log_function_data "A_NETWORK_DATA (advanced): $a_temp"
7612 get_networking_usb_data()
7615 local lsusb_path='' lsusb_data='' a_usb='' array_count=''
7617 # now we'll check for usb wifi, a work in progress
7618 # USB_NETWORK_SEARCH
7619 # alsa usb detection by damentz
7620 # for every sound card symlink in /proc/asound - display information about it
7621 lsusb_path=$( type -p lsusb )
7622 # if lsusb exists, the file is a symlink, and contains an important usb exclusive file: continue
7623 if [[ -n $lsusb_path ]]; then
7624 # send error messages of lsusb to /dev/null as it will display a bunch if not a super user
7625 lsusb_data="$( $lsusb_path 2>/dev/null )"
7626 # also, find the contents of usbid in lsusb and print everything after the 7th word on the
7627 # corresponding line. Finally, strip out commas as they will change the driver :)
7628 if [[ -n $lsusb_data ]];then
7637 /'"$USB_NETWORK_SEARCH"'/ && !/bluetooth| hub|keyboard|mouse|printer| ps2|reader|scan|storage/ {
7639 gsub(/'"$BAN_LIST_ARRAY"'/, " ", $0 )
7640 gsub(/'"$BAN_LIST_NORMAL"'/, "", $0)
7641 gsub(/ [ \t]+/, " ", $0)
7642 #sub(/realtek semiconductor/, "Realtek", $0)
7643 #sub(/davicom semiconductor/, "Davicom", $0)
7644 #sub(/Belkin Components/, "Belkin", $0)
7646 for ( i=7; i<= NF; i++ ) {
7647 string = string separator $i
7652 print string ",,,,usb-" $2 "-" $4 ",,,,,," $6
7654 }' <<< "$lsusb_data" ) )
7656 if [[ ${#a_usb[@]} -gt 0 ]];then
7657 array_count=${#A_NETWORK_DATA[@]}
7658 for (( i=0; i < ${#a_usb[@]}; i++ ))
7660 A_NETWORK_DATA[$array_count]=${a_usb[i]}
7663 # need this to get the driver data for -N regular output, but no need
7664 # to run the advanced stuff unless required
7665 B_USB_NETWORKING='true'
7669 # echo $B_USB_NETWORKING
7673 get_networking_wan_ip_data()
7676 local ip='' ip_data='' downloader_error=0 ua='' b_ipv4_good=true
7678 # get ip using wget redirect to stdout. This is a clean, text only IP output url,
7679 # single line only, ending in the ip address. May have to modify this in the future
7680 # to handle ipv4 and ipv6 addresses but should not be necessary.
7681 # awk has bad regex handling so checking it with grep -E instead
7682 # ip=$( echo 2001:0db8:85a3:0000:0000:8a2e:0370:7334 | gawk --re-interval '
7683 # ip=$( wget -q -O - $WAN_IP_URL | gawk --re-interval '
7684 # this generates a direct dns based ipv4 ip address, but if opendns.com goes down, the fall
7685 # note: consistently slower than domain based: dig +short +time=1 +tries=1 myip.opendns.com. A @208.67.222.222
7686 # backs will still work.
7687 if [[ -n $DNSTOOL ]];then
7688 ip=$( dig +short +time=1 +tries=1 myip.opendns.com @resolver1.opendns.com 2>/dev/null)
7690 if [[ $ip == '' ]];then
7693 if [[ -n $( grep 'smxi.org' <<< $WAN_IP_URL ) ]];then
7694 ua="-A s-tools/inxi-ip"
7696 ip_data="$( curl $ua -y $DL_TIMEOUT -s $WAN_IP_URL )" || downloader_error=$?
7699 ip_data="$( fetch -T $DL_TIMEOUT -q -o - $WAN_IP_URL )" || downloader_error=$?
7702 ip_data="$( ftp -o - $WAN_IP_URL 2>/dev/null )" || downloader_error=$?
7705 if [[ -n $( grep 'smxi.org' <<< $WAN_IP_URL ) ]];then
7706 ua="-U s-tools/inxi-ip"
7708 ip_data="$( wget $ua -T $DL_TIMEOUT -q -O - $WAN_IP_URL )" || downloader_error=$?
7714 ip=$( gawk --re-interval '
7722 if [[ -z $ip ]];then
7724 elif [[ -z $( grep -Es \
7725 '^([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}|[[:alnum:]]{0,4}:[[:alnum:]]{0,4}:[[:alnum:]]{0,4}:[[:alnum:]]{0,4}:[[:alnum:]]{0,4}:[[:alnum:]]{0,4}:[[:alnum:]]{0,4}:[[:alnum:]]{0,4})$' <<< $ip ) ]];then
7726 ip='IP Source Corrupt!'
7729 log_function_data "ip: $ip"
7733 get_networking_local_ip_data()
7737 local ip_tool_command=$( type -p ip )
7738 local a_temp='' ip_tool='ip' ip_tool_data=''
7739 # the chances for all new systems to have ip by default are far higher than
7740 # the deprecated ifconfig. Only try for ifconfig if ip is not present in system
7741 if [[ -z $ip_tool_command ]];then
7742 ip_tool_command=$( type -p ifconfig )
7745 ip_tool_command="$ip_tool_command addr"
7747 if [[ -n "$ip_tool_command" ]];then
7748 if [[ $ip_tool == 'ifconfig' ]];then
7749 ip_tool_data="$( $ip_tool_command | gawk '
7751 line=gensub(/^([a-z]+[0-9][:]?[[:space:]].*)/, "\n\\1", $0)
7754 # note, ip addr does not have proper record separation, so creating new lines explicitly here at start
7755 # of each IF record item. Also getting rid of the unneeded numeric line starters, now it can be parsed
7756 # like ifconfig more or less
7757 elif [[ $ip_tool == 'ip' ]];then
7758 ip_tool_data="$( eval $ip_tool_command | sed 's/^[0-9]\+:[[:space:]]\+/\n/' )"
7761 if [[ -z $ip_tool_command ]];then
7762 A_INTERFACES_DATA=( "Interfaces program 'ip' missing. Please check: $SCRIPT_NAME --recommends" )
7763 elif [[ -n "$ip_tool_data" ]];then
7764 IFS=$'\n' # $ip_tool_command
7765 A_INTERFACES_DATA=( $(
7766 gawk -v ipTool=$ip_tool -v bsdType=$BSD_TYPE '
7774 # skip past the lo item
7776 while (getline && !/^$/ ) {
7777 # do nothing, just get past this entry item
7781 # not clear on why inet is coming through, but this gets rid of it
7782 # as first line item.
7783 gsub(/'"$BAN_LIST_ARRAY"'/, " ", $0)
7784 gsub(/^ +| +$/, "", $0)
7785 gsub(/ [ \t]+/, " ", $0)
7787 # prep this this for ip addr: eth0:
7788 sub(/:/, "", interface)
7792 aInterfaces[interface]++
7794 while (getline && !/^$/ ) {
7795 if ( ipTool == "ifconfig" ) {
7797 ifIp = gensub( /addr:([0-9\.]+)/, "\\1", "g", $2 )
7799 ifMask = gensub( /mask:([0-9\.]+)/, "\\1", "g", $NF )
7802 if (/inet6 addr:/) {
7805 if ( bsdType == "bsd" ) {
7806 if ( $1 == "inet" ) {
7808 if ( $3 == "netmask" ) {
7812 if ( $0 ~ /inet6.*%/ ) {
7818 else if ( ipTool == "ip" ) {
7819 if ( $1 == "inet" ) {
7822 if ( $1 == "inet6" ) {
7827 # slice off the digits that are sometimes tacked to the end of the address,
7829 sub(/\/[0-9]+/, "", ifIp)
7830 sub(/\/[0-9]+/, "", ifIpV6)
7831 ipAddresses[interface] = ifIp "," ifMask "," ifIpV6
7835 for (i in aInterfaces) {
7838 if (ipAddresses[i] != "") {
7839 ifData = ipAddresses[i]
7841 # create array primary item for master array
7842 # tested needed to avoid bad data from above, if null it is garbage
7843 # this is the easiest way to handle junk I found, improve if you want
7844 if ( ifData != "" ) {
7845 print a[j] "," ifData
7849 }' <<< "$ip_tool_data" ) )
7852 A_INTERFACES_DATA=( "Interfaces program $ip_tool present but created no data. " )
7854 a_temp=${A_INTERFACES_DATA[@]}
7855 log_function_data "A_INTERFACES_DATA: $a_temp"
7858 # get_networking_local_ip_data;exit
7860 get_optical_drive_data()
7864 local a_temp='' sys_uevent_path='' proc_cdrom='' link_list=''
7865 local separator='' linked='' working_disk='' disk='' item_string='' proc_info_string=''
7866 local dev_disks_full=''
7867 dev_disks_full="$( ls /dev/dvd* /dev/cd* /dev/scd* /dev/sr* 2>/dev/null | grep -vE 'random' )"
7868 ## Not using this now because newer kernel is NOT linking all optical drives. Some, but not all
7869 # Some systems don't support xargs -L plus the unlinked optical drive unit make this not a good option
7870 # get the actual disk dev location, first try default which is easier to run, need to preserve line breaks
7871 # local dev_disks_real="$( echo "$dev_disks_full" | xargs -L 1 readlink 2>/dev/null | sort -u )"
7873 #echo ddl: $dev_disks_full
7874 for working_disk in $dev_disks_full
7876 disk=$( readlink $working_disk 2>/dev/null )
7877 if [[ -z $disk ]];then
7880 disk=${disk##*/} # puppy shows this as /dev/sr0, not sr0
7881 # if [[ -z $dev_disks_real || -z $( grep $disk <<< $dev_disks_real ) ]];then
7882 if [[ -n $disk && -z $( grep "$disk" <<< $dev_disks_real ) ]];then
7883 # need line break IFS for below, no white space
7884 dev_disks_real="$dev_disks_real$separator$disk"
7889 dev_disks_real="$( sort -u <<< "$dev_disks_real" )"
7893 #echo ddr: $dev_disks_real
7895 # A_OPTICAL_DRIVE_DATA indexes: not going to use all these, but it's just as easy to build the full
7896 # data array and use what we need from it as to update it later to add features or items
7897 # 0 - true dev path, ie, sr0, hdc
7898 # 1 - dev links to true path
7899 # 2 - device vendor - for hdx drives, vendor model are one string from proc
7901 # 4 - device rev version
7903 # 6 - multisession support
7913 if [[ -n $dev_disks_real ]];then
7914 if [[ $B_SHOW_FULL_OPTICAL == 'true' ]];then
7915 proc_cdrom="$( cat /proc/sys/dev/cdrom/info 2>/dev/null )"
7918 A_OPTICAL_DRIVE_DATA=( $(
7919 for disk in $dev_disks_real
7921 for working_disk in $dev_disks_full
7923 if [[ -n $( readlink $working_disk | grep $disk ) ]];then
7924 linked=${working_disk##*/}
7925 link_list="$link_list$separator$linked"
7929 item_string="$disk,$link_list"
7940 # this is only for new sd type paths in /sys, otherwise we'll use /proc/ide
7941 if [[ -z $( grep '^hd' <<< $disk ) ]];then
7942 # maybe newer kernels use this, not enough data.
7943 sys_path=$( ls /sys/devices/pci*/*/ata*/host*/target*/*/block/$disk/uevent 2>/dev/null | sed "s|/block/$disk/uevent||" )
7944 # maybe older kernels, this used to work (2014-03-16)
7945 if [[ -z $sys_path ]];then
7946 sys_path=$( ls /sys/devices/pci*/*/host*/target*/*/block/$disk/uevent 2>/dev/null | sed "s|/block/$disk/uevent||" )
7948 # no need to test for errors yet, probably other user systems will require some alternate paths though
7949 if [[ -n $sys_path ]];then
7950 vendor=$( cat $sys_path/vendor 2>/dev/null )
7951 model=$( cat $sys_path/model 2>/dev/null | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/,//g' )
7952 state=$( cat $sys_path/state 2>/dev/null | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/,//g' )
7953 rev_number=$( cat $sys_path/rev 2>/dev/null | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/,//g' )
7955 elif [[ -e /proc/ide/$disk/model ]];then
7956 vendor=$( cat /proc/ide/$disk/model 2>/dev/null )
7958 if [[ -n $vendor ]];then
7964 gsub(/'"$BAN_LIST_NORMAL"'/, "", $0)
7965 sub(/TSSTcorp/, "TSST ", $0) # seen more than one of these weird ones
7966 gsub(/'"$BAN_LIST_ARRAY"'/, " ", $0)
7967 gsub(/^[[:space:]]*|[[:space:]]*$/, "", $0)
7968 gsub(/ [[:space:]]+/, " ", $0)
7972 # this needs to run no matter if there's proc data or not to create the array comma list
7973 if [[ $B_SHOW_FULL_OPTICAL == 'true' ]];then
7974 proc_info_string=$( gawk -v diskId=$disk '
7988 # first get the position of the device name from top field
7989 # we will use this to get all the other data for that column
7991 for ( position=3; position <= NF; position++ ) {
7992 if ( $position == diskId ) {
8000 /Can read multisession:/ {
8001 multisession=$( position + 1 )
8004 mcn=$( position + 1 )
8007 audio=$( position + 1 )
8010 cdr=$( position + 1 )
8012 /Can write CD-RW:/ {
8013 cdrw=$( position + 1 )
8016 dvd=$( position + 1 )
8018 /Can write DVD-R:/ {
8019 dvdr=$( position + 1 )
8021 /Can write DVD-RAM:/ {
8022 dvdram=$( position + 1 )
8025 print speed "," multisession "," mcn "," audio "," cdr "," cdrw "," dvd "," dvdr "," dvdram
8027 ' <<< "$proc_cdrom" )
8029 item_string="$item_string,$vendor,$model,$rev_number,$proc_info_string,$state"
8035 a_temp=${A_OPTICAL_DRIVE_DATA[@]}
8037 log_function_data "A_OPTICAL_DRIVE_DATA: $a_temp"
8040 # get_optical_drive_data;exit
8042 get_optical_drive_data_bsd()
8048 if [[ -n $Dmesg_Boot_Data ]];then
8050 A_OPTICAL_DRIVE_DATA=( $( gawk -F ':' '
8054 # sde,3.9GB,STORE_N_GO,USB,C200431546D3CF49-0:0,0
8055 # sdd,250.1GB,ST3250824AS,,9ND08GKX,45
8056 $1 ~ /^(cd|dvd)[0-9]+/ {
8057 diskId=gensub(/^((cd|dvd)[0-9]+)[^0-9].*/,"\\1",1,$1)
8058 # note: /var/run/dmesg.boot may repeat items since it is not created
8059 # fresh every boot, this way, only the last items will be used per disk id
8060 if (aIds[diskId] == "" ) {
8063 aDisks[diskId, "id"] = diskId
8064 if ( $NF ~ /<.*>/ ){
8065 gsub(/.*<|>.*/,"",$NF)
8066 rev_number=gensub(/.*[^0-9\.]([0-9\.]+)$/,"\\1",1,$NF)
8067 if (rev_number ~ /^[0-9\.]+$/) {
8068 aDisks[diskId, "rev"] = rev_number
8070 model=gensub(/(.*[^0-9\.])[0-9\.]+$/,"\\1",1,$NF)
8071 sub(/[[:space:]]+$/,"",model)
8072 aDisks[diskId, "model"] = model
8074 if ( $NF ~ /serial number/ ){
8075 sub(/serial[[:space:]]+number[[:space:]]*/,"",$NF)
8076 aDisks[diskId, "serial"] = $NF
8078 if ( $NF ~ /[GM]B\/s/ ){
8079 speed=gensub(/^([0-9\.]+[[:space:]]*[GM]B\/s).*/,"\\1",1,$NF)
8080 sub(/\.[0-9]+/,"",speed)
8081 if ( speed ~ /^[0-9]+/ ) {
8082 aDisks[diskId, "speed"] = speed
8086 # "$link,dev-readlinks,$vendor,$model,$rev_number,$proc_info_string,$state"
8087 # $proc_info_string: print speed "," multisession "," mcn "," audio "," cdr "," cdrw "," dvd "," dvdr "," dvdram
8089 # multi dimensional pseudo arrays are sorted at total random, not in order of
8090 # creation, so force a sort of the aIds, which deletes the array index but preserves
8093 for ( key in aIds ) {
8094 print aDisks[aIds[key], "id"] ",,," aDisks[aIds[key], "model"] "," aDisks[aIds[key], "rev"] "," aDisks[aIds[key], "speed"] ",,,,,,,,"
8096 }' <<< "$Dmesg_Boot_Data" ) )
8100 a_temp=${A_OPTICAL_DRIVE_DATA[@]}
8102 log_function_data "A_OPTICAL_DRIVE_DATA: $a_temp"
8107 get_partition_data()
8111 local a_partition_working='' dev_item='' a_temp='' dev_working_item=''
8112 local swap_data='' df_string='' main_partition_data='' fs_type=''
8113 local mount_data='' dev_bsd_item=''
8114 #local excluded_file_types='--exclude-type=aufs --exclude-type=tmpfs --exclude-type=iso9660'
8115 # df doesn't seem to work in script with variables like at the command line
8116 # added devfs linprocfs sysfs fdescfs which show on debian kfreebsd kernel output
8117 if [[ -z $BSD_TYPE ]];then
8118 swap_data="$( swapon -s 2>/dev/null )"
8119 df_string='df -h -T -P --exclude-type=aufs --exclude-type=devfs --exclude-type=devtmpfs
8120 --exclude-type=fdescfs --exclude-type=iso9660 --exclude-type=linprocfs --exclude-type=procfs
8121 --exclude-type=squashfs --exclude-type=sysfs --exclude-type=tmpfs --exclude-type=unionfs'
8123 swap_data="$( swapctl -l -k 2>/dev/null )"
8124 # default size is 512, -H only for size in human readable format
8125 # older bsds don't support -T, pain, so we'll use partial output there
8126 if df -h -T &>/dev/null;then
8127 df_string='df -h -T'
8132 main_partition_data="$( eval $df_string )"
8133 # set dev disk label/mapper/uuid data globals
8134 get_partition_dev_data 'label'
8135 get_partition_dev_data 'mapper'
8136 get_partition_dev_data 'uuid'
8138 log_function_data 'raw' "main_partition_data:\n$main_partition_data\n\nswap_data:\n$swap_data"
8140 # new kernels/df have rootfs and / repeated, creating two entries for the same partition
8141 # so check for two string endings of / then slice out the rootfs one, I could check for it
8142 # before slicing it out, but doing that would require the same action twice re code execution
8143 if [[ $( grep -cs '[[:space:]]/$' <<< "$main_partition_data" ) -gt 1 ]];then
8144 main_partition_data="$( grep -vs '^rootfs' <<< "$main_partition_data" )"
8146 # echo "$main_partition_data"
8147 log_function_data 'raw' "main_partition_data_post_rootfs:\n$main_partition_data\n\nswap_data:\n$swap_data"
8149 # $NF = partition name; $(NF - 4) = partition size; $(NF - 3) = used, in gB; $(NF - 1) = percent used
8150 ## note: by subtracting from the last field number NF, we avoid a subtle issue with LVM df output, where if
8151 ## the first field is too long, it will occupy its own line, this way we are getting only the needed data
8152 A_PARTITION_DATA=( $( echo "$main_partition_data" | gawk -v bsdType="$BSD_TYPE" -v bsdVersion="$BSD_VERSION" '
8157 # this has to be nulled for every iteration so it does not retain value from last iteration
8159 # skipping these file systems because bsds do not support df --exclude-type=<fstype>
8160 # note that using $1 to handle older bsd df, which do not support -T. This will not be reliable but we will see
8162 # skip if non disk/partition, or if raid primary id, which will not have a / in it.
8163 # Note: kfreebsd uses /sys, not sysfs, is this a bug or expected behavior?
8164 if ( $1 ~ /^(aufs|devfs|devtmpfs|fdescfs|iso9660|linprocfs|procfs|squashfs|\/sys|sysfs|tmpfs|type|unionfs)$/ ||
8165 ( $1 ~ /^([^\/]+)$/ && $1 !~ /^ROOT/ ) ) {
8166 # note use next, not getline or it does not work right
8170 # this is required because below we are subtracting from NF, so it has to be > 5
8171 # the real issue is long file system names that force the wrap of df output: //fileserver/main
8172 # but we still need to handle more dynamically long space containing file names, but later.
8173 # Using df -P should fix this, ie, no wrapping of line lines, but leaving this for now
8174 ( NF < 6 ) && ( $0 !~ /[0-9]+%/ ) {
8175 # set the dev location here for cases of wrapped output
8177 devBase=gensub( /^(\/dev\/)(.+)$/, "\\2", 1, $1 )
8182 # next set devBase if it didn not get set above here
8183 ( devBase == "" ) && ( $1 ~ /^\/dev\/|:\/|\/\// ) {
8184 devBase=gensub( /^(\/dev\/)(.+)$/, "\\2", 1, $1 )
8186 # this handles zfs type devices/partitions, which do not start with / but contain /
8187 ( bsdType != "" && devBase == "" && $1 ~ /^[^\/]+\/.+/ ) {
8188 devBase=gensub( /^([^\/]+\/)([^\/]+)$/, "non-dev-\\1\\2", 1, $1 )
8190 # this handles yet another fredforfaen special case where a mounted drive
8191 # has the search string in its name
8192 $NF ~ /^\/$|^\/boot$|^\/var$|^\/home$|^\/tmp$|^\/usr$/ {
8193 # note, older df in bsd do not have file system column
8194 if ( NF == "7" && $(NF - 1) ~ /[0-9]+%/ ) {
8195 fileSystem=$(NF - 5)
8200 # /dev/disk0s2 249G 24G 225G 10% 5926984 54912758 10% /
8201 if ( bsdVersion == "darwin" && $(NF - 4) ~ /[0-9]+%/ ) {
8202 print $NF "," $(NF - 7) "," $(NF - 6) "," $(NF - 4) ",main," fileSystem "," devBase
8205 print $NF "," $(NF - 4) "," $(NF - 3) "," $(NF - 1) ",main," fileSystem "," devBase
8208 # skip all these, including the first, header line. Use the --exclude-type
8209 # to handle new filesystems types we do not want listed here
8210 $NF !~ /^\/$|^\/boot$|^\/var$|^\/home$|^\/tmp$|^\/usr$|^filesystem/ {
8211 # this is to avoid file systems with spaces in their names, that will make
8212 # the test show the wrong data in each of the fields, if no x%, then do not use
8213 # using 3 cases, first default, standard, 2nd, 3rd, handles one and two spaces in name
8214 if ( bsdVersion == "darwin" && $(NF - 4) ~ /[0-9]+%/ ) {
8216 print $NF "," $(NF - 7) "," $(NF - 6) "," $(NF - 4) ",main," fileSystem "," devBase
8218 else if ( $(NF - 1) ~ /[0-9]+%/ ) {
8219 # note, older df in bsd do not have file system column
8221 fileSystem=$(NF - 5)
8226 print $NF "," $(NF - 4) "," $(NF - 3) "," $(NF - 1) ",secondary," fileSystem "," devBase
8228 # these two cases construct the space containing name
8229 else if ( $(NF - 2) ~ /[0-9]+%/ ) {
8230 # note, older df in bsd do not have file system column
8231 if ( NF == "8" && $(NF - 6) !~ /^[0-9]+/ ) {
8232 fileSystem=$(NF - 6)
8237 print $(NF - 1) " " $NF "," $(NF - 5) "," $(NF - 4) "," $(NF - 2) ",secondary," fileSystem "," devBase
8239 else if ( $(NF - 3) ~ /[0-9]+%/ ) {
8240 # note, older df in bsd do not have file system column
8241 if ( NF == "9" && $(NF - 7) !~ /^[0-9]+/ ) {
8242 fileSystem=$(NF - 7)
8247 print $(NF - 2) " " $(NF - 1) " " $NF "," $(NF - 6) "," $(NF - 5) "," $(NF - 3) ",secondary," fileSystem "," devBase
8250 # now add the swap partition data, don't want to show swap files, just partitions,
8251 # though this can include /dev/ramzswap0. Note: you can also use /proc/swaps for this
8252 # data, it's the same exact output as swapon -s
8253 $( echo "$swap_data" | gawk -v bsdType=$BSD_TYPE '
8260 if ( bsdType == "" ) {
8268 size = sprintf( "%.2f", sizeHolder*1024/1000**3 )
8269 devBase = gensub( /^(\/dev\/)(.+)$/, "\\2", 1, $1 )
8270 used = sprintf( "%.2f", usedHolder*1024/1000**3 )
8271 percentUsed = sprintf( "%.0f", ( usedHolder/sizeHolder )*100 )
8272 print "swap-" swapCounter "," size "GB," used "GB," percentUsed "%,main," "swap," devBase
8273 swapCounter = ++swapCounter
8277 a_temp=${A_PARTITION_DATA[@]}
8279 log_function_data "1: A_PARTITION_DATA:\n$a_temp"
8281 # we'll use this for older systems where no filesystem type is shown in df
8282 if [[ $BSD_TYPE == 'bsd' ]];then
8283 mount_data="$( mount )"
8285 # now we'll handle some fringe cases where irregular df -hT output shows /dev/disk/.. instead of
8286 # /dev/h|sdxy type data for column 1, . A_PARTITION_DATA[6]
8287 # Here we just search for the uuid/label and then grab the end of the line to get the right dev item.
8288 for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
8291 a_partition_working=( ${A_PARTITION_DATA[i]} )
8294 dev_item=${a_partition_working[6]} # reset each loop
8295 fs_type=${a_partition_working[5]}
8296 # older bsds have df minus -T so can't get fs type easily, try using mount instead
8297 if [[ $BSD_TYPE == 'bsd' ]] && [[ -z $fs_type && -n $dev_item ]];then
8298 dev_bsd_item=$( sed -e 's/non-dev-//' -e 's|/|\\/|g' <<< "$dev_item" )
8299 fs_type=$( gawk -v bsdVersion="$BSD_VERSION" -F '(' '
8305 if ( bsdVersion != "openbsd" ) {
8306 # slice out everything after / plus the first comma
8307 sub( /,.*/, "", $2 )
8311 # for openbsd: /dev/wd0f on /usr type ffs (local, nodev)
8312 gsub(/^.*type[[:space:]]+|[[:space:]]*$/, "", $1 )
8317 }' <<< "$mount_data" )
8319 # note: for swap this will already be set
8320 if [[ -n $( grep -E '(by-uuid|by-label)' <<< $dev_item ) ]];then
8321 dev_working_item=${dev_item##*/}
8322 if [[ -n $DEV_DISK_UUID ]];then
8323 dev_item=$( echo "$DEV_DISK_UUID" | gawk '
8324 $0 ~ /[ /t]'$dev_working_item'[ /t]/ {
8325 item=gensub( /..\/..\/(.+)/, "\\1", 1, $NF )
8330 # if we didn't find anything for uuid try label
8331 if [[ -z $dev_item && -n $DEV_DISK_LABEL ]];then
8332 dev_item=$( echo "$DEV_DISK_LABEL" | gawk '
8333 $0 ~ /[ /t]'$dev_working_item'[ /t]/ {
8334 item=gensub( /..\/..\/(.+)/, "\\1", 1, $NF )
8339 elif [[ -n $( grep 'mapper/' <<< $dev_item ) ]];then
8340 # get the mapper actual dev item
8341 dev_item=$( get_dev_processed_item "$dev_item" )
8344 if [[ -n $dev_item ]];then
8345 # assemble everything we could get for dev/h/dx, label, and uuid
8347 A_PARTITION_DATA[i]=${a_partition_working[0]}","${a_partition_working[1]}","${a_partition_working[2]}","${a_partition_working[3]}","${a_partition_working[4]}","$fs_type","$dev_item
8351 a_temp=${A_PARTITION_DATA[@]}
8353 log_function_data "2: A_PARTITION_DATA:\n$a_temp"
8354 if [[ $B_SHOW_LABELS == 'true' || $B_SHOW_UUIDS == 'true' ]];then
8355 get_partition_data_advanced
8360 # first get the locations of the mount points for label/uuid detection
8361 get_partition_data_advanced()
8364 local a_partition_working='' dev_partition_data=''
8365 local dev_item='' dev_label='' dev_uuid='' a_temp=''
8366 local mount_point=''
8367 # set dev disk label/mapper/uuid data globals
8368 get_partition_dev_data 'label'
8369 get_partition_dev_data 'mapper'
8370 get_partition_dev_data 'uuid'
8372 if [[ $B_MOUNTS_FILE == 'true' ]];then
8373 for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
8376 a_partition_working=( ${A_PARTITION_DATA[i]} )
8379 # note: for swap this will already be set
8380 if [[ -z ${a_partition_working[6]} ]];then
8382 mount_point=$( sed 's|/|\\/|g' <<< ${a_partition_working[0]} )
8383 #echo mount_point $mount_point
8384 dev_partition_data=$( gawk '
8390 # trying to handle space in name
8391 # gsub(/\\040/, " ", $0 )
8392 /[ \t]'$mount_point'[ \t]/ && $1 != "rootfs" {
8393 # initialize the variables
8397 # slice out the /dev
8398 partition=gensub( /^(\/dev\/)(.+)$/, "\\2", 1, $1 )
8399 # label and uuid can occur for root, set partition to null now
8400 if ( partition ~ /by-label/ ) {
8401 label=gensub( /^(\/dev\/disk\/by-label\/)(.+)$/, "\\2", 1, $1 )
8404 if ( partition ~ /by-uuid/ ) {
8405 uuid=gensub( /^(\/dev\/disk\/by-uuid\/)(.+)$/, "\\2", 1, $1 )
8409 # handle /dev/root for / id
8410 if ( partition == "root" ) {
8411 # if this works, great, otherwise, just set this to null values
8412 partTemp="'$( readlink /dev/root 2>/dev/null )'"
8413 if ( partTemp != "" ) {
8414 if ( partTemp ~ /[hsv]d[a-z]+[0-9]{1,2}/ ) {
8415 partition=gensub( /^(\/dev\/)(.+)$/, "\\2", 1, partTemp )
8417 else if ( partTemp ~ /by-uuid/ ) {
8418 uuid=gensub( /^(\/dev\/disk\/by-uuid\/)(.+)$/, "\\2", 1, partTemp )
8419 partition="" # set null to let real location get discovered
8421 else if ( partTemp ~ /by-label/ ) {
8422 label=gensub( /^(\/dev\/disk\/by-label\/)(.+)$/, "\\2", 1, partTemp )
8423 partition="" # set null to let real location get discovered
8432 print partition "," label "," uuid
8436 # assemble everything we could get for dev/h/dx, label, and uuid
8438 A_PARTITION_DATA[i]=${a_partition_working[0]}","${a_partition_working[1]}","${a_partition_working[2]}","${a_partition_working[3]}","${a_partition_working[4]}","${a_partition_working[5]}","$dev_partition_data
8441 ## now we're ready to proceed filling in the data
8443 a_partition_working=( ${A_PARTITION_DATA[i]} )
8445 # get the mapper actual dev item first, in case it's mapped
8446 dev_item=$( get_dev_processed_item "${a_partition_working[6]}" )
8447 # make sure not to slice off rest if it's a network mounted file system
8448 if [[ -n $dev_item && -z $( grep -E '(^//|:/)' <<< $dev_item ) ]];then
8449 dev_item=${dev_item##*/} ## needed to avoid error in case name still has / in it
8451 dev_label=${a_partition_working[7]}
8452 dev_uuid=${a_partition_working[8]}
8453 # then if dev data/uuid is incomplete, try to get missing piece
8454 # it's more likely we'll get a uuid than a label. But this should get the
8455 # dev item set no matter what, so then we can get the rest of any missing data
8456 # first we'll get the dev_item if it's missing
8457 if [[ -z $dev_item ]];then
8458 if [[ -n $DEV_DISK_UUID && -n $dev_uuid ]];then
8459 dev_item=$( echo "$DEV_DISK_UUID" | gawk '
8460 $0 ~ /[ \t]'$dev_uuid'[ \t]/ {
8461 item=gensub( /..\/..\/(.+)/, "\\1", 1, $NF )
8465 elif [[ -n $DEV_DISK_LABEL && -n $dev_label ]];then
8466 dev_item=$( echo "$DEV_DISK_LABEL" | gawk '
8467 # first we need to change space x20 in by-label back to a real space
8468 #gsub(/x20/, " ", $0 )
8469 # then we can see if the string is there
8470 $0 ~ /[ \t]'$dev_label'[ \t]/ {
8471 item=gensub( /..\/..\/(.+)/, "\\1", 1, $NF )
8478 # this can trigger all kinds of weird errors if it is a non /dev path, like: remote:/machine/name
8479 if [[ -n $dev_item && -z $( grep -E '(^//|:/)' <<< $dev_item ) ]];then
8480 if [[ -n $DEV_DISK_UUID && -z $dev_uuid ]];then
8481 dev_uuid=$( echo "$DEV_DISK_UUID" | gawk '
8487 if [[ -n $DEV_DISK_LABEL && -z $dev_label ]];then
8488 dev_label=$( echo "$DEV_DISK_LABEL" | gawk '
8496 # assemble everything we could get for dev/h/dx, label, and uuid
8498 A_PARTITION_DATA[i]=${a_partition_working[0]}","${a_partition_working[1]}","${a_partition_working[2]}","${a_partition_working[3]}","${a_partition_working[4]}","${a_partition_working[5]}","$dev_item","$dev_label","$dev_uuid
8501 log_function_data 'cat' "$FILE_MOUNTS"
8503 if [[ $BSD_TYPE == 'bsd' ]];then
8504 get_partition_data_advanced_bsd
8507 a_temp=${A_PARTITION_DATA[@]}
8509 log_function_data "3-advanced: A_PARTITION_DATA:\n$a_temp"
8513 get_partition_data_advanced_bsd()
8516 local gpart_data="$( gpart list 2>/dev/null )"
8517 local a_partition_working='' label_uuid='' dev_item=''
8519 if [[ -n $gpart_data ]];then
8520 for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
8523 a_partition_working=( ${A_PARTITION_DATA[i]} )
8525 # no need to use the rest of the name if it's not a straight /dev/item
8526 dev_item=${a_partition_working[6]##*/}
8528 label_uuid=$( gawk -F ':' '
8534 /^[0-9]+\.[[:space:]]*Name.*'$dev_item'/ {
8535 while ( getline && $1 !~ /^[0-9]+\.[[:space:]]*Name/ ) {
8536 if ( $1 ~ /rawuuid/ ) {
8537 gsub(/^[[:space:]]+|[[:space:]]+$/,"",$2)
8540 if ( $1 ~ /label/ ) {
8541 gsub(/^[[:space:]]+|[[:space:]]+$|none|\(null\)/,"",$2)
8547 }' <<< "$gpart_data" )
8549 # assemble everything we could get for dev/h/dx, label, and uuid
8551 A_PARTITION_DATA[i]=${a_partition_working[0]}","${a_partition_working[1]}","${a_partition_working[2]}","${a_partition_working[3]}","${a_partition_working[4]}","${a_partition_working[5]}","${a_partition_working[6]}","$label_uuid
8558 # args: $1 - uuid/label/id/mapper
8559 get_partition_dev_data()
8563 # only run these tests once per directory to avoid excessive queries to fs
8566 if [[ $B_ID_SET != 'true' ]];then
8567 if [[ -d /dev/disk/by-id ]];then
8568 DEV_DISK_ID="$( ls -l /dev/disk/by-id )"
8574 if [[ $B_LABEL_SET != 'true' ]];then
8575 if [[ -d /dev/disk/by-label ]];then
8576 DEV_DISK_LABEL="$( ls -l /dev/disk/by-label )"
8582 if [[ $B_MAPPER_SET != 'true' ]];then
8583 if [[ -d /dev/mapper ]];then
8584 DEV_DISK_MAPPER="$( ls -l /dev/mapper )"
8590 if [[ $B_UUID_SET != 'true' ]];then
8591 if [[ -d /dev/disk/by-uuid ]];then
8592 DEV_DISK_UUID="$( ls -l /dev/disk/by-uuid )"
8599 log_function_data 'raw' "DEV_DISK_LABEL:\n$DEV_DISK_LABEL\n\nDEV_DISK_UUID:\n$DEV_DISK_UUID\n\nDEV_DISK_ID:\n$DEV_DISK_ID\n\nDEV_DISK_MAPPER:\n$DEV_DISK_MAPPER"
8600 # debugging section, uncomment to insert user data
8613 # args: $1 - dev item, check for mapper, then get actual dev item if mapped
8614 # eg: lrwxrwxrwx 1 root root 7 Sep 26 15:10 truecrypt1 -> ../dm-2
8615 get_dev_processed_item()
8619 local dev_item=$1 dev_return=''
8621 if [[ -n $DEV_DISK_MAPPER && -n $( grep -is 'mapper/' <<< $dev_item ) ]];then
8622 dev_return=$( echo "$DEV_DISK_MAPPER" | gawk '
8623 $( NF - 2 ) ~ /^'${dev_item##*/}'$/ {
8624 item=gensub( /..\/(.+)/, "\\1", 1, $NF )
8628 if [[ -z $dev_return ]];then
8629 dev_return=$dev_item
8637 get_patch_version_string()
8639 local patch_version_number=$( sed 's/^[0]*//' <<< $SCRIPT_PATCH_NUMBER )
8641 if [[ -n $patch_version_number ]];then
8642 patch_version_number="-$patch_version_number"
8643 # for cases where it was for example: 00-bsd cleaned to --bsd trim out one -
8644 if [[ -n $( grep '\--' <<< $patch_version_number ) ]];then
8645 patch_version_number=$( sed 's/--/-/' <<< $patch_version_number )
8648 echo $patch_version_number
8655 local pciconf_data='' a_temp=''
8657 if [[ $B_PCICONF == 'true' ]];then
8658 pciconf_data="$( pciconf -lv 2>/dev/null )"
8659 if [[ -n $pciconf_data ]];then
8660 pciconf_data=$( gawk '
8665 gsub(/'"$BAN_LIST_NORMAL"'/, "", $0)
8666 gsub(/[[:space:]]+=[[:space:]]+/, "=",$0)
8667 gsub(/^[[:space:]]+|'"'"'|\"|,/, "", $0)
8669 # line=gensub(/.*[[:space:]]+(class=[^[:space:]]*|card=[^[:space:]]*)|chip=[^[:space:]]*|rev=[^[:space:]]*|hdr=[^[:space:]]*).*/,"\n\\1","g",$0)
8670 line=gensub(/(.*@.*)/,"\n\\1",$0)
8672 }' <<< "$pciconf_data" )
8673 # create empty last line with this spacing trick
8674 pciconf_data="$pciconf_data
8677 # echo "$pciconf_data"
8678 # now insert into arrays
8680 A_PCICONF_DATA=( $( gawk '
8701 driver=gensub(/^([^@]+)@.*/, "\\1", itemData )
8702 pciId=gensub(/^.*@pci([0-9\.:]+).*/, "\\1", itemData )
8703 sub(/:$/, "", pciId)
8705 chipId=gensub(/.*chip=([0-9a-f][0-9a-f][0-9a-f][0-9a-f])([0-9a-f][0-9a-f][0-9a-f][0-9a-f]).*/, "\\2:\\1", itemData )
8706 if ( $2 ~ /class=020000/ ) {
8709 else if ( $2 == "class=030000" ) {
8712 else if ( $2 ~ /class=040300|class=040100/ ) {
8716 while ( getline && $1 !~ /^$/ ) {
8717 if ( $1 ~ /^vendor/ ) {
8718 sub(/^vendor=/, "", $1 )
8721 else if ( $1 ~ /^device/ ) {
8722 sub(/^device=/, "", $1 )
8725 else if ( $1 ~ /^class=/ && class == "" ) {
8726 sub(/^class=/, "", $1)
8730 if ( device == "" ) {
8733 fullLine=class "," device "," vendor "," driver "," pciId "," chipId
8735 }' <<< "$pciconf_data" ))
8739 A_PCICONF_DATA='pciconf-not-installed'
8741 B_PCICONF_SET='true'
8742 a_temp=${A_PCICONF_DATA[@]}
8743 log_function_data "$a_temp"
8744 log_function_data "$pciconf_data"
8748 # packs standard card arrays using the pciconf stuff
8749 # args: $1 - audio/network/display - matches first item in A_PCICONF_DATA arrays
8750 get_pciconf_card_data()
8753 local a_temp='' array_string='' j=0 device_string=''
8754 local ip_tool_command=$( type -p ifconfig )
8755 local mac='' state='' speed='' duplex='' network_string=''
8757 for (( i=0;i<${#A_PCICONF_DATA[@]};i++ ))
8760 a_temp=( ${A_PCICONF_DATA[i]} )
8763 if [[ ${a_temp[0]} == $1 ]];then
8764 # don't print the vendor if it's already in the device name
8765 if [[ -z $( grep -i "${a_temp[2]}" <<< "${a_temp[1]}" ) ]];then
8766 device_string="${a_temp[2]} ${a_temp[1]}"
8768 device_string=${a_temp[1]}
8772 array_string="$device_string,${a_temp[3]},,,${a_temp[4]},,${a_temp[5]}"
8773 A_AUDIO_DATA[j]=$array_string
8776 array_string="$device_string,${a_temp[4]},${a_temp[5]}"
8777 A_GRAPHICS_CARD_DATA[j]=$array_string
8780 if [[ -n $ip_tool_command && -n ${a_temp[3]} ]];then
8781 network_string=$( $ip_tool_command ${a_temp[3]} | gawk '
8789 /^[[:space:]]*ether/ {
8792 /^[[:space:]]*media/ {
8793 if ( $0 ~ /<.*>/ ) {
8794 duplex=gensub(/.*<([^>]+)>.*/,"\\1",$0)
8796 if ( $0 ~ /\(.*\)/ ) {
8797 speed=gensub(/.*\(([^<[:space:]]+).*\).*/,"\\1",$0)
8800 /^[[:space:]]*status/ {
8801 sub(/.*status[:]?[[:space:]]*/,"", $0)
8805 print state "~" speed "~" mac "~" duplex
8808 if [[ -n $network_string ]];then
8809 mac=$( cut -d '~' -f 3 <<< $network_string )
8810 state=$( cut -d '~' -f 1 <<< $network_string )
8811 speed=$( cut -d '~' -f 2 <<< $network_string )
8812 duplex=$( cut -d '~' -f 4 <<< $network_string )
8814 array_string="$device_string,${a_temp[3]},,,${a_temp[4]},${a_temp[3]},$state,$speed,$duplex,$mac,${a_temp[5]}"
8815 A_NETWORK_DATA[j]=$array_string
8825 # args: $1 - type cpu/mem
8829 local array_length='' reorder_temp='' i=0 head_tail='' sort_type='' ps_data=''
8831 # bummer, have to make it more complex here because of reverse sort
8832 # orders in output, pesky lack of support of +rss in old systems
8835 if [[ $BSD_TYPE != 'bsd' ]];then
8836 sort_type='ps aux --sort -rss'
8839 sort_type='ps aux -m'
8844 if [[ $BSD_TYPE != 'bsd' ]];then
8845 sort_type='ps aux --sort %cpu'
8848 sort_type='ps aux -r'
8854 # throttle potential irc abuse
8855 if [[ $B_IRC == 'true' && $PS_COUNT -gt 5 ]];then
8856 PS_THROTTLED=$PS_COUNT
8859 # use eval here to avoid glitches with -
8860 ps_data="$( eval $sort_type )"
8863 # note that inxi can use a lot of cpu, and can actually show up here as the script runs
8864 A_PS_DATA=( $( echo "$ps_data" | grep -Ev "($SCRIPT_NAME|%CPU|[[:space:]]ps[[:space:]])" | $head_tail -n $PS_COUNT | gawk '
8882 rss=sprintf( "%.2f", $6/1024 )
8883 # have to get rid of [,],(,) eg: [lockd] which break the printout function compare in bash
8884 gsub(/\[|\]|\(|\)/,"~", $0 )
8893 appStarterName=gensub( /(\/.*\/)(.*)/, "\\2", "1", appStarterPath )
8894 appName=gensub( /(\/.*\/)(.*)/, "\\2", "1", appPath )
8895 print appName "," appPath "," appStarterName "," appStarterPath "," cpu "," mem "," pid "," rss "," user
8898 # make the array ordered highest to lowest so output looks the way we expect it to
8899 # this isn't necessary for -rss, and we can't make %cpu ordered the other way, so
8900 # need to reverse it here. -rss is used because on older systems +rss is not supported
8901 if [[ $1 == 'cpu' && $BSD_TYPE != 'bsd' ]];then
8902 array_length=${#A_PS_DATA[@]};
8903 while (( $i < $array_length/2 ))
8905 reorder_temp=${A_PS_DATA[i]}f
8906 A_PS_DATA[i]=${A_PS_DATA[$array_length-$i-1]}
8907 A_PS_DATA[$array_length-$i-1]=$reorder_temp
8914 # echo ${A_PS_DATA[@]}
8918 # mdstat syntax information: http://www-01.ibm.com/support/docview.wss?uid=isg3T1011259
8919 # note that this does NOT use either Disk or Partition information for now, ie, there
8920 # is no connection between the data types, but the output should still be consistent
8927 if [[ $B_MDSTAT_FILE == 'true' ]];then
8928 mdstat="$( cat $FILE_MDSTAT 2>/dev/null )"
8931 if [[ -n $mdstat ]];then
8932 # need to make sure there's always a newline in front of each record type, and
8933 # also correct possible weird formats for the output from older kernels etc.
8934 mdstat="$( sed -e 's/^md/\nmd/' -e 's/^unused[[:space:]]/\nunused /' \
8935 -e 's/read_ahead/\nread_ahead/' -e 's/^resync=/\nresync=/' -e 's/^Event/\nEvent/' \
8936 -e 's/^[[:space:]]*$//' -e 's/[[:space:]]read_ahead/\nread_ahead/' <<< "$mdstat" )"
8937 # some fringe cases do not end as expected, so need to add newlines plus EOF to make sure while loop doesn't spin
8938 mdstat=$( echo -e "$mdstat\n\nEOF" )
8949 KernelRaidSupport = gensub(/personalities[[:space:]]*:[[:space:]]*(.*)/, "\\1", 1, $0)
8950 # clean off the brackets
8951 gsub(/[\[\]]/,"",KernelRaidSupport)
8952 print "KernelRaidSupport," KernelRaidSupport
8955 ReadAhead=gensub(/read_ahead (.*)/, "\\1", 1 )
8956 print "ReadAhead," ReadAhead
8959 print "raidEvent," $NF
8961 # print logic will search for this value and use it to print out the unused devices data
8963 unusedDevices = gensub(/^unused devices:[[:space:]][<]?([^>]*)[>]?.*/, "\\1", 1, $0)
8964 print "UnusedDevices," unusedDevices
8968 # reset for each record loop through
8978 recoveryProgressBar = ""
8979 recoveryPercent = ""
8981 sectorsRecovered = ""
8986 while ( !/^[[:space:]]*$/ ) {
8987 gsub(/'"$BAN_LIST_ARRAY"'/, " ", $0 )
8988 gsub(/[[:space:]]+/, " ", $0 )
8990 device = gensub(/(md.*)[[:space:]]?:/, "\\1", "1", $1 )
8992 if ( $0 ~ /mirror|raid[0-9]+/ ) {
8993 raidLevel = gensub(/(.*)raid([0-9]+)(.*)/, "\\2", "g", $0 )
8995 if ( $0 ~ /(active \(auto-read-only\)|active|inactive)/ ) {
8996 deviceState = gensub(/(.*) (active \(auto-read-only\)|active|inactive) (.*)/, "\\2", "1", $0 )
8998 # gawk will not return all the components using gensub, only last one
9000 for ( i=3; i<=NF; i++ ) {
9001 if ( $i ~ /[hs]d[a-z][0-9]*(\[[0-9]+\])?(\([SF]\))?/ ) {
9002 components = components separator $i
9006 if ( $0 ~ /blocks/ ) {
9007 blocks = gensub(/(.*[[:space:]]+)?([0-9]+)[[:space:]]blocks.*/, "\\2", "1", $0)
9009 if ( $0 ~ /super[[:space:]][0-9\.]+/ ) {
9010 superBlock = gensub(/.*[[:space:]]super[[:space:]]([0-9\.]+)[[:space:]].*/, "\\1", "1", $0)
9012 if ( $0 ~ /algorithm[[:space:]][0-9\.]+/ ) {
9013 algorithm = gensub(/.*[[:space:]]algorithm[[:space:]]([0-9\.]+)[[:space:]].*/, "\\1", "1", $0)
9015 if ( $0 ~ /\[[0-9]+\/[0-9]+\]/ ) {
9016 deviceReport = gensub(/.*[[:space:]]\[([0-9]+\/[0-9]+)\][[:space:]].*/, "\\1", "1", $0)
9017 uData = gensub(/.*[[:space:]]\[([U_]+)\]/, "\\1", "1", $0)
9019 # need to avoid this: bitmap: 0/10 pages [0KB], 16384KB chunk
9020 # while currently all the normal chunks are marked with k, not kb, this can change in the future
9021 if ( $0 ~ /[0-9]+[k] chunk/ && $0 !~ /bitmap/ ) {
9022 chunkSize = gensub(/(.*) ([0-9]+[k]) chunk.*/, "\\2", "1", $0)
9024 if ( $0 ~ /^resync=/ ) {
9026 print "resyncStatus," $0
9028 if ( $0 ~ /\[[=]*>[\.]*\].*(resync|recovery)/ ) {
9029 recoveryProgressBar = gensub(/.*(\[[=]*>[\.]*\]).*/, "\\1",1,$0)
9031 if ( $0 ~ / (resync|recovery)[[:space:]]*=/ ) {
9032 recoveryPercent = gensub(/.* (resync|recovery)[[:space:]]*=[[:space:]]*([0-9\.]+%).*/, "\\1~\\2", 1 )
9033 if ( $0 ~ /[[:space:]]\([0-9]+\/[0-9]+\)/ ) {
9034 sectorsRecovered = gensub(/.* \(([0-9]+\/[0-9]+)\).*/, "\\1", 1, $0 )
9036 if ( $0 ~ /finish[[:space:]]*=/ ) {
9037 finishTime = gensub(/.* finish[[:space:]]*=[[:space:]]*([[0-9\.]+)([a-z]+) .*/, "\\1 \\2", 1, $0 )
9039 if ( $0 ~ /speed[[:space:]]*=/ ) {
9040 recoverSpeed = gensub(/.* speed[[:space:]]*=[[:space:]]*([[0-9\.]+)([a-z]+\/[a-z]+)/, "\\1 \\2", 1, $0 )
9043 if ( $0 ~ /bitmap/ ) {
9044 bitmapValues = gensub(/(.*[[:space:]])?bitmap:(.*)/, "\\2", 1, $0 )
9049 raidString = device "," deviceState "," raidLevel "," components "," deviceReport "," uData
9050 raidString = raidString "," blocks "," superBlock "," algorithm "," chunkSize "," bitmapValues
9051 raidString = raidString "," recoveryProgressBar "," recoveryPercent "," sectorsRecovered "," finishTime "," recoverSpeed
9058 if [[ $BSD_TYPE == 'bsd' ]];then
9063 a_temp=${A_RAID_DATA[@]}
9064 log_function_data "A_RAID_DATA: $a_temp"
9065 # echo -e "A_RAID_DATA:\n${a_temp}"
9073 local zpool_path=$( type -p zpool 2>/dev/null )
9074 local zpool_data='' zpool_arg='v'
9076 if [[ -n $zpool_path ]];then
9078 # bsd sed does not support inserting a true \n so use this trick
9079 # some zfs does not have -v
9080 if $zpool_path list -v &>/dev/null;then
9081 zpool_data="$( $zpool_path list -v 2>/dev/null | sed $SED_RX 's/^([^[:space:]])/\
9084 zpool_data="$( $zpool_path list 2>/dev/null | sed $SED_RX 's/^([^[:space:]])/\
9088 # echo "$zpool_data"
9099 chunkRaidAllocated=""
9102 sub(/.*ALLOC.*/,"", $0)
9104 # gptid/d874c7e7-3f6d-11e4-b7dc-080027ea466c
9113 chunkRaidAllocated=$3
9116 # raid level is the second item in the output, unless it is not, sometimes it is absent
9118 if ( $1 ~ /raid|mirror/ ) {
9122 raidLevel="zfs-no-raid"
9128 while ( getline && $1 !~ /^$/ ) {
9129 # https://blogs.oracle.com/eschrock/entry/zfs_hot_spares
9130 if ($1 ~ /spares/) {
9134 components = components separator $1
9137 # some issues if we use ~ here
9138 gsub(/\//,"%",components)
9140 raidString = device "," deviceState "," raidLevel "," components "," reportSize "," uData
9141 raidString = raidString "," blocksAvailable "," superBlock "," algorithm "," chunkRaidAllocated
9142 # none of these are used currently
9143 raidString = raidString "," bitmapValues "," recoveryProgressBar "," recoveryPercent
9144 raidString = raidString "," sectorsRecovered "," finishTime "," recoverSpeed
9145 gsub(/~/,"",raidString)
9147 }' <<< "$zpool_data" ) )
9149 # pass the zpool type, so we know how to get the components
9150 get_raid_component_data_bsd "$zpool_arg"
9155 # note, we've already tested for zpool so no further tests required
9156 # args: $1 - zpool type, v will have a single row output, no-v has stacked for components
9157 get_raid_component_data_bsd()
9160 local a_raid_data='' array_string='' component='' component_string=''
9161 local zpool_status='' device='' separator='' component_status=''
9163 for (( i=0; i<${#A_RAID_DATA[@]}; i++))
9166 a_raid_data=( ${A_RAID_DATA[i]} )
9172 device=${a_raid_data[0]}
9173 zpool_status="$( zpool status $device )"
9174 # we will remove ONLINE for status and only use OFFLINE/DEGRADED as tests
9175 # for print output display of issues with components
9176 # note: different zfs outputs vary, some have the components listed by line
9177 if [[ $1 == 'v' ]];then
9178 for component in ${a_raid_data[3]}
9180 component_status=$( gawk '
9188 $1 ~ /^'$component'$/ {
9189 sub( /ONLINE/, "", $2 )
9190 print "'$component'" $2
9192 }' <<< "$zpool_status" )
9193 component_string="$component_string$separator$component_status"
9196 array_string="$device,${a_raid_data[1]},${a_raid_data[2]},${component_string//%/\/},${a_raid_data[4]}"
9197 array_string="$array_string,${a_raid_data[5]},${a_raid_data[6]},${a_raid_data[7]},${a_raid_data[8]}"
9198 array_string="$array_string,${a_raid_data[9]},${a_raid_data[10]},${a_raid_data[11]},${a_raid_data[12]},"
9199 array_string="$array_string${a_raid_data[13]},${a_raid_data[14]},${a_raid_data[15]}"
9201 component_string=$( gawk '
9208 $1 ~ /^'$device'$/ {
9209 while ( getline && !/^$/ ) {
9210 # raid level is the second item in the output, unless it is not, sometimes it is absent
9212 if ( raidLevel == "" ) {
9213 if ( $1 ~ /raid|mirror/ ) {
9218 raidLevel="zfs-no-raid"
9222 # https://blogs.oracle.com/eschrock/entry/zfs_hot_spares
9223 if ($1 ~ /spares/) {
9226 sub( /ONLINE/, "", $2 )
9227 components=components separator $1 separator $2
9230 print raidLevel "," components
9231 }' <<< "$zpool_status" )
9232 # note: component_string is raid type AND components
9233 array_string="$device,${a_raid_data[1]},$component_string,${a_raid_data[4]}"
9234 array_string="$array_string,${a_raid_data[5]},${a_raid_data[6]},${a_raid_data[7]},${a_raid_data[8]}"
9235 array_string="$array_string,${a_raid_data[9]},${a_raid_data[10]},${a_raid_data[11]},${a_raid_data[12]},"
9236 array_string="$array_string${a_raid_data[13]},${a_raid_data[14]},${a_raid_data[15]}"
9239 A_RAID_DATA[i]=$array_string
9245 # get_raid_data_bsd;exit
9251 local a_temp='' array_string=''
9255 if [[ -n $DMIDECODE_DATA ]];then
9256 if [[ $DMIDECODE_DATA == 'dmidecode-error-'* ]];then
9257 A_MEMORY_DATA[0]=$DMIDECODE_DATA
9258 # please note: only dmidecode version 2.11 or newer supports consistently the -s flag
9268 configuredClockSpeed=""
9270 deviceManufacturer=""
9272 deviceSerialNumber=""
9282 aArrayData[0,"maxCapacity5"]=0
9283 aArrayData[0,"maxCapacity16"]=0
9284 aArrayData[0,"usedCapacity"]=0
9285 aArrayData[0,"maxModuleSize"]=0
9286 aArrayData[0,"derivedModuleSize"]=0
9287 aArrayData[0,"deviceCount5"]=0
9288 aArrayData[0,"deviceCount16"]=0
9289 aArrayData[0,"deviceCountFound"]=0
9290 aArrayData[0,"moduleVoltage5"]=""
9303 function calculateSize(data,size) {
9304 if ( data ~ /^[0-9]+[[:space:]]*[GMTP]B/) {
9305 if ( data ~ /GB/ ) {
9306 data=gensub(/([0-9]+)[[:space:]]*GB/,"\\1",1,data) * 1024
9308 else if ( data ~ /MB/ ) {
9309 data=gensub(/([0-9]+)[[:space:]]*MB/,"\\1",1,data)
9311 else if ( data ~ /TB/ ) {
9312 data=gensub(/([0-9]+)[[:space:]]*TB/,"\\1",1,data) * 1024 * 1000
9314 else if ( data ~ /PB/ ) {
9315 data=gensub(/([0-9]+)[[:space:]]*TB/,"\\1",1,data) * 1024 * 1000 * 1000
9317 if (data ~ /^[0-9][0-9]+$/ && data > size ) {
9323 /^Table[[:space:]]+at[[:space:]]/ {
9325 # we need to start count here because for testing > 1 array, and we want always to have
9326 # the actual module data assigned to the right primary array, even when it is out of
9327 # position in dmidecode output
9332 # {print k ":k:" $0}
9333 /^Handle .* DMI[[:space:]]+type[[:space:]]+5(,|[[:space:]])/ {
9334 while ( getline && !/^$/ ) {
9335 if ( $1 == "Maximum Memory Module Size" ) {
9336 aArrayData[k,"maxModuleSize"]=calculateSize($2,aArrayData[k,"maxModuleSize"])
9337 # print "mms:" aArrayData[k,"maxModuleSize"] ":" $2
9339 if ($1 == "Maximum Total Memory Size") {
9340 aArrayData[k,"maxCapacity5"]=calculateSize($2,aArrayData[k,"maxCapacity5"])
9342 if ( $1 == "Memory Module Voltage" ) {
9343 aArrayData[k,"moduleVoltage5"]=$2
9346 aArrayData[k,"data-type"]="memory-array"
9347 # print k ":data5:"aArrayData[k,"data-type"]
9350 /^Handle .* DMI[[:space:]]+type[[:space:]]+6(,|[[:space:]])/ {
9351 while ( getline && !/^$/ ) {
9352 if ( $1 == "Installed Size" ) {
9354 aMemory[k,j,18]=calculateSize($2,0)
9355 # get data after module size
9356 sub(/ Connection/,"",$2)
9357 sub(/^[0-9]+[[:space:]]*[MGTP]B[[:space:]]*/,"",$2)
9360 if ( $1 == "Current Speed" ) {
9367 /^Handle .* DMI[[:space:]]+type[[:space:]]+16/ {
9368 arrayHandle=gensub(/Handle[[:space:]]([0-9a-zA-Z]+)([[:space:]]|,).*/,"\\1",$0)
9369 while ( getline && !/^$/ ) {
9371 if ( $1 == "Maximum Capacity") {
9372 aArrayData[k,"maxCapacity16"]=calculateSize($2,aArrayData[k,"maxCapacity16"])
9373 #print "mc:" aArrayData[k,"maxCapacity16"] ":" $2
9375 # note: these 3 have cleaned data in get_dmidecode_data, so replace stuff manually
9376 if ( $1 == "Location") {
9377 sub(/[[:space:]]Or[[:space:]]Motherboard/,"",$2)
9379 if ( location == "" ){
9380 location="System Board"
9389 if ( $1 == "Error Correction Type") {
9391 if ( errorCorrection == "" ){
9392 errorCorrection="None"
9395 if ( $1 == "Number of Devices") {
9399 aArrayData[k,"data-type"]="memory-array"
9400 # print k ":data16:"aArrayData[k,"data-type"]
9401 aArrayData[k,"handle"]=arrayHandle
9402 aArrayData[k,"location"]=location
9403 aArrayData[k,"deviceCount16"]=numberOfDevices
9404 aArrayData[k,"use"]=use
9405 aArrayData[k,"errorCorrection"]=errorCorrection
9416 aDerivedModuleSize[k+1]=0
9417 aArrayData[k+1,"deviceCountFound"]=0
9418 aArrayData[k+1,"maxCapacity5"]=0
9419 aArrayData[k+1,"maxCapacity16"]=0
9420 aArrayData[k+1,"maxModuleSize"]=0
9422 /^Handle .* DMI[[:space:]]+type[[:space:]]+17/ {
9423 while ( getline && !/^$/ ) {
9424 if ( $1 == "Array Handle") {
9427 if ( $1 == "Data Width") {
9430 if ( $1 == "Total Width") {
9433 if ( $1 == "Size") {
9434 # do not try to guess from installed modules, only use this to correct type 5 data
9435 aArrayData[k,"derivedModuleSize"]=calculateSize($2,aArrayData[k,"derivedModuleSize"])
9436 workingSize=calculateSize($2,0)
9437 if ( workingSize ~ /^[0-9][0-9]+$/ ){
9438 aArrayData[k,"deviceCountFound"]++
9439 # build up actual capacity found for override tests
9440 aArrayData[k,"usedCapacity"]=workingSize + aArrayData[k,"usedCapacity"]
9442 # print aArrayData[k,"derivedModuleSize"] " dm:" k ":mm " aMaxModuleSize[k] " uc:" aArrayData[k,"usedCapacity"]
9443 # we want any non real size data to be preserved
9444 if ( $2 ~ /^[0-9]+[[:space:]]*[MTPG]B/ ) {
9445 deviceSize=workingSize
9451 if ( $1 == "Locator") {
9453 #sub(/RAM slot #|^DIMM/, "Slot",$2)
9454 sub(/RAM slot #/, "Slot",$2)
9456 #locator=toupper($2)
9459 if ( $1 == "Bank Locator") {
9461 #sub(/RAM slot #|Channel|Chan/,"bank",$2)
9462 #sub(/RAM slot #|Channel|Chan/,"bank",$2)
9463 #bankLocator=toupper($2)
9466 if ( $1 == "Form Factor") {
9469 if ( $1 == "Type") {
9472 if ( $1 == "Type Detail") {
9475 if ( $1 == "Speed") {
9478 if ( $1 == "Configured Clock Speed") {
9479 configuredClockSpeed=$2
9481 if ( $1 == "Manufacturer") {
9482 gsub(/(^[0]+$|Undefined.*|.*Manufacturer.*)/,"",$2)
9483 deviceManufacturer=$2
9485 if ( $1 == "Part Number") {
9486 sub(/(^[0]+$||.*Module.*|Undefined.*)/,"",$2)
9489 if ( $1 == "Serial Number") {
9490 gsub(/(^[0]+$|Undefined.*)/,"",$2)
9491 deviceSerialNumber=$2
9494 # because of the wide range of bank/slot type data, we will just use
9495 # the one that seems most likely to be right. Some have: Bank: SO DIMM 0 slot: J6A
9496 # so we dump the useless data and use the one most likely to be visibly correct
9497 if ( bankLocator ~ /DIMM/ ) {
9498 mainLocator=bankLocator
9503 # sometimes the data is just wrong, they reverse total/data. data I believe is
9504 # used for the actual memory bus width, total is some synthetic thing, sometimes missing.
9505 # note that we do not want a regular string comparison, because 128 bit memory buses are
9506 # in our future, and 128 bits < 64 bits with string compare
9507 intData=gensub(/(^[0-9]+).*/,"\\1",1,dataWidth)
9508 intTotal=gensub(/(^[0-9]+).*/,"\\1",1,totalWidth)
9509 if (intData != "" && intTotal != "" && intData > intTotal ) {
9511 dataWidth=totalWidth
9512 totalWidth=tempWidth
9515 aMemory[k,i,0]="memory-device"
9516 aMemory[k,i,1]=arrayHandle
9517 aMemory[k,i,2]=deviceSize
9518 aMemory[k,i,3]=bankLocator
9519 aMemory[k,i,4]=locator
9520 aMemory[k,i,5]=formFactor
9521 aMemory[k,i,6]=deviceType
9522 aMemory[k,i,7]=deviceTypeDetail
9523 aMemory[k,i,8]=deviceSpeed
9524 aMemory[k,i,9]=configuredClockSpeed
9525 aMemory[k,i,10]=dataWidth
9526 aMemory[k,i,11]=totalWidth
9527 aMemory[k,i,12]=deviceManufacturer
9528 aMemory[k,i,13]=devicePartNumber
9529 aMemory[k,i,14]=deviceSerialNumber
9530 aMemory[k,i,15]=mainLocator
9543 configuredClockSpeed=""
9546 deviceManufacturer=""
9548 deviceSerialNumber=""
9552 ## CRITICAL: gawk keeps changing integers to strings, so be explicit with int() in math
9553 # print primaryType "," arrayHandle "," location "," maxCapacity "," numberOfDevices "," use "," errorCorrection "," maxModuleSize "," moduleVoltage
9555 # print primaryType "," arrayHandle "," deviceSize "," bankLocator "," locator "," formFactor "," deviceType "," deviceTypeDetail "," deviceSpeed "," configuredClockSpeed "," dataWidth "," totalWidth "," deviceManufacturer "," devicePartNumber "," deviceSerialNumber "," mainLocator
9557 for ( m=1;m<=k;m++ ) {
9562 workingMaxCap=int(aArrayData[m,"maxCapacity16"])
9564 if ( bDebugger1 == "true" ){
9567 print "1: mmods: " aArrayData[m,"maxModuleSize"] " :dmmods: " aArrayData[m,"derivedModuleSize"] " :mcap: " workingMaxCap " :ucap: " aArrayData[m,"usedCapacity"]
9569 # 1: if max cap 1 is null, and max cap 2 not null, use 2
9570 if ( workingMaxCap == 0 ) {
9571 if ( aArrayData[m,"maxCapacity5"] != 0 ) {
9572 workingMaxCap=aArrayData[m,"maxCapacity5"]
9575 if ( aArrayData[m,"deviceCount16"] == "" ) {
9576 aArrayData[m,"deviceCount16"] = 0
9578 if ( bDebugger1 == "true" ){
9579 print "2: mmods: " aArrayData[m,"maxModuleSize"] " :dmmods: " aArrayData[m,"derivedModuleSize"] " :mcap: " workingMaxCap " :ucap: " aArrayData[m,"usedCapacity"]
9581 # 2: now check to see if actually found module sizes are > than listed max module, replace if >
9582 if (aArrayData[m,"maxModuleSize"] != 0 && aArrayData[m,"derivedModuleSize"] != 0 && int(aArrayData[m,"derivedModuleSize"]) > int(aArrayData[m,"maxModuleSize"]) ) {
9583 aArrayData[m,"maxModuleSize"]=aArrayData[m,"derivedModuleSize"]
9586 aArrayData[m,"maxModuleSize"]=int(aArrayData[m,"maxModuleSize"])
9587 aArrayData[m,"derivedModuleSize"]=int(aArrayData[m,"derivedModuleSize"])
9588 aArrayData[m,"usedCapacity"]=int(aArrayData[m,"usedCapacity"])
9589 workingMaxCap=int(workingMaxCap)
9591 # note: some cases memory capacity == max module size, so one stick will fill it
9592 # but I think only with cases of 2 slots does this happen, so if > 2, use the count of slots.
9593 if ( bDebugger1 == "true" ){
9594 print "3: fmod: " aArrayData[m,"deviceCountFound"] " :modc: " aArrayData[m,"deviceCount16"] " :maxc1: " aArrayData[m,"maxCapacity5"] " :maxc2: " aArrayData[m,"maxCapacity16"]
9596 if (workingMaxCap != 0 && ( aArrayData[m,"deviceCountFound"] != 0 || aArrayData[m,"deviceCount16"] != 0 ) ) {
9597 aArrayData[m,"deviceCount16"]=int(aArrayData[m,"deviceCount16"])
9598 ## first check that actual memory found is not greater than listed max cap, or
9599 ## checking to see module count * max mod size is not > used capacity
9600 if ( aArrayData[m,"usedCapacity"] != 0 && aArrayData[m,"maxCapacity16"] != 0 ) {
9601 if ( aArrayData[m,"usedCapacity"] > workingMaxCap ) {
9602 if ( aArrayData[m,"maxModuleSize"] != 0 &&
9603 aArrayData[m,"usedCapacity"] < aArrayData[m,"deviceCount16"] * aArrayData[m,"maxModuleSize"] ) {
9604 workingMaxCap=aArrayData[m,"deviceCount16"] * aArrayData[m,"maxModuleSize"]
9606 if ( bDebugger1 == "true" ){
9610 else if ( aArrayData[m,"derivedModuleSize"] != 0 &&
9611 aArrayData[m,"usedCapacity"] < aArrayData[m,"deviceCount16"] * aArrayData[m,"derivedModuleSize"] ) {
9612 workingMaxCap=aArrayData[m,"deviceCount16"] * aArrayData[m,"derivedModuleSize"]
9614 if ( bDebugger1 == "true" ){
9619 workingMaxCap=aArrayData[m,"usedCapacity"]
9621 if ( bDebugger1 == "true" ){
9627 # note that second case will never really activate except on virtual machines and maybe
9629 if ( estCap == "" ) {
9630 # do not do this for only single modules found, max mod size can be equal to the array size
9631 if ( ( aArrayData[m,"deviceCount16"] > 1 && aArrayData[m,"deviceCountFound"] > 1 ) &&
9632 ( workingMaxCap < aArrayData[m,"derivedModuleSize"] * aArrayData[m,"deviceCount16"] ) ) {
9633 workingMaxCap = aArrayData[m,"derivedModuleSize"] * aArrayData[m,"deviceCount16"]
9635 if ( bDebugger1 == "true" ){
9639 else if ( ( aArrayData[m,"deviceCountFound"] > 0 ) &&
9640 ( workingMaxCap < aArrayData[m,"derivedModuleSize"] * aArrayData[m,"deviceCountFound"] ) ) {
9641 workingMaxCap = aArrayData[m,"derivedModuleSize"] * aArrayData[m,"deviceCountFound"]
9643 if ( bDebugger1 == "true" ){
9647 ## handle cases where we have type 5 data: mms x device count equals type 5 max cap
9648 # however do not use it if cap / devices equals the derived module size
9649 else if ( aArrayData[m,"maxModuleSize"] > 0 &&
9650 ( aArrayData[m,"maxModuleSize"] * aArrayData[m,"deviceCount16"] == aArrayData[m,"maxCapacity5"] ) &&
9651 aArrayData[m,"maxCapacity5"] != aArrayData[m,"maxCapacity16"] &&
9652 aArrayData[m,"maxCapacity16"] / aArrayData[m,"deviceCount16"] != aArrayData[m,"derivedModuleSize"] ) {
9653 workingMaxCap = aArrayData[m,"maxCapacity5"]
9654 altCap=aArrayData[m,"maxCapacity5"] # not used
9656 if ( bDebugger1 == "true" ){
9663 workingMaxCap=int(workingMaxCap)
9664 if ( bDebugger1 == "true" ){
9665 print "4: mmods: " aArrayData[m,"maxModuleSize"] " :dmmods: " aArrayData[m,"derivedModuleSize"] " :mcap: " workingMaxCap " :ucap: " aArrayData[m,"usedCapacity"]
9667 # some cases of type 5 have too big module max size, just dump the data then since
9668 # we cannot know if it is valid or not, and a guess can be wrong easily
9669 if ( aArrayData[m,"maxModuleSize"] != 0 && workingMaxCap != "" &&
9670 ( aArrayData[m,"maxModuleSize"] > workingMaxCap ) ){
9671 aArrayData[m,"maxModuleSize"] = 0
9674 if ( bDebugger1 == "true" ){
9675 print "5: dms: " aArrayData[m,"derivedModuleSize"] " :dc: " aArrayData[m,"deviceCount16"] " :wmc: " workingMaxCap
9677 ## prep for output ##
9678 if (aArrayData[m,"maxModuleSize"] == 0 ){
9679 aArrayData[m,"maxModuleSize"]=""
9681 if ( estCap == "" && int(aArrayData[m,"derivedModuleSize"]) > 0 &&
9682 workingMaxCap > ( int(aArrayData[m,"derivedModuleSize"]) * int(aArrayData[m,"deviceCount16"]) * 4 ) ) {
9684 if ( bDebugger1 == "true" ){
9690 # case where listed max cap is too big for actual slots x max cap, eg:
9691 # listed max cap, 8gb, max mod 2gb, slots 2
9692 if ( estCap == "" && aArrayData[m,"maxModuleSize"] > 0 ) {
9693 if ( int(workingMaxCap) > int(aArrayData[m,"maxModuleSize"]) * aArrayData[m,"deviceCount16"] ) {
9695 if ( bDebugger1 == "true" ){
9700 if (aArrayData[m,"maxModuleSize"] > 1023 ) {
9701 aArrayData[m,"maxModuleSize"]=aArrayData[m,"maxModuleSize"] / 1024 " GB"
9704 aArrayData[m,"maxModuleSize"]=aArrayData[m,"maxModuleSize"] " MB"
9707 if ( aArrayData[m,"deviceCount16"] == 0 ) {
9708 aArrayData[m,"deviceCount16"] = ""
9710 if (workingMaxCap != 0 ) {
9711 if ( workingMaxCap < 1024 ) {
9712 workingMaxCap = workingMaxCap
9715 else if ( workingMaxCap < 1024000 ) {
9716 workingMaxCap = workingMaxCap / 1024
9719 else if ( workingMaxCap < 1024000000 ) {
9720 workingMaxCap = workingMaxCap / 1024000
9723 # we only want a max 2 decimal places, this trick gives 0 to 2
9724 workingMaxCap=gensub(/([0-9]+\.[0-9][0-9]).*/,"\\1",1,workingMaxCap)
9725 workingMaxCap = workingMaxCap unit estCap
9732 print aArrayData[m,"data-type"] "," aArrayData[m,"handle"] "," aArrayData[m,"location"] "," workingMaxCap "," aArrayData[m,"deviceCount16"] "," aArrayData[m,"use"] "," aArrayData[m,"errorCorrection"] "," aArrayData[m,"maxModuleSize"] estMod "," aArrayData[m,"voltage5"]
9733 # print device rows next
9734 for ( j=0;j<=100;j++ ) {
9735 if (aMemory[m,j,0] != "" ) {
9737 workingSize=aMemory[m,j,2]
9738 if ( workingSize ~ /^[0-9]+$/ ) {
9739 workingSize=int(workingSize)
9740 if ( workingSize < 1024 ) {
9741 workingSize = workingSize
9744 else if ( workingSize < 1024000 ) {
9745 workingSize = workingSize / 1024
9748 else if ( workingSize < 1024000000 ) {
9749 workingSize = workingSize / 1024000
9752 # we only want a max 2 decimal places, this trick gives 0 to 2
9753 workingSize=gensub(/([0-9]+\.[0-9][0-9]).*/,"\\1",1,workingSize)
9754 workingSize = workingSize unit
9756 print aMemory[m,j,0] "," aMemory[m,j,1] "," workingSize "," aMemory[m,j,3] "," aMemory[m,j,4] "," aMemory[m,j,5] "," aMemory[m,j,6] "," aMemory[m,j,7] "," aMemory[m,j,8] "," aMemory[m,j,9] "," aMemory[m,j,10] "," aMemory[m,j,11] "," aMemory[m,j,12] "," aMemory[m,j,13] "," aMemory[m,j,14] "," aMemory[m,j,15] "," aMemory[m,j,16] "," aMemory[m,j,17]
9763 }' <<< "$DMIDECODE_DATA" ) )
9767 a_temp=${A_MEMORY_DATA[@]}
9769 # echo "${a_temp[@]}"
9770 log_function_data "A_MEMORY_DATA: $a_temp"
9775 # Repos will be added as we get distro package manager data to create the repo data.
9776 # This method will output the file name also, which is useful to create output that's
9777 # neat and readable. Each line of the total number contains the following sections,
9778 # separated by a : for splitting in the print function
9779 # part one, repo type/string : part two, file name, if present, of info : part 3, repo data
9780 # args: $1 - [file location of debug data file - optional, only for debugging data collection]
9784 local repo_file='' repo_data_working='' repo_data_working2='' repo_line='' repo_files=''
9786 local apt_file='/etc/apt/sources.list' yum_repo_dir='/etc/yum.repos.d/' yum_conf='/etc/yum.conf'
9787 local pacman_conf='/etc/pacman.conf' pacman_repo_dir='/etc/pacman.d/' pisi_dir='/etc/pisi/'
9788 local zypp_repo_dir='/etc/zypp/repos.d/' ports_conf='/etc/portsnap.conf' openbsd_conf='/etc/pkg.conf'
9789 local bsd_pkg_dir='/usr/local/etc/pkg/repos/' slackpkg_file='/etc/slackpkg/mirrors'
9790 local netbsd_file='/usr/pkg/etc/pkgin/repositories.conf' freebsd_file='/etc/freebsd-update.conf'
9791 local freebsd_pkg_file='/etc/pkg/FreeBSD.conf' slackpkg_plus_file='/etc/slackpkg/slackpkgplus.conf'
9792 local portage_repo_dir='/etc/portage/repos.conf/'
9794 # apt - debian, buntus, also sometimes some yum/rpm repos may create apt repos here as well
9795 if [[ -f $apt_file || -d $apt_file.d ]];then
9796 repo_files=$(ls /etc/apt/sources.list /etc/apt/sources.list.d/*.list 2>/dev/null)
9797 log_function_data "apt repo files: $repo_files"
9798 for repo_file in $repo_files
9801 cat $repo_file &> $1/repo-data_${repo_file//\//-}.txt
9803 repo_data_working="$( gawk -v repoFile="$repo_file" '
9804 !/^[[:space:]]*$|^[[:space:]]*#/ {
9805 print "apt sources^" repoFile "^" $0
9807 get_repo_builder "$repo_data_working"
9809 repo_data_working=''
9811 # yum - fedora, redhat, centos, etc. Note that rpmforge also may create apt sources
9812 # in /etc/apt/sources.list.d/. Therefore rather than trying to assume what package manager is
9813 # actually running, inxi will merely note the existence of each repo type for apt/yum.
9814 # Also, in rpm, you can install apt-rpm for the apt-get command, so it's not good to check for
9815 # only the commands in terms of selecting which repos to show.
9816 if [[ -d $yum_repo_dir || -f $yum_conf || -d $zypp_repo_dir ]];then
9817 if [[ -d $yum_repo_dir || -f $yum_conf ]];then
9818 # older redhats put their yum data in /etc/yum.conf
9819 repo_files=$( ls $yum_repo_dir*.repo $yum_conf 2>/dev/null )
9821 log_function_data "yum repo files: $repo_files"
9822 elif [[ -d $zypp_repo_dir ]];then
9823 repo_files=$( ls $zypp_repo_dir*.repo 2>/dev/null )
9825 log_function_data "zypp repo files: $repo_files"
9827 if [[ -n $repo_files ]];then
9828 for repo_file in $repo_files
9831 cat $repo_file &> $1/repo-data_${repo_file//\//-}.txt
9833 repo_data_working="$( gawk -v repoFile="$repo_file" '
9834 # construct the string for the print function to work with, file name: data
9835 function print_line( fileName, repoId, repoUrl ){
9836 print "'$repo_name' sources^" fileName "^" repoId repoUrl
9845 # this is a hack, assuming that each item has these fields listed, we collect the 3
9846 # items one by one, then when the url/enabled fields are set, we print it out and
9847 # reset the data. Not elegant but it works. Note that if enabled was not present
9848 # we assume it is enabled then, and print the line, reset the variables. This will
9849 # miss the last item, so it is printed if found in END
9851 if ( urlData != "" && repoTitle != "" ){
9852 print_line( repoFile, repoTitle, urlData )
9857 gsub(/\[|\]/, "", $1 ) # strip out the brackets
9858 repoTitle = $1 " ~ "
9860 /^(mirrorlist|baseurl)/ {
9861 sub( /(mirrorlist|baseurl)[[:space:]]*=[[:space:]]*/, "", $1 ) # strip out the field starter
9864 # note: enabled = 1. enabled = 0 means disabled
9865 /^enabled[[:space:]]*=/ {
9868 # print out the line if all 3 values are found, otherwise if a new
9869 # repoTitle is hit above, it will print out the line there instead
9871 if ( urlData != "" && enabledStatus != "" && repoTitle != "" ){
9872 if ( enabledStatus !~ /enabled[[:space:]]*=[[:space:]]*0/ ){
9873 print_line( repoFile, repoTitle, urlData )
9881 # print the last one if there is data for it
9882 if ( urlData != "" && repoTitle != "" ){
9883 print_line( repoFile, repoTitle, urlData )
9887 # then load the global for each file as it gets filled
9888 get_repo_builder "$repo_data_working"
9891 repo_data_working=''
9892 # pacman - archlinux, going to assume that pisi and arch/pacman, etc don't have the above issue with apt/yum
9893 elif [[ -f $pacman_conf ]];then
9894 # get list of mirror include files, trim white space off ends
9895 repo_data_working="$( gawk '
9900 /^[[:space:]]*Include/ {
9901 sub(/^[[:space:]]+|[[:space:]]+$/,"",$2)
9905 # sort into unique paths only, to be used to search for server = data
9906 repo_data_working=$( sort -bu <<< "$repo_data_working" | uniq )
9907 repo_data_working="$repo_data_working $pacman_conf"
9908 for repo_file in $repo_data_working
9911 cat $repo_file &> $1/repo-data_${repo_file//\//-}.txt
9913 if [[ -f $repo_file ]];then
9914 # inserting a new line after each found / processed match
9915 repo_data_working2="$repo_data_working2$( gawk -v repoFile=$repo_file '
9920 /^[[:space:]]*Server/ {
9921 sub(/^[[:space:]]+|[[:space:]]+$/,"",$2)
9922 print "pacman repo servers^" repoFile "^" $2 "\\n"
9926 echo "Error: file listed in $pacman_conf does not exist - $repo_file"
9929 # execute line breaks
9930 REPO_DATA="$( echo -e $repo_data_working2 )"
9931 repo_data_working=''
9933 elif [[ -f $slackpkg_file || -f $slackpkg_plus_file ]];then
9934 # note, only one file, but loop it in case more are added in future
9935 if [[ -f $slackpkg_file ]];then
9937 cat $slackpkg_file &> $1/repo-data_${slackpkg_file//\//-}.txt
9939 repo_data_working="$( gawk -v repoFile="$slackpkg_file" '
9940 !/^[[:space:]]*$|^[[:space:]]*#/ {
9941 print "slackpkg sources^" repoFile "^" $0
9942 }' $slackpkg_file )"
9943 get_repo_builder "$repo_data_working"
9945 if [[ -f $slackpkg_plus_file ]];then
9947 cat $slackpkg_plus_file &> $1/repo-data_${slackpkg_plus_file//\//-}.txt
9949 # see sample for syntax
9950 repo_data_working="$( gawk -F '=' -v repoFile="$slackpkg_plus_file" '
9954 # stop if set to off
9960 # get list of current active repos
9964 # print out repo line if found
9966 if ( activeRepos != "" ) {
9967 gsub(/MIRRORPLUS\['\''|'\''\]/,"",$1)
9968 if ( match( activeRepos, $1 ) ){
9969 print "slackpkg+ sources^" repoFile "^" $1 " ~ " $2
9972 }' $slackpkg_plus_file )"
9973 get_repo_builder "$repo_data_working"
9975 repo_data_working=''
9976 elif [[ -d $portage_repo_dir && -n $( type -p emerge ) ]];then
9977 repo_files=$( ls $portage_repo_dir*.conf 2>/dev/null )
9979 log_function_data "portage repo files: $repo_files"
9980 if [[ -n $repo_files ]];then
9981 for repo_file in $repo_files
9984 cat $repo_file &> $1/repo-data_${repo_file//\//-}.txt
9986 repo_data_working="$( gawk -v repoFile="$repo_file" '
9987 # construct the string for the print function to work with, file name: data
9988 function print_line( fileName, repoId, repoUrl ){
9989 print "'$repo_name' sources^" fileName "^" repoId repoUrl
9998 # this is a hack, assuming that each item has these fields listed, we collect the 3
9999 # items one by one, then when the url/enabled fields are set, we print it out and
10000 # reset the data. Not elegant but it works. Note that if enabled was not present
10001 # we assume it is enabled then, and print the line, reset the variables. This will
10002 # miss the last item, so it is printed if found in END
10004 if ( urlData != "" && repoTitle != "" ){
10005 print_line( repoFile, repoTitle, urlData )
10010 gsub(/\[|\]/, "", $1 ) # strip out the brackets
10011 repoTitle = $1 " ~ "
10014 sub( /sync-uri[[:space:]]*=[[:space:]]*/, "", $1 ) # strip out the field starter
10017 # note: enabled = 1. enabled = 0 means disabled
10018 /^auto-sync[[:space:]]*=/ {
10019 sub( /auto-sync[[:space:]]*=[[:space:]]*/, "", $1 ) # strip out the field starter
10022 # print out the line if all 3 values are found, otherwise if a new
10023 # repoTitle is hit above, it will print out the line there instead
10025 if ( urlData != "" && enabledStatus != "" && repoTitle != "" ){
10026 if ( enabledStatus !~ /enabled[[:space:]]*=[[:space:]]*0/ ){
10027 print_line( repoFile, repoTitle, urlData )
10035 # print the last one if there is data for it
10036 if ( urlData != "" && repoTitle != "" ){
10037 print_line( repoFile, repoTitle, urlData )
10041 # then load the global for each file as it gets filled
10042 get_repo_builder "$repo_data_working"
10045 elif [[ -d $pisi_dir && -n $( type -p pisi ) ]];then
10046 REPO_DATA="$( pisi list-repo )"
10047 if [[ -n $1 ]];then
10048 echo "$REPO_DATA" &> $1/repo-data_pisi-list-repo.txt
10050 log_function_data "pisi-list-repo: $REPO_DATA"
10051 # now we need to create the structure: repo info: repo path
10052 # we do that by looping through the lines of the output and then
10053 # putting it back into the <data>:<url> format print repos expects to see
10054 # note this structure in the data, so store first line and make start of line
10055 # then when it's an http line, add it, and create the full line collection.
10056 # Pardus-2009.1 [Aktiv]
10057 # http://packages.pardus.org.tr/pardus-2009.1/pisi-index.xml.bz2
10059 # http://packages.pardus.org.tr/contrib-2009/pisi-index.xml.bz2
10060 while read repo_line
10062 repo_line=$( gawk '
10064 # need to dump leading/trailing spaces and clear out color codes for irc output
10065 sub(/^[[:space:]]+|[[:space:]]+$/,"",$0)
10066 # gsub(/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]/,"",$0) # leaving this pattern in case need it
10067 gsub(/
\e\[([0-9];)?[0-9]+m/,"",$0)
10069 }' <<< $repo_line )
10070 if [[ -n $( grep '://' <<< $repo_line ) ]];then
10071 repo_data_working="$repo_data_working^$repo_line\n"
10073 repo_data_working="${repo_data_working}pisi repo^$repo_line"
10075 done <<< "$REPO_DATA"
10076 # echo and execute the line breaks inserted
10077 REPO_DATA="$( echo -e $repo_data_working )"
10078 repo_data_working=''
10079 # Mandriva/Mageia using: urpmq
10080 elif type -p urpmq &>/dev/null;then
10081 REPO_DATA="$( urpmq --list-media active --list-url )"
10082 if [[ -n $1 ]];then
10083 echo "$REPO_DATA" &> $1/repo-data_urpmq-list-media-active.txt
10085 # now we need to create the structure: repo info: repo path
10086 # we do that by looping through the lines of the output and then
10087 # putting it back into the <data>:<url> format print repos expects to see
10088 # note this structure in the data, so store first line and make start of line
10089 # then when it's an http line, add it, and create the full line collection.
10090 # Contrib ftp://ftp.uwsg.indiana.edu/linux/mandrake/official/2011/x86_64/media/contrib/release
10091 # Contrib Updates ftp://ftp.uwsg.indiana.edu/linux/mandrake/official/2011/x86_64/media/contrib/updates
10092 # Non-free ftp://ftp.uwsg.indiana.edu/linux/mandrake/official/2011/x86_64/media/non-free/release
10093 # Non-free Updates ftp://ftp.uwsg.indiana.edu/linux/mandrake/official/2011/x86_64/media/non-free/updates
10094 # Nonfree Updates (Local19) /mnt/data/mirrors/mageia/distrib/cauldron/x86_64/media/nonfree/updates
10095 while read repo_line
10097 repo_line=$( gawk '
10099 # need to dump leading/trailing spaces and clear out color codes for irc output
10100 sub(/^[[:space:]]+|[[:space:]]+$/,"",$0)
10101 # gsub(/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]/,"",$0) # leaving this pattern in case need it
10102 gsub(/
\e\[([0-9];)?[0-9]+m/,"",$0)
10104 }' <<< $repo_line )
10105 # urpmq output is the same each line, repo name space repo url, can be:
10106 # rsync://, ftp://, file://, http:// OR repo is locally mounted on FS in some cases
10107 if [[ -n $( grep -E '(://|[[:space:]]/)' <<< $repo_line ) ]];then
10108 # cut out the repo first
10109 repo_data_working2=$( grep -Eo '([^[:space:]]+://|[[:space:]]/).*' <<< $repo_line )
10110 # then get the repo name string by slicing out the url string
10111 repo_name=$( sed "s|[[:space:]]*$repo_data_working2||" <<< $repo_line )
10112 repo_data_working="${repo_data_working}urpmq repo^$repo_name^$repo_data_working2\n"
10114 done <<< "$REPO_DATA"
10115 # echo and execute the line breaks inserted
10116 REPO_DATA="$( echo -e $repo_data_working )"
10117 elif [[ -f $ports_conf || -f $freebsd_file || -d $bsd_pkg_dir ]];then
10118 if [[ -f $ports_conf ]];then
10119 if [[ -n $1 ]];then
10120 cat $ports_conf &> $1/repo-data_${ports_conf//\//-}.txt
10122 repo_data_working="$( gawk -F '=' -v repoFile=$ports_conf '
10127 print "BSD ports server^" repoFile "^" $2
10131 get_repo_builder "$repo_data_working"
10133 if [[ -f $freebsd_file ]];then
10134 if [[ -n $1 ]];then
10135 cat $freebsd_file &> $1/repo-data_${freebsd_file//\//-}.txt
10137 repo_data_working="$( gawk -v repoFile=$freebsd_file '
10142 print "FreeBSD update server^" repoFile "^" $2
10146 get_repo_builder "$repo_data_working"
10148 if [[ -f $freebsd_pkg_file ]];then
10149 if [[ -n $1 ]];then
10150 cat $freebsd_pkg_file &> $1/repo-data_${freebsd_pkg_file//\//-}.txt
10152 repo_data_working="$( gawk -F ': ' -v repoFile=$freebsd_pkg_file '
10156 $1 ~ /^[[:space:]]*url/ {
10157 gsub(/\"|pkg\+|,/,"",$2)
10158 print "FreeBSD default pkg server^" repoFile "^" $2
10161 ' $freebsd_pkg_file )"
10162 get_repo_builder "$repo_data_working"
10165 if [[ -d $bsd_pkg_dir ]];then
10166 repo_files=$(ls ${bsd_pkg_dir}*.conf 2>/dev/null )
10167 for repo_file in $repo_files
10169 if [[ -n $1 ]];then
10170 cat $repo_file &> $1/repo-data_${repo_file//\//-}.txt
10172 repo_data_working="$( gawk -v repoFile=$repo_file '
10181 gsub(/{|}|^#.*/,"",$0)
10187 while ( getline && $0 !~ /^[[:space:]]*$/ ) {
10188 gsub(/'"$BAN_LIST_ARRAY"'/,"",$0)
10189 gsub(/({|}|^[[:space:]]+|[[:space:]]+$)/,"",$1)
10190 gsub(/({|}|^[[:space:]]+|[[:space:]]+$)/,"",$2)
10191 if ( $1 == "url" ) {
10194 if ( $1 == "enabled" ) {
10195 if ( $2 == "yes" ) {
10196 print "BSD pkg server^" repoFile "^" repoName " ~ " repoUrl
10202 get_repo_builder "$repo_data_working"
10205 repo_data_working=''
10206 elif [[ -f $openbsd_conf ]];then
10207 if [[ -n $1 ]];then
10208 cat $openbsd_conf &> $1/repo-data_${openbsd_conf//\//-}.txt
10210 REPO_DATA="$( gawk -F '=' -v repoFile=$openbsd_conf '
10215 print "OpenBSD pkg mirror^" repoFile "^" $2
10218 elif [[ -f $netbsd_file ]];then
10219 # note, only one file, but loop it in case more are added in future
10220 for repo_file in $netbsd_file
10222 if [[ -n $1 ]];then
10223 cat $repo_file &> $1/repo-data_${repo_file//\//-}.txt
10225 repo_data_working="$( gawk -v repoFile="$repo_file" '
10226 !/^[[:space:]]*$|^[[:space:]]*#/ {
10227 print "NetBSD pkg servers^" repoFile "^" $0
10229 get_repo_builder "$repo_data_working"
10231 repo_data_working=''
10235 # build the total REPO_DATA global here
10236 # args: $1 - the repo line/s
10239 if [[ -n $1 ]];then
10240 if [[ -z $REPO_DATA ]];then
10243 REPO_DATA="$REPO_DATA
10249 get_runlevel_data()
10254 if type -p runlevel &>/dev/null;then
10255 runlvl="$( runlevel | gawk '{ print $2 }' )"
10261 # note: it appears that at least as of 2014-01-13, /etc/inittab is going to be used for
10262 # default runlevel in upstart/sysvinit. systemd default is not always set so check to see
10264 get_runlevel_default()
10267 local default_runlvl=''
10268 local inittab='/etc/inittab'
10269 local systemd_default='/etc/systemd/system/default.target'
10270 local upstart_default='/etc/init/rc-sysinit.conf'
10272 # note: systemd systems do not necessarily have this link created
10273 if [[ -L $systemd_default ]];then
10274 default_runlvl=$( readlink $systemd_default )
10275 if [[ -n $default_runlvl ]];then
10276 default_runlvl=${default_runlvl##*/}
10278 # http://askubuntu.com/questions/86483/how-can-i-see-or-change-default-run-level
10279 # note that technically default can be changed at boot but for inxi purposes that does
10280 # not matter, we just want to know the system default
10281 elif [[ -e $upstart_default ]];then
10282 # env DEFAULT_RUNLEVEL=2
10283 default_runlvl=$( gawk -F '=' '/^env[[:space:]]+DEFAULT_RUNLEVEL/ {
10285 }' $upstart_default )
10288 # handle weird cases where null but inittab exists
10289 if [[ -z $default_runlvl && -f $inittab ]];then
10290 default_runlvl=$( gawk -F ':' '
10291 /^id.*initdefault/ {
10295 echo $default_runlvl
10307 if [[ -n $Sensors_Data ]];then
10308 # note: non-configured sensors gives error message, which we need to redirect to stdout
10309 # also, -F ':' no space, since some cases have the data starting right after,like - :1287
10310 A_SENSORS_DATA=( $(
10311 gawk -F ':' -v userCpuNo="$SENSORS_CPU_NO" '
10314 core0Temp="" # these only if all else fails...
10315 cpuPeciTemp="" # use if temps are missing or wrong
10319 indexCountaFanMain=0
10320 indexCountaFanDefault=0
10331 tempDiff=20 # for C, handled for F after that is determined
10332 tempFanType="" # set to 1 or 2
10337 # new data arriving: gpu temp in sensors, have to skip that
10338 /^('"$SENSORS_GPU_SEARCH"')-pci/ {
10339 while ( getline && !/^$/ ) {
10340 # do nothing, just skip it
10343 # dumping the extra + signs after testing for them, nobody has negative temps.
10344 # also, note gawk treats ° as a space, so we have to get the C/F data
10345 # there are some guesses here, but with more sensors samples it will get closer.
10346 # note: using arrays starting at 1 for all fan arrays to make it easier overall
10347 # more validation because gensub if fails to get match returns full string, so
10348 # we have to be sure we are working with the actual real string before assiging
10349 # data to real variables and arrays. Extracting C/F degree unit as well to use
10350 # when constructing temp items for array.
10351 # note that because of charset issues, no tempUnit="°" tempWorkingUnit degree sign
10352 # used, but it is required in testing regex to avoid error.
10353 /^(M\/B|MB|SIO|SYS)(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
10354 moboTemp=gensub( /[ \t]+\+([0-9\.]*)(.*)/, "\\1", 1, $2 )
10355 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
10356 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
10357 tempUnit=tempWorkingUnit
10360 # issue 58 msi/asus show wrong for CPUTIN so overwrite it if PECI 0 is present
10361 # http://www.spinics.net/lists/lm-sensors/msg37308.html
10362 /^CPU(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
10363 cpuTemp=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
10364 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
10365 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
10366 tempUnit=tempWorkingUnit
10369 /^PECI[[:space:]]Agent[[:space:]]0(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
10370 cpuPeciTemp=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
10371 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
10372 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
10373 tempUnit=tempWorkingUnit
10376 /^(P\/S|Power)(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
10377 psuTemp=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
10378 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
10379 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
10380 tempUnit=tempWorkingUnit
10383 # for temp1/2 only use temp1/2 if they are null or greater than the last ones
10384 $1 ~ /^temp1$/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
10385 tempWorking=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
10386 if ( temp1 == "" || ( tempWorking != "" && tempWorking > 0 ) ) {
10389 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
10390 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
10391 tempUnit=tempWorkingUnit
10394 $1 ~ /^temp2$/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
10395 tempWorking=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
10396 if ( temp2 == "" || ( tempWorking != "" && tempWorking > 0 ) ) {
10399 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
10400 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
10401 tempUnit=tempWorkingUnit
10404 # temp3 is only used as an absolute override for systems with all 3 present
10405 $1 ~ /^temp3$/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
10406 tempWorking=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
10407 if ( temp3 == "" || ( tempWorking != "" && tempWorking > 0 ) ) {
10410 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
10411 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
10412 tempUnit=tempWorkingUnit
10415 # final fallback if all else fails, funtoo user showed sensors putting
10416 # temp on wrapped second line, not handled
10417 /^(core0|core 0|Physical id 0)(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
10418 tempWorking=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
10419 if ( tempWorking != "" && core0Temp == "" && tempWorking > 0 ) {
10420 core0Temp=tempWorking
10422 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
10423 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
10424 tempUnit=tempWorkingUnit
10427 # note: can be cpu fan:, cpu fan speed:, etc. Some cases have no space before
10428 # $2 starts (like so :1234 RPM), so skip that space test in regex
10429 /^CPU(.*)[ \t]*([0-9]+)[ \t]RPM/ {
10430 aFanMain[1]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
10432 /^(M\/B|MB|SYS)(.*)[ \t]*([0-9]+)[ \t]RPM/ {
10433 aFanMain[2]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
10435 /(Power|P\/S|POWER)(.*)[ \t]*([0-9]+)[ \t]RPM/ {
10436 aFanMain[3]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
10438 # note that the counters are dynamically set for fan numbers here
10439 # otherwise you could overwrite eg aux fan2 with case fan2 in theory
10440 # note: cpu/mobo/ps are 1/2/3
10441 # NOTE: test: ! i in array does NOT work, this appears to be an awk/gawk bug
10442 /^(AUX(1)? |CASE(1)? |CHASSIS(1)? )(.*)[ \t]*([0-9]+)[ \t]RPM/ {
10443 for ( i = 4; i < 7; i++ ){
10444 if ( i in aFanMain ){
10448 aFanMain[i]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
10453 /^(AUX([2-9]) |CASE([2-9]) |CHASSIS([2-9]) )(.*)[ \t]*([0-9]+)[ \t]RPM/ {
10454 for ( i = 5; i < 30; i++ ){
10455 if ( i in aFanMain ) {
10460 aFanMain[i]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
10465 # in rare cases syntax is like: fan1: xxx RPM
10466 /^(FAN(1)?[ \t:])(.*)[ \t]*([0-9]+)[ \t]RPM/ {
10467 aFanDefault[1]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
10469 /^FAN([2-9]|1[0-9])(.*)[ \t]*([0-9]+)[ \t]RPM/ {
10470 fanWorking=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
10471 sysFanNu=gensub( /fan([0-9]+)/, "\\1", 1, $1 )
10472 if ( sysFanNu ~ /^([0-9]+)$/ ) {
10473 # add to array if array index does not exist OR if number is > existing number
10474 if ( sysFanNu in aFanDefault ) {
10475 if ( fanWorking >= aFanDefault[sysFanNu] ) {
10476 aFanDefault[sysFanNu]=fanWorking
10480 aFanDefault[sysFanNu]=fanWorking
10485 # first we need to handle the case where we have to determine which temp/fan to use for cpu and mobo:
10486 # note, for rare cases of weird cool cpus, user can override in their prefs and force the assignment
10487 # this is wrong for systems with > 2 tempX readings, but the logic is too complex with 3 variables
10488 # so have to accept that it will be wrong in some cases, particularly for motherboard temp readings.
10489 if ( temp1 != "" && temp2 != "" ){
10490 if ( userCpuNo != "" && userCpuNo ~ /(1|2)/ ) {
10491 tempFanType=userCpuNo
10494 # first some fringe cases with cooler cpu than mobo: assume which is cpu temp based on fan speed
10495 # but only if other fan speed is 0.
10496 if ( temp1 >= temp2 && 1 in aFanDefault && 2 in aFanDefault && aFanDefault[1] == 0 && aFanDefault[2] > 0 ) {
10499 else if ( temp2 >= temp1 && 1 in aFanDefault && 2 in aFanDefault && aFanDefault[2] == 0 && aFanDefault[1] > 0 ) {
10502 # then handle the standard case if these fringe cases are false
10503 else if ( temp1 >= temp2 ) {
10511 # need a case for no temps at all reported, like with old intels
10512 else if ( temp2 == "" && cpuTemp == "" ){
10513 if ( temp1 == "" && moboTemp == "" ){
10516 else if ( temp1 != "" && moboTemp == "" ){
10519 else if ( temp1 != "" && moboTemp != "" ){
10523 # convert the diff number for F, it needs to be bigger that is
10524 if ( tempUnit == "F" ) {
10525 tempDiff = tempDiff * 1.8
10527 if ( cpuTemp != "" ) {
10528 # specific hack to handle broken CPUTIN temps with PECI
10529 if ( cpuPeciTemp != "" && ( cpuTemp - cpuPeciTemp ) > tempDiff ){
10530 cpuTempReal=cpuPeciTemp
10532 # then get the real cpu temp, best guess is hottest is real
10534 cpuTempReal=cpuTemp
10538 if ( tempFanType != "" ){
10539 # there are some weird scenarios
10540 if ( tempFanType == 1 ){
10541 if ( temp1 != "" && temp2 != "" && temp2 > temp1 ) {
10549 if ( temp1 != "" && temp2 != "" && temp1 > temp2 ) {
10558 cpuTempReal=temp1 # can be null, that is ok
10560 if ( cpuTempReal != "" ) {
10561 # using temp3 is just not reliable enough, more errors caused than fixed imo
10562 #if ( temp3 != "" && temp3 > cpuTempReal ) {
10563 # cpuTempReal=temp3
10565 # there are some absurdly wrong temp1: acpitz-virtual-0 temp1: +13.8°C
10566 if ( core0Temp != "" && (core0Temp - cpuTempReal) > tempDiff ) {
10567 cpuTempReal=core0Temp
10571 # if all else fails, use core0/peci temp if present and cpu is null
10572 if ( cpuTempReal == "" ) {
10573 if ( core0Temp != "" ) {
10574 cpuTempReal=core0Temp
10576 # note that peci temp is known to be colder than the actual system
10577 # sometimes so it is the last fallback we want to use even though in theory
10578 # it is more accurate, but fact suggests theory wrong.
10579 else if ( cpuPeciTemp != "" ) {
10580 cpuTempReal=cpuPeciTemp
10583 # then the real mobo temp
10584 if ( moboTemp != "" ){
10585 moboTempReal=moboTemp
10587 else if ( tempFanType != "" ){
10588 if ( tempFanType == 1 ) {
10589 if ( temp1 != "" && temp2 != "" && temp2 > temp1 ) {
10597 if ( temp1 != "" && temp2 != "" && temp1 > temp2 ) {
10604 ## NOTE: not safe to assume temp3 is the mobo temp, sad to say
10605 #if ( temp1 != "" && temp2 != "" && temp3 != "" && temp3 < moboTempReal ) {
10606 # moboTempReal= temp3
10612 # then set the cpu fan speed
10613 if ( aFanMain[1] == "" ) {
10614 # note, you cannot test for aFanDefault[1] or [2] != ""
10615 # because that creates an array item in gawk just by the test itself
10616 if ( tempFanType == 1 && 1 in aFanDefault ) {
10617 aFanMain[1]=aFanDefault[1]
10620 else if ( tempFanType == 2 && 2 in aFanDefault ) {
10621 aFanMain[1]=aFanDefault[2]
10625 # then we need to get the actual numeric max array count for both fan arrays
10626 for (i = 0; i <= 29; i++) {
10627 if ( i in aFanMain && i > indexCountaFanMain ) {
10628 indexCountaFanMain=i
10631 for (i = 0; i <= 14; i++) {
10632 if ( i in aFanDefault && i > indexCountaFanDefault ) {
10633 indexCountaFanDefault=i
10636 # clear out any duplicates. Primary fan real trumps fan working always if same speed
10637 for (i = 1; i <= indexCountaFanMain; i++) {
10638 if ( i in aFanMain && aFanMain[i] != "" && aFanMain[i] != 0 ) {
10639 for (j = 1; j <= indexCountaFanDefault; j++) {
10640 if ( j in aFanDefault && aFanMain[i] == aFanDefault[j] ) {
10641 aFanDefault[j] = ""
10646 # now see if you can find the fast little mobo fan, > 5000 rpm and put it as mobo
10647 # note that gawk is returning true for some test cases when aFanDefault[j] < 5000
10648 # which has to be a gawk bug, unless there is something really weird with arrays
10649 # note: 500 > aFanDefault[j] < 1000 is the exact trigger, and if you manually
10650 # assign that value below, the > 5000 test works again, and a print of the value
10651 # shows the proper value, so the corruption might be internal in awk.
10652 # Note: gensub is the culprit I think, assigning type string for range 501-1000 but
10653 # type integer for all others, this triggers true for >
10654 for (j = 1; j <= indexCountaFanDefault; j++) {
10655 if ( j in aFanDefault && int( aFanDefault[j] ) > 5000 && aFanMain[2] == "" ) {
10656 aFanMain[2] = aFanDefault[j]
10657 aFanDefault[j] = ""
10658 # then add one if required for output
10659 if ( indexCountaFanMain < 2 ) {
10660 indexCountaFanMain = 2
10664 # then construct the sys_fan string for echo, note that iteration 1
10665 # makes: fanDefaultString separator null, ie, no space or ,
10666 for (j = 1; j <= indexCountaFanDefault; j++) {
10667 fanDefaultString = fanDefaultString separator aFanDefault[j]
10670 separator="" # reset to null for next loop
10671 # then construct the sys_fan string for echo
10672 for (j = 1; j <= indexCountaFanMain; j++) {
10673 fanMainString = fanMainString separator aFanMain[j]
10677 # and then build the temps:
10678 if ( moboTempReal != "" ) {
10679 moboTempReal = moboTempReal tempUnit
10681 if ( cpuTempReal != "" ) {
10682 cpuTempReal = cpuTempReal tempUnit
10684 # if they are ALL null, print error message. psFan is not used in output currently
10685 if ( cpuTempReal == "" && moboTempReal == "" && aFanMain[1] == "" && aFanMain[2] == "" && aFanMain[3] == "" && fanDefaultString == "" ) {
10686 print "No active sensors found. Have you configured your sensors yet?"
10689 # then build array arrays:
10690 print cpuTempReal "," moboTempReal "," psuTemp
10691 # this is for output, a null print line does NOT create a new array index in bash
10692 if ( fanMainString == "" ) {
10695 print fanMainString
10696 print fanDefaultString
10698 }' <<< "$Sensors_Data" ) )
10701 IFS="$ORIGINAL_IFS"
10702 a_temp=${A_SENSORS_DATA[@]}
10703 log_function_data "A_SENSORS_DATA: $a_temp"
10704 # echo "A_SENSORS_DATA: ${A_SENSORS_DATA[@]}"
10708 get_sensors_output()
10710 local sensors_data=''
10712 if type -p sensors &>/dev/null;then
10713 sensors_data="$( sensors 2>/dev/null )"
10714 if [[ -n "$sensors_data" ]];then
10715 # make sure the file ends in newlines then characters, the newlines are lost in the echo unless
10716 # the data ends in some characters
10717 sensors_data="$sensors_data\n\n###"
10720 echo -e "$sensors_data"
10727 local shell_type="$( ps -p $PPID -o comm= 2>/dev/null )"
10728 local shell_version=''
10730 if [[ $B_EXTRA_DATA == 'true' && -n $shell_type ]];then
10731 case $shell_type in
10733 shell_version=$( get_program_version "$shell_type" "^GNU[[:space:]]bash,[[:space:]]version" "4" | \
10734 sed $SED_RX 's/(\(.*|-release|-version)//' )
10736 # csh/dash use dpkg package version data, debian/buntu only
10738 shell_version=$( get_program_version "$shell_type" "^tcsh" "2" )
10741 shell_version=$( get_program_version "$shell_type" "$shell_type" "3" )
10744 shell_version=$( get_program_version "$shell_type" "version" "5" )
10747 shell_version=$( get_program_version "$shell_type" "^tcsh" "2" )
10750 shell_version=$( get_program_version "$shell_type" "^zsh" "2" )
10754 if [[ -n $shell_version ]];then
10755 shell_type="$shell_type $shell_version"
10758 log_function_data "shell type: $shell_type"
10765 local shell_parent='' script_parent=''
10767 # removed --no-headers to make bsd safe, adding in -j to make output the same
10768 script_parent=$( ps -j -fp $PPID 2>/dev/null | gawk '/'"$PPID"'/ { print $3 }' )
10769 log_function_data "script parent: $script_parent"
10770 shell_parent=$( ps -j -p $script_parent 2>/dev/null | gawk '/'"$script_parent"'/ { print $NF}' )
10771 # no idea why have to do script_parent action twice in su case, but you do, oh well.
10772 if [[ $shell_parent == 'su' ]];then
10773 script_parent=$( ps -j -fp $script_parent 2>/dev/null | gawk '/'"$script_parent"'/ { print $3 }' )
10774 script_parent=$( ps -j -fp $script_parent 2>/dev/null | gawk '/'"$script_parent"'/ { print $3 }' )
10775 shell_parent=$( ps -j -p $script_parent 2>/dev/null | gawk '/'"$script_parent"'/ { print $NF}' )
10778 log_function_data "shell parent final: $shell_parent"
10782 # this will be used for some bsd data types
10783 # args: $1 - option type
10788 local sysctl_data=''
10790 if [[ $B_SYSCTL ]];then
10791 # darwin sysctl has BOTH = and : separators, and repeats data. Why? No bsd discipline, that's for sure
10792 if [[ $BSD_VERSION == 'darwin' ]];then
10793 sysctl_data="$( sysctl -$1 | sed 's/[[:space:]]*=[[:space:]]*/: /' )"
10795 sysctl_data="$( sysctl -$1 )"
10798 # log_function_data "sysctl_data: $sysctl_data"
10799 echo "$sysctl_data"
10804 get_tty_console_irc()
10807 local tty_number=''
10808 if [[ -n $IRC_CLIENT ]];then
10809 tty_number=$( gawk '
10813 # if multiple irc clients open, can give wrong results
10814 # so make sure to also use the PPID number to get the right tty
10815 /.*'$PPID'.*'$IRC_CLIENT'/ {
10816 gsub(/[^0-9]/, "", $7)
10819 }' <<< "$Ps_aux_Data" )
10821 log_function_data "tty_number: $tty_number"
10830 local tty_number=$( tty 2>/dev/null | sed 's/[^0-9]*//g' )
10831 tty_number=${tty_number##*/}
10832 echo ${tty_number##*/}
10837 get_unmounted_partition_data()
10840 local a_unmounted_working='' mounted_partitions='' separator='|' unmounted_fs=''
10841 local dev_working='' uuid_working='' label_working='' a_raid_working='' raid_partitions=''
10843 if [[ $B_PARTITIONS_FILE == 'true' ]];then
10844 # set dev disk label/uuid data globals
10845 get_partition_dev_data 'label'
10846 get_partition_dev_data 'uuid'
10847 # load the raid data array here so we can exclude its partitions
10848 if [[ $B_RAID_SET != 'true' ]];then
10851 # sr0 type cd drives are showing up now as unmounted partitions
10852 mounted_partitions="scd[0-9]+|sr[0-9]+|cdrom[0-9]*|cdrw[0-9]*|dvd[0-9]*|dvdrw[0-9]*"
10853 # create list for slicing out the mounted partitions
10854 for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
10857 a_unmounted_working=( ${A_PARTITION_DATA[i]} )
10858 IFS="$ORIGINAL_IFS"
10859 if [[ -n ${a_unmounted_working[6]} ]];then
10860 mounted_partitions="$mounted_partitions$separator${a_unmounted_working[6]}"
10863 # now we need to exclude the mdraid partitions from the unmounted partition output as well
10864 for (( i=0; i < ${#A_RAID_DATA[@]}; i++ ))
10867 a_raid_working=( ${A_RAID_DATA[i]} )
10868 IFS="$ORIGINAL_IFS"
10869 if [[ -n ${a_raid_working[3]} ]];then
10870 raid_partitions=$( sed $SED_RX 's/(\([^\)]*\)|\[[^\]]*\])//g' <<< ${a_raid_working[3]}\
10871 | sed 's/[[:space:]]\+/|/g' )
10872 mounted_partitions="$mounted_partitions$separator$raid_partitions"
10876 A_UNMOUNTED_PARTITION_DATA=( $( grep -Ev '[[:space:]]('$mounted_partitions')$' $FILE_PARTITIONS | gawk '
10880 # note that size 1 means it is a logical extended partition container
10881 # lvm might have dm-1 type syntax
10882 # need to exclude loop type file systems, squashfs for example
10883 /[a-z][0-9]+$|dm-[0-9]+$/ && $3 != 1 && $NF !~ /loop/ {
10884 size = sprintf( "%.2f", $3*1024/1000**3 )
10885 print $4 "," size "G"
10888 for (( i=0; i < ${#A_UNMOUNTED_PARTITION_DATA[@]}; i++ ))
10891 a_unmounted_working=( ${A_UNMOUNTED_PARTITION_DATA[i]} )
10892 IFS="$ORIGINAL_IFS"
10894 label_working=$( grep -E "${a_unmounted_working[0]}$" <<< "$DEV_DISK_LABEL" | gawk '{
10897 uuid_working=$( grep -E "${a_unmounted_working[0]}$" <<< "$DEV_DISK_UUID" | gawk '{
10900 unmounted_fs=$( get_unmounted_partition_filesystem "/dev/${a_unmounted_working[0]}" )
10903 A_UNMOUNTED_PARTITION_DATA[i]=${a_unmounted_working[0]}","${a_unmounted_working[1]}","$label_working","$uuid_working","$unmounted_fs
10904 IFS="$ORIGINAL_IFS"
10907 # echo "${A_PARTITION_DATA[@]}"
10908 # echo "${A_UNMOUNTED_PARTITION_DATA[@]}"
10912 # a few notes, normally file -s requires root, but you can set user rights in /etc/sudoers.
10913 # list of file systems: http://en.wikipedia.org/wiki/List_of_file_systems
10914 # args: $1 - /dev/<disk><part> to be tested for
10915 get_unmounted_partition_filesystem()
10918 local partition_filesystem='' sudo_command=''
10920 if [[ $B_FILE_TESTED != 'true' ]];then
10921 B_FILE_TESTED='true'
10922 FILE_PATH=$( type -p file )
10925 if [[ $B_SUDO_TESTED != 'true' ]];then
10926 B_SUDO_TESTED='true'
10927 SUDO_PATH=$( type -p sudo )
10930 if [[ -n $FILE_PATH && -n $1 ]];then
10931 # only use sudo if not root, -n option requires sudo -V 1.7 or greater. sudo will just error out
10932 # which is the safest course here for now, otherwise that interactive sudo password thing is too annoying
10933 # important: -n makes it non interactive, no prompt for password
10934 if [[ $B_ROOT != 'true' && -n $SUDO_PATH ]];then
10935 sudo_command='sudo -n '
10937 # this will fail if regular user and no sudo present, but that's fine, it will just return null
10938 # note the hack that simply slices out the first line if > 1 items found in string
10939 # also, if grub/lilo is on partition boot sector, no file system data is available
10940 # BSD fix: -Eio -Em 1
10941 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 '.*' )
10942 if [[ -n $partition_filesystem ]];then
10943 echo $partition_filesystem
10949 ## return uptime string
10953 local uptime_value=''
10954 ## note: removing gsub(/ /,"",a); to get get space back in there, goes right before print a
10955 if type -p uptime &>/dev/null;then
10956 uptime_value="$( uptime | gawk '{
10957 a = gensub(/^.*up *([^,]*).*$/,"\\1","g",$0)
10961 echo "$uptime_value"
10962 log_function_data "uptime_value: $uptime_value"
10970 local location_site='http://geoip.ubuntu.com/lookup'
10971 local weather_feed='http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query='
10972 local weather_spider='http://wunderground.com/'
10973 local data_grab_error='' downloader_error=0
10974 local b_test_loc=false b_test_weather=false b_debug=false
10975 local test_dir="$HOME/bin/scripts/inxi/data/weather/"
10976 local test_location='location2.xml' test_weather='weather-feed.xml'
10977 local location_data='' location='' weather_data='' location_array_value='' a_location=''
10978 local weather_array_value='' site_elevation='' a_temp=''
10980 # first we get the location data, once that is parsed and handled, we move to getting the
10981 # actual weather data, assuming no errors
10982 if [[ -n $ALTERNATE_WEATHER_LOCATION ]];then
10983 # note, this api does not support spaces in names, replace spaces with + sign.
10984 location=$ALTERNATE_WEATHER_LOCATION
10985 # echo $ALTERNATE_WEATHER_LOCATION;exit
10987 if [[ $b_test_loc != 'true' ]];then
10988 case $DOWNLOADER in
10990 location_data="$( curl -y $DL_TIMEOUT -s $location_site )" || downloader_error=$?
10993 location_data="$( fetch -T $DL_TIMEOUT -q -o - $location_site )" || downloader_error=$?
10996 location_data="$( ftp -o - $location_site 2>/dev/null )" || downloader_error=$?
10999 location_data="$( wget -t 1 -T $DL_TIMEOUT -q -O - $location_site )" || downloader_error=$?
11002 downloader_error=100
11005 log_function_data "$location_data"
11007 if [[ $downloader_error -ne 0 ]];then
11008 if [[ $downloader_error -eq 100 ]];then
11009 data_grab_error="Error: No downloader tool available. Install wget, curl, or fetch."
11011 data_grab_error="Error: location server up but download error - $DOWNLOADER: $downloader_error"
11016 if [[ -f $test_dir$test_location ]];then
11017 location_data="$( cat $test_dir$test_location )"
11019 data_grab_error="Error: location xml local file not found."
11022 if [[ -n $data_grab_error ]];then
11024 elif [[ -z $( grep -i '<Response' <<< $location_data ) ]];then
11025 data_grab_error="Error: location downloaded but data contains no xml."
11027 # clean up xml and make easy to process with newlines, note, bsd sed has no support for inserting
11028 # \n dircctly so we have to use this hack
11029 # location_data="$( sed $SED_RX 's|><|>\n<|g' <<< $location_data )"
11030 location_data="$( sed $SED_RX 's|><|>\
11031 <|g' <<< $location_data )"
11032 # echo -e "ld:\n$location_data"
11033 location_array_value=$( gawk '
11034 function clean(data) {
11036 # some lines might be empty, so ignore those
11037 if (data !~ /^<[^>]+>$/ ) {
11038 returnData=gensub(/(.*>)([^<]*)(<.*)/, "\\2", 1, data)
11058 if ( $0 ~ /CountryCode3/ ){
11059 countryCode3=clean($0)
11062 countryCode=clean($0)
11066 countryName = clean($0)
11069 regionCode = clean($0)
11072 regionName = clean($0)
11078 postalCode = clean($0)
11081 latitude = clean($0)
11084 longitude = clean($0)
11087 timeZone = clean($0)
11090 locationString = city ";" regionCode ";" regionName ";" countryName ";" countryCode ";" countryCode3
11091 locationString = locationString ";" latitude "," longitude ";" postalCode ";" timeZone
11092 print locationString
11093 }' <<< "$location_data" )
11095 A_WEATHER_DATA[0]=$location_array_value
11097 a_location=( ${A_WEATHER_DATA[0]} )
11098 IFS="$ORIGINAL_IFS"
11100 # assign location, cascade from most accurate
11101 # latitude,longitude first
11102 if [[ -n ${a_location[6]} ]];then
11103 location="${a_location[6]}"
11105 elif [[ -n ${a_location[0]} && -n ${a_location[1]} ]];then
11106 location="${a_location[0]},${a_location[1]}"
11107 # postal code last, that can be a very large region
11108 elif [[ -n ${a_location[7]} ]];then
11109 location=${a_location[7]}
11112 if [[ $b_debug == 'true' ]];then
11113 echo -e "location array:\n${A_WEATHER_DATA[0]}"
11114 echo "location: $location"
11116 log_function_data "location: $location"
11118 if [[ -z $location && -z $data_grab_error ]];then
11119 data_grab_error="Error: location data downloaded but no location detected."
11122 # now either dump process or go on to get weather data
11123 if [[ -z $data_grab_error ]];then
11124 if [[ $b_test_weather != 'true' ]];then
11125 case $DOWNLOADER in
11127 weather_data="$( curl -y $DL_TIMEOUT -s $weather_feed"$location" )" || downloader_error=$?
11130 weather_data="$( fetch -T $DL_TIMEOUT -q -o - $weather_feed"$location" )" || downloader_error=$?
11133 weather_data="$( ftp -o - $weather_feed"$location" 2>/dev/null )" || downloader_error=$?
11136 weather_data="$( wget -t 1 -T $DL_TIMEOUT -q -O - $weather_feed"$location" )" || downloader_error=$?
11139 downloader_error=100
11142 if [[ $downloader_error -ne 0 ]];then
11143 if [[ $downloader_error -eq 100 ]];then
11144 data_grab_error="Error: No downloader tool available. Install wget, curl, or fetch."
11146 data_grab_error="Error: weather server up but download error - $DOWNLOADER: $downloader_error"
11149 log_function_data "$weather_data"
11151 if [[ -f $test_dir$test_weather ]];then
11152 weather_data="$( cat $test_dir$test_weather)"
11154 data_grab_error="Error: weather feed xml local file not found."
11157 if [[ -z $data_grab_error && -z $( grep -i '<current_observation' <<< $weather_data ) ]];then
11158 data_grab_error="Error: weather data downloaded but shows no xml start."
11160 if [[ -z $data_grab_error ]];then
11162 weather_data=$( sed 's/^[[:space:]]*//' <<< "$weather_data" )
11163 site_elevation=$( grep -im 1 '<elevation>' <<< "$weather_data" | sed $SED_RX -e 's/<[^>]*>//g' \
11164 -e 's/\.[0-9]*//' )
11165 # we need to grab the location data from the feed for remote checks
11166 if [[ -n $ALTERNATE_WEATHER_LOCATION && -n $weather_data ]];then
11167 location_data=$( sed -e '/<current_observation>/,/<display_location>/d' -e '/<\/display_location>/,/<\/current_observation>/d' <<< "$weather_data" )
11168 # echo -e "ld1:\n$location_data"
11169 A_WEATHER_DATA[0]=$( gawk '
11170 function clean(data) {
11172 # some lines might be empty, so ignore those
11173 if (data !~ /^<[^>]+>$/ ) {
11174 returnData=gensub(/(.*>)([^<]*)(<.*)/, "\\2", 1, data)
11175 gsub(/^[[:space:]]+|[[:space:]]+$|^NA$|^N\/A$/, "", returnData)
11195 print city ";" state ";;;;" country
11196 }' <<< "$location_data" )
11197 # echo -e "location:\n${A_WEATHER_DATA[0]}"
11200 # clean off everything before/after observation_location
11201 weather_data=$( sed -e '/<current_observation>/,/<observation_location>/d' \
11202 -e '/<icons>/,/<\/current_observation>/d' <<< "$weather_data" -e 's/^[[:space:]]*$//g' -e '/^$/d' )
11204 # echo "$weather_data";exit
11205 weather_array_value=$( gawk -v siteElevation="$site_elevation" '
11206 function clean(data) {
11208 # some lines might be empty, so ignore those
11209 if (data !~ /^<[^>]+>$/ ) {
11210 returnData=gensub(/(.*>)([^<]*)(<.*)/, "\\2", 1, data)
11211 gsub(/^[[:space:]]+|[[:space:]]+$|^NA$|^N\/A$/, "", returnData)
11229 /observation_time>/ {
11230 observationTime=clean($0)
11231 sub(/Last Updated on /, "", observationTime )
11234 localTime=clean($0)
11239 /temperature_string/ {
11240 tempString=clean($0)
11242 /relative_humidity/ {
11246 windString=clean($0)
11248 /pressure_string/ {
11249 pressureString=clean($0)
11251 /heat_index_string/ {
11252 heatIndexString=clean($0)
11254 /windchill_string/ {
11255 windChillString=clean($0)
11258 weatherString = observationTime ";" localTime ";" weather ";" tempString ";" humidity
11259 weatherString = weatherString ";" windString ";" pressureString ";" dewpointString ";" heatIndexString
11260 weatherString = weatherString ";" windChillString ";" siteElevation
11261 print weatherString
11262 }' <<< "$weather_data" )
11264 if [[ -z $weather_array_value ]];then
11265 data_grab_error="Error: weather info downloaded but no data detected."
11267 A_WEATHER_DATA[1]=$weather_array_value
11270 # now either dump process or go on to get weather data
11271 if [[ -n $data_grab_error ]];then
11272 A_WEATHER_DATA=$data_grab_error
11273 log_function_data "data grab error: $data_grab_error"
11276 if [[ $b_debug == 'true' ]];then
11277 echo "site_elevation: $site_elevation"
11278 echo "${A_WEATHER_DATA[1]}"
11280 a_temp=${A_WEATHER_DATA[@]}
11281 log_function_data "A_WEATHER_DATA: $a_temp"
11285 # ALTERNATE_WEATHER_LOCATION='portland,or'
11286 # get_weather_data;exit
11288 #### -------------------------------------------------------------------
11289 #### special data handling for specific options and conditions
11290 #### -------------------------------------------------------------------
11292 # args: $1 - string to strip color code characters out of
11293 # returns count of string length minus colors
11294 # note; this cleanup may not be working on bsd sed
11295 calculate_line_length()
11298 # ansi:
\e[1;34m irc: \x0312
11299 # note: using special trick for bsd sed, tr - NOTE irc sed must use " double quote
11300 string=$( sed -e 's/'$ESC'\[[0-9]\{1,2\}\(;[0-9]\{1,2\}\)\{0,2\}m//g' -e "s/\\\x0[0-9]\{1,3\}//g" <<< $string )
11305 ## multiply the core count by the data to be calculated, bmips, cache
11306 # args: $1 - string to handle; $2 - cpu count
11307 calculate_multicore_data()
11310 local string_number=$1 string_data=''
11312 if [[ -n $( grep -Ei '( mb| kb)' <<< $1 ) ]];then
11313 string_data=" $( gawk '{print $2}' <<< $1 )" # add a space for output
11314 string_number=$( gawk '{print $1}' <<< $1 )
11316 # handle weird error cases where it's not a number
11317 if [[ -n $( grep -E '^[0-9\.,]+$' <<< $string_number ) ]];then
11318 string_number=$( echo $string_number $2 | gawk '{
11322 elif [[ $string_number == '' ]];then
11323 string_number='N/A'
11325 # I believe that the above returns 'unknown' by default so no need for extra text
11326 string_number="$string_number "
11328 echo "$string_number$string_data"
11329 log_function_data "string_numberstring_data: $string_number$string_data"
11333 # prints out shortened list of flags, the main ones of interest
11334 # args: $1 - string of cpu flags to process
11335 process_cpu_flags()
11339 local cpu_flags_working=$1
11340 local bits=$( uname -m | grep 64 )
11342 # no need to show pae for 64 bit cpus, it's pointless
11343 if [[ -n $bits ]];then
11344 cpu_flags_working=$( sed 's/[[:space:]]*pae//' <<< "$cpu_flags_working" )
11346 # must have a space after last item in list for RS=" "
11347 cpu_flags_working="$cpu_flags_working "
11349 # nx = AMD stack protection extensions
11350 # lm = Intel 64bit extensions
11351 # sse, sse2, pni = sse1,2,3,4,5 gfx extensions
11352 # svm = AMD pacifica virtualization extensions
11353 # vmx = Intel IVT (vanderpool) virtualization extensions
11354 cpu_flags=$( gawk '
11358 i = 1 # start at one because of for increment issue
11362 /^(lm|nx|pae|pni|svm|vmx|(sss|ss)e([2-9])?([a-z])?(_[0-9])?)$/ {
11363 if ( $0 == "pni" ){
11364 a_flags[i] = "sse3"
11372 count = asort( a_flags )
11373 # note: why does gawk increment before the loop and not after? weird.
11374 for ( i=0; i <= count; i++ ){
11375 if ( flag_string == "" ) {
11376 flag_string = a_flags[i]
11379 flag_string = flag_string " " a_flags[i]
11383 }' <<< "$cpu_flags_working" )
11385 #grep -oE '\<(nx|lm|sse[0-9]?|pni|svm|vmx)\>' | tr '\n' ' '))
11386 if [[ -z $cpu_flags ]];then
11390 log_function_data "cpu_flags: $cpu_flags"
11394 #### -------------------------------------------------------------------
11395 #### print and processing of output data
11396 #### -------------------------------------------------------------------
11398 #### MASTER PRINT FUNCTION - triggers all line item print functions
11399 ## main function to print out, master for all sub print functions.
11403 # note that print_it_out passes local variable values on to its children,
11404 # and in some cases, their children, with Lspci_v_Data
11405 local Lspci_v_Data='' Lspci_n_Data='' # only for verbose
11406 local Sysctl_a_Data='' Dmesg_Boot_Data=''
11408 if [[ -n $BSD_TYPE ]];then
11409 Sysctl_a_Data="$( get_sysctl_data 'a' )"
11410 Dmesg_Boot_Data="$( get_dmesg_boot_data )"
11413 if [[ $B_SHOW_SHORT_OUTPUT == 'true' ]];then
11416 Lspci_v_Data="$( get_lspci_data 'v' )"
11417 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
11418 Lspci_n_Data="$( get_lspci_data 'n' )"
11420 if [[ $B_SHOW_SYSTEM == 'true' ]];then
11423 if [[ $B_SHOW_MACHINE == 'true' ]];then
11426 if [[ $B_SHOW_BATTERY == 'true' ]];then
11429 if [[ $B_SHOW_BASIC_CPU == 'true' || $B_SHOW_CPU == 'true' ]];then
11432 if [[ $B_SHOW_MEMORY == 'true' ]];then
11435 if [[ $B_SHOW_GRAPHICS == 'true' ]];then
11436 print_graphics_data
11438 if [[ $B_SHOW_AUDIO == 'true' ]];then
11441 if [[ $B_SHOW_NETWORK == 'true' ]];then
11442 print_networking_data
11444 if [[ $B_SHOW_DISK_TOTAL == 'true' || $B_SHOW_BASIC_DISK == 'true' || $B_SHOW_DISK == 'true' ]];then
11445 print_hard_disk_data
11447 if [[ $B_SHOW_PARTITIONS == 'true' ]];then
11448 print_partition_data
11450 if [[ $B_SHOW_RAID == 'true' || $B_SHOW_BASIC_RAID == 'true' ]];then
11453 if [[ $B_SHOW_UNMOUNTED_PARTITIONS == 'true' ]];then
11454 print_unmounted_partition_data
11456 if [[ $B_SHOW_SENSORS == 'true' ]];then
11459 if [[ $B_SHOW_REPOS == 'true' ]];then
11462 if [[ $B_SHOW_PS_CPU_DATA == 'true' || $B_SHOW_PS_MEM_DATA == 'true' ]];then
11465 if [[ $B_SHOW_WEATHER == 'true' ]];then
11468 if [[ $B_SHOW_INFO == 'true' ]];then
11472 ## last steps, clear any lingering colors
11473 if [[ $B_IRC == 'false' && $SCHEME -gt 0 ]];then
11480 #### SHORT OUTPUT PRINT FUNCTION, ie, verbosity 0
11481 # all the get data stuff is loaded here to keep execution time down for single line print commands
11482 # these will also be loaded in each relevant print function for long output
11486 local current_kernel=$( get_kernel_version )
11487 local processes=$(( $( wc -l <<< "$Ps_aux_Data" ) - 1 ))
11488 local short_data='' i='' b_background_black='false'
11489 local memory=$( get_memory_data )
11490 local up_time="$( get_uptime )"
11491 if [[ -z $up_time ]];then
11492 up_time='N/A - missing uptime?'
11495 # set A_CPU_CORE_DATA
11497 local cpc_plural='' cpu_count_print='' model_plural='' current_max_clock=''
11498 local cpu_physical_count=${A_CPU_CORE_DATA[0]}
11499 local cpu_core_count=${A_CPU_CORE_DATA[3]}
11500 local cpu_core_alpha=${A_CPU_CORE_DATA[1]}
11501 local cpu_type=${A_CPU_CORE_DATA[2]}
11502 local kernel_os='' speed_starter='speed'
11503 local cpu_data_string=''
11505 if [[ -z $BSD_TYPE || -n $cpu_type ]];then
11506 cpu_type=" ($cpu_type)"
11509 if [[ $BSD_TYPE == 'bsd' ]];then
11510 kernel_os="${C1}OS${C2}$SEP1$( uname -rsp )"
11512 kernel_os="${C1}Kernel${C2}$SEP1$current_kernel"
11515 if [[ $cpu_physical_count -gt 1 ]];then
11518 cpu_count_print="$cpu_physical_count "
11519 # for multicpu systems, divide total cores by cpu count to get per cpu cores
11520 $cpu_core_count=$(($cpu_core_count/$cpu_physical_count))
11522 if [[ -z $BSD_TYPE ]];then
11523 cpu_data_string="$cpu_count_print$cpu_core_alpha core"
11525 cpu_data_string="$cpu_count_print$cpu_core_count core"
11527 # local cpu_core_count=${A_CPU_CORE_DATA[0]}
11531 ## note: if hdd_model is declared prior to use, whatever string you want inserted will
11532 ## be inserted first. In this case, it's desirable to print out (x) before each disk found.
11533 local a_hdd_data_count=$(( ${#A_HDD_DATA[@]} - 1 ))
11535 local a_hdd_basic_working=( ${A_HDD_DATA[$a_hdd_data_count]} )
11536 IFS="$ORIGINAL_IFS"
11537 local hdd_capacity=${a_hdd_basic_working[0]}
11538 local hdd_used=${a_hdd_basic_working[1]}
11544 local a_cpu_working=(${A_CPU_DATA[0]})
11545 # this gets that weird min/max final array item, which almost never contains any data of use
11546 local current_max_clock_nu=$(( ${#A_CPU_DATA[@]} - 1 ))
11547 local a_cpu_speeds=(${A_CPU_DATA[$current_max_clock_nu]})
11548 IFS="$ORIGINAL_IFS"
11549 local cpu_model="${a_cpu_working[0]}"
11550 ## assemble data for output
11551 local cpu_clock="${a_cpu_working[1]}" # old CPU3
11553 # if [[ -z ${a_cpu_working[1]} || ${a_cpu_working[1]} < 50 ]];then
11554 # a_cpu_working[1]=$(get_cpu_speed_hack)
11557 # this handles the case of for example ARM cpus, which will not have data for
11558 # min/max, since they don't have speed. Since that sets a flag, not found, just
11559 # look for that and use the speed from the first array array, same where we got
11561 # index: 0 speed ; 1 min ; 2 max
11562 # this handles bsd types which always should show N/A unless we get a way to get min / max data
11563 if [[ "${a_cpu_speeds[0]}" == 'N/A' && ${a_cpu_working[1]} != '' ]];then
11564 current_max_clock="${a_cpu_working[1]} MHz"
11566 if [[ ${a_cpu_speeds[2]} != 0 ]];then
11567 if [[ ${a_cpu_speeds[0]} == ${a_cpu_speeds[2]} ]];then
11568 current_max_clock="${a_cpu_speeds[0]} MHz (max)"
11570 current_max_clock="${a_cpu_speeds[0]}/${a_cpu_speeds[2]} MHz"
11571 speed_starter='speed/max'
11575 local patch_version_number=$( get_patch_version_string )
11577 #set_color_scheme 12
11578 if [[ $B_IRC == 'true' ]];then
11579 for i in $C1 $C2 $CN
11582 "$GREEN"|"$WHITE"|"$YELLOW"|"$CYAN")
11583 b_background_black='true'
11587 if [[ $b_background_black == 'true' ]];then
11590 ## these need to be in quotes, don't know why
11591 if [[ ${!i} == $NORMAL ]];then
11592 declare $i="${!i}15,1"
11594 declare $i="${!i},1"
11597 #C1="${C1},1"; C2="${C2},1"; CN="${CN},1"
11600 short_data="${C1}CPU$cpc_plural${C2}$SEP1$cpu_data_string $cpu_model$model_plural$cpu_type ${C1}$speed_starter${C2}$SEP1$current_max_clock$SEP2$kernel_os$SEP2${C1}Up${C2}$SEP1$up_time$SEP2${C1}Mem${C2}$SEP1$memory$SEP2${C1}HDD${C2}$SEP1$hdd_capacity($hdd_used)$SEP2${C1}Procs${C2}$SEP1$processes$SEP2"
11602 if [[ $SHOW_IRC -gt 0 ]];then
11603 short_data="$short_data${C1}Client${C2}$SEP1$IRC_CLIENT$IRC_CLIENT_VERSION$SEP2"
11605 short_data="$short_data${C1}$SCRIPT_NAME${C2}$SEP1$SCRIPT_VERSION_NUMBER$patch_version_number$SEP2${CN}"
11606 if [[ $SCHEME -gt 0 ]];then
11607 short_data="$short_data $NORMAL"
11609 print_screen_output "$short_data"
11613 #### LINE ITEM PRINT FUNCTIONS
11615 # print sound card data
11619 local i='' card_id='' audio_data='' a_audio_data='' port_data='' pci_bus_id='' card_string=''
11620 local a_audio_working='' audio_driver='' alsa_data='' port_plural='' module_version='' chip_id=''
11621 local bus_usb_text='' bus_usb_id='' line_starter='Audio:' alsa='' alsa_version='' print_data=''
11623 # set A_AUDIO_DATA and get alsa data
11624 if [[ $BSD_TYPE == 'bsd' ]];then
11625 if [[ $B_PCICONF == 'true' ]];then
11626 if [[ $B_PCICONF_SET == 'false' ]];then
11629 get_pciconf_card_data 'audio'
11630 elif [[ $B_LSPCI == 'true' ]];then
11637 get_audio_alsa_data
11638 # alsa driver data now prints out no matter what
11639 if [[ -n $A_ALSA_DATA ]];then
11641 if [[ -n ${A_ALSA_DATA[0]} ]];then
11642 alsa=${A_ALSA_DATA[0]}
11646 if [[ -n ${A_ALSA_DATA[1]} ]];then
11647 alsa_version=${A_ALSA_DATA[1]}
11651 alsa_data="${C1}Sound$SEP3${C2} $alsa ${C1}v$SEP3${C2} $alsa_version"
11652 IFS="$ORIGINAL_IFS"
11654 # note, error handling is done in the get function, so this will never be null, but
11655 # leaving the test just in case it's changed.
11656 if [[ -n ${A_AUDIO_DATA[@]} ]];then
11657 for (( i=0; i< ${#A_AUDIO_DATA[@]}; i++ ))
11660 a_audio_working=( ${A_AUDIO_DATA[i]} )
11661 IFS="$ORIGINAL_IFS"
11674 if [[ ${#A_AUDIO_DATA[@]} -gt 1 ]];then
11675 card_id="-$(( $i + 1 ))"
11677 if [[ $BSD_TYPE != 'bsd' ]];then
11678 if [[ -n ${a_audio_working[3]} && $B_EXTRA_DATA == 'true' ]];then
11679 module_version=$( print_module_version "${a_audio_working[3]}" 'audio' )
11680 elif [[ -n ${a_audio_working[1]} && $B_EXTRA_DATA == 'true' ]];then
11681 module_version=$( print_module_version "${a_audio_working[1]}" 'audio' )
11684 # we're testing for the presence of the 2nd array item here, which is the driver name
11685 if [[ -n ${a_audio_working[1]} ]];then
11686 # note: linux drivers can have numbers, like tg3
11687 if [[ $BSD_TYPE == 'bsd' ]];then
11688 driver=$( sed 's/[0-9]$//' <<< ${a_audio_working[1]} )
11690 driver=${a_audio_working[1]}
11692 audio_driver="${C1}driver$SEP3${C2} $driver "
11694 if [[ -n ${a_audio_working[2]} && $B_EXTRA_DATA == 'true' ]];then
11695 if [[ $( wc -w <<< ${a_audio_working[2]} ) -gt 1 ]];then
11698 port_data="${C1}port$port_plural$SEP3${C2} ${a_audio_working[2]} "
11700 if [[ -n ${a_audio_working[4]} && $B_EXTRA_DATA == 'true' ]];then
11701 if [[ ${a_audio_working[1]} != 'USB Audio' ]];then
11702 bus_usb_text='bus-ID'
11703 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
11704 if [[ $BSD_TYPE != 'bsd' ]];then
11705 chip_id=$( get_lspci_chip_id "${a_audio_working[4]}" )
11707 chip_id=${a_audio_working[6]}
11711 bus_usb_text='usb-ID'
11712 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
11713 chip_id=${a_audio_working[5]}
11716 bus_usb_id=${a_audio_working[4]}
11717 pci_bus_id="${C1}$bus_usb_text$SEP3${C2} $bus_usb_id "
11718 if [[ -n $chip_id ]];then
11719 chip_id="${C1}chip-ID$SEP3${C2} $chip_id "
11722 if [[ -n ${a_audio_working[0]} ]];then
11723 card_string="${C1}Card$card_id$EP3${C2} ${a_audio_working[0]} "
11724 audio_data="$audio_driver$port_data$pci_bus_id$chip_id"
11726 # only print alsa on last line if short enough, otherwise print on its own line
11727 if [[ $i -eq 0 ]];then
11728 if [[ -n $alsa_data && $( calculate_line_length "$card_string$audio_data$alsa_data" ) -lt $COLS_INNER ]];then
11729 audio_data="$audio_data$alsa_data"
11733 if [[ -n $audio_data ]];then
11734 if [[ $( calculate_line_length "$card_string$audio_data" ) -lt $COLS_INNER ]];then
11735 print_data=$( create_print_line "$line_starter" "$card_string$audio_data" )
11736 print_screen_output "$print_data"
11739 # keep the driver on the same line no matter what, looks weird alone on its own line
11740 if [[ $( calculate_line_length "$card_string$audio_data" ) -gt $COLS_INNER ]];then
11741 print_data=$( create_print_line "$line_starter" "$card_string" )
11742 print_screen_output "$print_data"
11744 print_data=$( create_print_line "$line_starter" "$audio_data" )
11745 print_screen_output "$print_data"
11747 print_data=$( create_print_line "$line_starter" "$card_string$audio_data" )
11748 print_screen_output "$print_data"
11755 if [[ -n $alsa_data ]];then
11756 if [[ $( calculate_line_length "${alsa_data/ALSA/Advanced Linux Sound Architecture}" ) -lt $COLS_INNER ]];then
11757 # alsa_data=$( sed 's/ALSA/Advanced Linux Sound Architecture/' <<< $alsa_data )
11758 alsa_data=${alsa_data/ALSA/Advanced Linux Sound Architecture}
11760 alsa_data=$( create_print_line "$line_starter" "$alsa_data" )
11761 print_screen_output "$alsa_data"
11766 print_battery_data()
11769 local line_starter='Battery' print_data=''
11771 if [[ -n ${A_BATTERY_DATA[@]} ]];then
11772 local battery_data='' battery_string=''
11773 local present='' chemistry='' cycles='' voltage_min_design='' voltage_now=''
11774 local power_now='' charge_full_design='' charge_full='' charge_now='' capacity=''
11775 local capacity_level='' model='' company='' serial='' of_orig='' model='' condition=''
11778 # echo ${A_BATTERY_DATA[@]}
11779 for (( i=0; i< ${#A_BATTERY_DATA[@]}; i++ ))
11794 voltage_min_design=''
11797 charge_full_design=''
11806 location='' # dmidecode only
11808 a_battery_working=( ${A_BATTERY_DATA[i]} )
11809 IFS="$ORIGINAL_IFS"
11810 bat_id="$(( $i + 1 ))"
11812 if [[ -n ${a_battery_working[10]} ]];then
11813 charge="${a_battery_working[10]} Wh "
11815 if [[ -n ${a_battery_working[11]} ]];then
11816 charge="$charge${a_battery_working[11]} "
11818 if [[ $charge == '' ]];then
11821 charge="${C1}charge$SEP3${C2} $charge"
11822 if [[ -n ${a_battery_working[9]} ]];then
11823 condition="${a_battery_working[9]}"
11827 if [[ -n ${a_battery_working[8]} ]];then
11828 condition="$condition/${a_battery_working[8]} Wh "
11830 condition="$condition/NA Wh "
11832 if [[ -n ${a_battery_working[13]} ]];then
11833 condition="$condition(${a_battery_working[13]}) "
11835 if [[ $condition == '' ]];then
11838 condition="${C1}condition$SEP3${C2} $condition"
11839 if [[ $B_EXTRA_DATA == 'true' ]];then
11840 if [[ -n ${a_battery_working[15]} ]];then
11841 model="${a_battery_working[15]} "
11843 if [[ -n ${a_battery_working[14]} ]];then
11844 model="$model${a_battery_working[14]} "
11846 if [[ $model == '' ]];then
11849 model="${C1}model$SEP3${C2} $model"
11851 if [[ -n ${a_battery_working[1]} ]];then
11852 status="${a_battery_working[1]} "
11856 status="${C1}status$SEP3${C2} $status"
11858 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
11859 if [[ -n ${a_battery_working[16]} ]];then
11860 serial="${a_battery_working[16]} "
11864 serial="${C1}serial$SEP3${C2} $serial"
11865 if [[ -n ${a_battery_working[6]} ]];then
11866 voltage="${a_battery_working[6]}"
11868 if [[ -n ${a_battery_working[5]} ]];then
11869 if [[ $voltage == '' ]];then
11872 voltage="$voltage/${a_battery_working[5]} "
11874 if [[ $voltage == '' ]];then
11877 voltage="${C1}volts$SEP3${C2} $voltage"
11879 if [[ $B_EXTRA_EXTRA_EXTRA_DATA == 'true' ]];then
11880 if [[ -n ${a_battery_working[3]} ]];then
11881 chemistry="${a_battery_working[3]} "
11883 if [[ -n ${a_battery_working[4]} ]];then
11884 cycles="${C1}cycles$SEP3${C2} ${a_battery_working[4]} "
11886 # location is dmidecode only
11887 if [[ -n ${a_battery_working[17]} ]];then
11888 location="${C1}loc$SEP3${C2} ${a_battery_working[17]} "
11891 if [[ -n ${a_battery_working[15]} ]];then
11892 battery_string="${C1}${a_battery_working[0]}$SEP3${C2} $charge$condition"
11893 battery_data="$model$chemistry$serial$status$cycles$location"
11896 if [[ ${A_BATTERY_DATA[0]} == 'dmidecode-error-'* ]];then
11897 error_string=$( print_dmidecode_error 'bat' "${A_BATTERY_DATA[0]}" )
11898 battery_string=${C2}$error_string
11903 if [[ -n $battery_string ]];then
11904 if [[ $( calculate_line_length "$battery_string$voltage$battery_data" ) -lt $COLS_INNER ]];then
11906 print_data=$( create_print_line "$line_starter" "$battery_string$voltage$battery_data" )
11907 print_screen_output "$print_data"
11910 # keep the driver on the same line no matter what, looks weird alone on its own line
11911 if [[ $( calculate_line_length "$battery_string$voltage$battery_data" ) -gt $COLS_INNER ]];then
11912 if [[ $( calculate_line_length "$battery_string$voltage" ) -gt $COLS_INNER ]];then
11913 print_data=$( create_print_line "$line_starter" "$battery_string" )
11914 print_screen_output "$print_data"
11917 print_data=$( create_print_line "$line_starter" "$voltage" )
11918 print_screen_output "$print_data"
11921 print_data=$( create_print_line "$line_starter" "$battery_string$voltage" )
11922 print_screen_output "$print_data"
11928 if [[ $battery_data != '' ]];then
11929 print_data=$( create_print_line "$line_starter" "$battery_data" )
11930 print_screen_output "$print_data"
11934 print_data=$( create_print_line "$line_starter" "$battery_string$voltage$battery_data" )
11935 print_screen_output "$print_data"
11941 elif [[ $B_SHOW_BATTERY_FORCED == 'true' ]];then
11942 print_data=$( create_print_line "$line_starter" "No battery data found in /sys or dmidecode. Is one present?" )
11943 print_screen_output "$print_data"
11951 local cpu_data='' i='' cpu_clock_speed='' cpu_multi_clock_data='' a_cpu_speeds=''
11952 local bmip_data='' cpu_cache='' cpu_vendor='' cpu_flags='' flag_feature='flags'
11953 local a_cpu_working='' cpu_model='' cpu_clock='' cpu_null_error='' max_speed=''
11954 local cpc_plural='' cpu_count_print='' model_plural='' cpu_data_string=''
11955 local cpu_physical_count='' cpu_core_count='' cpu_core_alpha='' cpu_type=''
11956 local cpu_2_data='' working_cpu='' temp1='' per_cpu_cores='' current_max_clock_nu=''
11957 local line_starter="CPU:" multi_cpu_starter="${C1}clock speeds$SEP3${C2} "
11958 local speed_starter='speed'
11960 ##print_screen_output "A_CPU_DATA[0]=\"${A_CPU_DATA[0]}\""
11961 # Array A_CPU_DATA always has one extra element: max clockfreq found.
11962 # that's why its count is one more than you'd think from cores/cpus alone
11967 a_cpu_working=(${A_CPU_DATA[0]})
11968 current_max_clock_nu=$(( ${#A_CPU_DATA[@]} - 1 ))
11969 a_cpu_speeds=(${A_CPU_DATA[$current_max_clock_nu]})
11970 IFS="$ORIGINAL_IFS"
11972 # Strange (and also some expected) behavior encountered. If print_screen_output() uses $1
11973 # as the parameter to output to the screen, then passing "<text1> ${ARR[@]} <text2>"
11974 # will output only <text1> and first element of ARR. That "@" splits in elements and "*" _doesn't_,
11975 # is to be expected. However, that text2 is consecutively truncated is somewhat strange, so take note.
11976 # This has been confirmed by #bash on freenode.
11977 # The above mentioned only emerges when using the debugging markers below
11978 ## print_screen_output "a_cpu_working=\"***${a_cpu_working[@]} $hostName+++++++\"----------"
11979 # unless all these are null, process whatever you have
11980 if [[ -n ${a_cpu_working[0]} || -n ${a_cpu_working[1]} || -n ${a_cpu_working[2]} || -n ${a_cpu_working[3]} ]];then
11981 cpu_model="${a_cpu_working[0]}"
11982 ## assemble data for output
11983 cpu_clock="${a_cpu_working[1]}"
11984 cpu_vendor=${a_cpu_working[5]}
11985 # set A_CPU_CORE_DATA
11987 cpu_physical_count=${A_CPU_CORE_DATA[0]}
11988 cpu_core_count=${A_CPU_CORE_DATA[3]}
11989 cpu_core_alpha=${A_CPU_CORE_DATA[1]}
11990 cpu_type=${A_CPU_CORE_DATA[2]}
11992 if [[ $cpu_physical_count -gt 1 ]];then
11994 cpu_count_print="$cpu_physical_count "
11997 line_starter="CPU$cpc_plural:"
11998 if [[ -z $BSD_TYPE ]];then
11999 cpu_data_string="$cpu_count_print$cpu_core_alpha core"
12000 cpu_data="${C1}$cpu_data_string${C2} ${a_cpu_working[0]}$model_plural ($cpu_type)"
12002 if [[ $cpu_physical_count -gt 1 ]];then
12003 per_cpu_cores=$(($cpu_core_count/$cpu_physical_count))
12004 cpu_data_string="${C1}Cores$SEP3${C2} $cpu_core_count ($cpu_physical_count $per_cpu_cores core cpus) "
12006 cpu_data_string="${C1}Cores$SEP3${C2} $cpu_core_count "
12008 if [[ -n $cpu_type ]];then
12009 cpu_type=" ($cpu_type)"
12011 cpu_data="$cpu_data_string${C1}model$SEP3${C2} ${a_cpu_working[0]}$cpu_type"
12013 if [[ $B_SHOW_CPU == 'true' ]];then
12014 # update for multicore, bogomips x core count.
12015 if [[ $B_EXTRA_DATA == 'true' ]];then
12016 # if [[ $cpu_vendor != 'intel' ]];then
12017 # ARM may use the faked 1 cpucorecount to make this work
12018 # echo $cpu_core_count $cpu_physical_count
12019 if [[ -n ${a_cpu_working[4]} ]];then
12020 # new arm shows bad bogomip value, so don't use it
12021 if [[ ${a_cpu_working[4]%.*} -gt 50 ]];then
12022 bmip_data=$( calculate_multicore_data "${a_cpu_working[4]}" "$(( $cpu_core_count * $cpu_physical_count ))" )
12024 bmip_data=${bmip_data%.*}
12027 # bmip_data="${a_cpu_working[4]}"
12029 # bogomips are a linux thing, but my guess is over time bsds will use them somewhere anyway
12030 if [[ -n $BSD_TYPE && -z $bmip_data ]];then
12033 bmip_data="${C1}bmips$SEP3${C2} $bmip_data "
12036 ## note: this handles how intel reports L2, total instead of per core like AMD does
12037 # note that we need to multiply by number of actual cpus here to get true cache size
12038 if [[ -n ${a_cpu_working[2]} ]];then
12039 if [[ -z $BSD_TYPE ]];then
12040 if [[ $cpu_vendor != 'intel' ]];then
12041 cpu_cache=$( calculate_multicore_data "${a_cpu_working[2]}" "$(( $cpu_core_count * $cpu_physical_count ))" )
12043 cpu_cache=$( calculate_multicore_data "${a_cpu_working[2]}" "$cpu_physical_count" )
12046 cpu_cache=${a_cpu_working[2]}
12051 # only print shortened list
12052 if [[ $B_CPU_FLAGS_FULL != 'true' ]];then
12053 # gawk has already sorted this output, no flags returns -
12054 if [[ $B_EXTRA_DATA == 'true' ]];then
12055 cpu_flags=$( process_cpu_flags "${a_cpu_working[3]}" "${a_cpu_working[6]}" )
12056 cpu_flags="($cpu_flags)"
12057 if [[ ${a_cpu_working[6]} == 'true' ]];then
12058 flag_feature='features'
12060 cpu_flags="${C1}$flag_feature$SEP3${C2} $cpu_flags "
12063 # arm cpus do not have flags or cache
12064 if [[ ${a_cpu_working[6]} != 'true' ]];then
12065 cpu_data="$cpu_data${C2} ${C1}cache$SEP3${C2} $cpu_cache"
12066 cpu_2_data="$cpu_flags$bmip_data"
12068 cpu_data="$cpu_data${C2} (ARM)$bmip_data"
12071 # we don't this printing out extra line unless > 1 cpu core
12072 if [[ ${#A_CPU_DATA[@]} -gt 2 && $B_SHOW_CPU == 'true' ]];then
12073 cpu_clock_speed='' # null < verbosity level 5
12075 if [[ -z ${a_cpu_working[1]} ]];then
12076 if [[ -z ${cpu_data/*ARM*/} ]];then
12079 a_cpu_working[1]="N/A$temp1"
12081 a_cpu_working[1]="${a_cpu_working[1]%.*} MHz"
12083 # this handles bsd case unless we get a way to get max/min cpu speeds
12084 if [[ ${a_cpu_speeds[0]} != 'N/A' && ${a_cpu_speeds[2]} != 0 ]];then
12085 if [[ $B_EXTRA_EXTRA_DATA == 'true' && ${#A_CPU_DATA[@]} -eq 2 &&
12086 $B_SHOW_CPU == 'true' && ${a_cpu_speeds[1]} != 0 ]];then
12087 a_cpu_working[1]="${a_cpu_speeds[0]}/${a_cpu_speeds[1]}/${a_cpu_speeds[2]} MHz"
12088 speed_starter='speed/min/max'
12090 if [[ ${a_cpu_speeds[0]} == ${a_cpu_speeds[2]} ]];then
12091 a_cpu_working[1]="${a_cpu_speeds[0]} MHz (max)"
12093 a_cpu_working[1]="${a_cpu_speeds[0]}/${a_cpu_speeds[2]} MHz"
12094 speed_starter='speed/max'
12098 cpu_clock_speed="${C1}$speed_starter$SEP3${C2} ${a_cpu_working[1]}"
12100 cpu_2_data="$cpu_2_data$cpu_clock_speed"
12102 if [[ $BSD_TYPE == 'bsd' && $B_ROOT != 'true' ]];then
12103 cpu_null_error=' No permissions for sysctl use?'
12105 cpu_data="${C2}No CPU data available.$cpu_null_error"
12107 # echo $cpu_data $cpu_2_data
12108 # echo ln: $( calculate_line_length "$cpu_data $cpu_2_data" )
12109 # echo cpl: $( create_print_line "$line_starter" "$cpu_2_data" ):
12110 # echo icols: $COLS_INNER
12111 # echo tc: $TERM_COLUMNS
12112 # echo :${cpu_2_data}:
12113 if [[ -n $cpu_2_data && $( calculate_line_length "$cpu_data $cpu_2_data" ) -gt $COLS_INNER ]];then
12114 cpu_data=$( create_print_line "$line_starter" "$cpu_data" )
12116 print_screen_output "$cpu_data"
12117 cpu_data=$( create_print_line " " "$cpu_2_data" )
12118 print_screen_output "$cpu_data"
12120 cpu_data=$( create_print_line "$line_starter" "$cpu_data" )
12121 print_screen_output "$cpu_data $cpu_2_data"
12123 # we don't do this printing out extra line unless > 1 cpu core
12124 # note the numbering, the last array item is the min/max/not found for cpu speeds
12125 if [[ ${#A_CPU_DATA[@]} -gt 2 && $B_SHOW_CPU == 'true' ]];then
12126 if [[ ${a_cpu_speeds[2]} != 0 ]];then
12127 if [[ $B_EXTRA_EXTRA_DATA == 'true' && ${a_cpu_speeds[1]} != 0 ]];then
12128 max_speed="${C1}min/max$SEP3${C2} ${a_cpu_speeds[1]}/${a_cpu_speeds[2]} MHz "
12130 max_speed="${C1}max$SEP3${C2} ${a_cpu_speeds[2]} MHz "
12133 for (( i=0; i < ${#A_CPU_DATA[@]}-1; i++ ))
12136 a_cpu_working=(${A_CPU_DATA[i]})
12137 IFS="$ORIGINAL_IFS"
12138 # note: the first iteration will create a first space, for color code separation below
12139 # someone actually appeared with a 16 core system, so going to stop the cpu core throttle
12140 # if this had some other purpose which we can't remember we'll add it back in
12141 #if [[ $i -gt 10 ]];then
12144 # echo $(calculate_line_length "$multi_cpu_starter$SEP3 $cpu_multi_clock_data" )
12145 working_cpu="$max_speed${C1}$(( i + 1 ))$SEP3${C2} ${a_cpu_working[1]%.*} MHz "
12147 if [[ -n $cpu_multi_clock_data && \
12148 $( calculate_line_length "$multi_cpu_starter$cpu_multi_clock_data$working_cpu" ) -gt $COLS_INNER ]];then
12149 cpu_multi_clock_data=$( create_print_line " " "$multi_cpu_starter$cpu_multi_clock_data" )
12150 print_screen_output "$cpu_multi_clock_data"
12151 multi_cpu_starter=''
12152 cpu_multi_clock_data="$working_cpu"
12154 cpu_multi_clock_data="$cpu_multi_clock_data$working_cpu"
12158 # print the last line if it exists after loop
12159 if [[ -n $cpu_multi_clock_data ]];then
12160 cpu_multi_clock_data=$( create_print_line " " "$multi_cpu_starter$cpu_multi_clock_data" )
12161 print_screen_output "$cpu_multi_clock_data"
12163 if [[ $B_CPU_FLAGS_FULL == 'true' ]];then
12164 print_cpu_flags_full "${a_cpu_working[3]}" "${a_cpu_working[6]}"
12169 # takes list of all flags, split them and prints x per line
12170 # args: $1 - cpu flag string; $2 - arm true/false
12171 print_cpu_flags_full()
12174 # note: sort only sorts lines, not words in a string, so convert to lines
12175 local cpu_flags_full="$( echo $1 | tr " " "\n" | sort )"
12176 local a_cpu_flags='' line_starter='' temp_string=''
12177 local i=0 counter=0 starter_length=0 flag='' flag_data=''
12178 local line_length='' flag_feature='Flags' spacer='' flag_string=''
12180 if [[ $2 == 'true' ]];then
12181 flag_feature='Features'
12183 line_starter="CPU $flag_feature$SEP3"
12184 starter_length=$(( ${#line_starter} + 1 ))
12185 line_starter="${C1}$line_starter${C2} "
12186 line_length=$(( $COLS_INNER - $starter_length ))
12187 # build the flag line array
12188 for flag in $cpu_flags_full
12190 temp_string="$flag_string$spacer$flag"
12192 # handle inner line starter
12193 if [[ $counter -gt 0 ]];then
12194 line_length=$COLS_INNER
12196 if [[ $line_length -ge ${#temp_string} ]];then
12197 flag_string=$temp_string
12199 a_cpu_flags[$counter]=$flag_string
12205 if [[ -n $flag_string ]];then
12206 a_cpu_flags[$counter]=$flag_string
12208 a_cpu_flags[$counter]='No CPU flag data found.'
12210 # then print it out
12211 for (( i=0; i < ${#a_cpu_flags[@]};i++ ))
12213 if [[ $i -gt 0 ]];then
12216 flag_data=$( create_print_line " " "$line_starter${a_cpu_flags[$i]}" )
12217 print_screen_output "$flag_data"
12222 # args: $1 - type [sys/bat/default]; $2 - get_dmidecode_data error return
12223 print_dmidecode_error()
12226 local error_message='Unknown dmidecode error.'
12227 local sysDmiError='Using '
12229 if [[ $1 == 'sys' || $1 == 'bat' ]];then
12230 if [[ $B_FORCE_DMIDECODE == 'true' ]];then
12231 sysDmiError='Forcing '
12232 # dragonfly has /sys, but it's empty
12233 elif [[ $1 == 'sys' ]] && [[ $BSD_TYPE == '' || -d /sys/devices ]];then
12234 sysDmiError='No /sys/class/dmi; using '
12235 #elif [[ $1 == 'bat' ]] && [[ $BSD_TYPE == '' || -d /sys/devices ]];then
12236 # sysDmiError='No /sys/ battery; using '
12238 sysDmiError='Using '
12241 if [[ $2 == 'dmidecode-error-requires-root' ]];then
12242 error_message="${sysDmiError}dmidecode: you must be root to run dmidecode"
12243 elif [[ $2 == 'dmidecode-error-not-installed' ]];then
12244 error_message="${sysDmiError}dmidecode: dmidecode is not installed."
12245 elif [[ $2 == 'dmidecode-error-no-smbios-dmi-data' ]];then
12246 error_message="${sysDmiError}dmidecode: no smbios data available. Old system?"
12247 elif [[ $2 == 'dmidecode-error-no-battery-data' ]];then
12248 error_message="${sysDmiError}dmidecode: no battery data available."
12249 elif [[ $2 == 'dmidecode-error-unknown-error' ]];then
12250 error_message="${sysDmiError}dmidecode: unknown error occured"
12252 echo $error_message
12256 print_graphics_data()
12259 local graphics_data='' card_id='' i='' root_alert='' root_x_string='' a_graphics_working=''
12260 local b_is_mesa='false' display_full_string='' card_bus_id='' card_data=''
12261 local res_tty='Resolution' xorg_data='' display_vendor_string='' chip_id=''
12262 local spacer='' driver='' driver_string='' driver_plural='' direct_render_string=''
12263 local separator_loaded='' separator_unloaded='' separator_failed=''
12264 local loaded='' unloaded='' failed='' display_server_string=''
12265 local line_starter='Graphics:' part_1_data='' part_2_data=''
12266 local screen_resolution="$( get_graphics_res_data )"
12268 # set A_DISPLAY_SERVER_DATA
12269 get_graphics_display_server_data
12270 local display_vendor=${A_DISPLAY_SERVER_DATA[0]}
12271 local display_version=${A_DISPLAY_SERVER_DATA[1]}
12273 get_graphics_glx_data
12274 local glx_renderer="${A_GLX_DATA[0]}"
12275 local glx_version="${A_GLX_DATA[1]}"
12276 # this can contain a long No case debugging message, so it's being sliced off
12277 # note: using grep -ioE '(No|Yes)' <<< ${A_GLX_DATA[2]} did not work in Arch, no idea why
12278 local glx_direct_render=$( gawk '{print $1}' <<< "${A_GLX_DATA[2]}" )
12280 # set A_GRAPHICS_CARD_DATA
12281 if [[ $BSD_TYPE == 'bsd' ]];then
12282 if [[ $B_PCICONF == 'true' ]];then
12283 if [[ $B_PCICONF_SET == 'false' ]];then
12286 get_pciconf_card_data 'display'
12287 elif [[ $B_LSPCI == 'true' ]];then
12288 get_graphics_card_data
12291 get_graphics_card_data
12293 # set A_GRAPHIC_DRIVERS
12294 get_graphics_driver
12296 if [[ ${#A_GRAPHIC_DRIVERS[@]} -eq 0 ]];then
12299 for (( i=0; i < ${#A_GRAPHIC_DRIVERS[@]}; i++ ))
12302 a_graphics_working=( ${A_GRAPHIC_DRIVERS[i]} )
12303 IFS="$ORIGINAL_IFS"
12304 case ${a_graphics_working[1]} in
12306 loaded="$loaded$separator_loaded${a_graphics_working[0]}"
12307 separator_loaded=','
12310 unloaded="$unloaded$separator_unloaded${a_graphics_working[0]}"
12311 separator_unloaded=','
12314 failed="$failed$separator_failed${a_graphics_working[0]}"
12315 separator_failed=','
12320 if [[ -n $loaded ]];then
12321 driver="$driver $loaded"
12323 if [[ -n $unloaded ]];then
12324 driver="$driver (unloaded: $unloaded)"
12326 if [[ -n $failed ]];then
12327 driver="$driver ${RED}FAILED$SEP3${C2} $failed"
12329 # sometimes for some reason there is no driver found but the array is started
12330 if [[ -z $driver ]];then
12333 if [[ ${#A_GRAPHIC_DRIVERS[@]} -gt 1 ]];then
12336 # some basic error handling:
12337 if [[ -z $screen_resolution ]];then
12338 screen_resolution='N/A'
12340 # note: fix this, we may find a display server that has no version
12341 if [[ -z $display_vendor || -z $display_version ]];then
12342 display_vendor_string="N/A"
12344 display_vendor_string="$display_vendor $display_version"
12346 display_server_string="${C1}Display Server${SEP3}${C2} $display_vendor_string "
12347 driver_string="${C1}driver$driver_plural$SEP3${C2}$driver "
12349 if [[ $B_ROOT == 'true' ]];then
12350 root_x_string='for root '
12351 if [[ $B_IRC == 'false' || $B_CONSOLE_IRC == 'true' ]];then
12355 if [[ $B_RUNNING_IN_DISPLAY != 'true' ]];then
12356 root_x_string="${root_x_string}out of X"
12360 if [[ -n $root_x_string ]];then
12361 root_x_string="${C1}Advanced Data$SEP3${C2} N/A $root_x_string"
12363 # note, this comes out with a count of 1 sometimes for null data
12364 if [[ ${A_GRAPHICS_CARD_DATA[0]} != '' ]];then
12365 for (( i=0; i < ${#A_GRAPHICS_CARD_DATA[@]}; i++ ))
12368 a_graphics_working=( ${A_GRAPHICS_CARD_DATA[i]} )
12369 IFS="$ORIGINAL_IFS"
12371 card_data=${a_graphics_working[0]}
12372 if [[ $B_EXTRA_DATA == 'true' ]];then
12373 if [[ -n ${a_graphics_working[1]} ]];then
12374 card_bus_id="${a_graphics_working[1]}"
12375 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
12376 if [[ $BSD_TYPE != 'bsd' ]];then
12377 chip_id=$( get_lspci_chip_id "${a_graphics_working[1]}" )
12379 chip_id=${a_graphics_working[2]}
12386 if [[ -n $card_bus_id ]];then
12387 card_bus_id="${C1}bus-ID$SEP3${C2} $card_bus_id "
12389 if [[ -n $chip_id ]];then
12390 chip_id="${C1}chip-ID$SEP3${C2} $chip_id"
12392 if [[ ${#A_GRAPHICS_CARD_DATA[@]} -gt 1 ]];then
12393 card_id="-$(($i+1))"
12396 part_1_data="${C1}Card$card_id$SEP3${C2} $card_data "
12397 part_2_data="$card_bus_id$chip_id"
12399 if [[ ${#A_GRAPHICS_CARD_DATA[@]} -gt 1 ]];then
12400 if [[ $( calculate_line_length "$part_1_data$part_2_data" ) -gt $COLS_INNER ]];then
12401 graphics_data=$( create_print_line "$line_starter" "$part_1_data" )
12402 print_screen_output "$graphics_data"
12406 if [[ -n $( grep -vE '^[[:space:]]*$' <<< $part_1_data$part_2_data ) ]];then
12407 graphics_data=$( create_print_line "$line_starter" "$part_1_data$part_2_data" )
12408 print_screen_output "$graphics_data"
12416 # handle cases where card detection fails, like in PS3, where lspci gives no output, or headless boxes..
12418 part_1_data="${C1}Card$SEP3${C2} Failed to Detect Video Card! "
12420 # Print cards if not dual card system
12421 if [[ -n $part_1_data$part_2_data ]];then
12422 if [[ $( calculate_line_length "$part_1_data$part_2_data" ) -gt $COLS_INNER ]];then
12423 graphics_data=$( create_print_line "$line_starter" "$part_1_data" )
12424 print_screen_output "$graphics_data"
12428 if [[ -n $( grep -vE '^[[:space:]]*$' <<< $part_1_data$part_2_data ) ]];then
12429 graphics_data=$( create_print_line "$line_starter" "$part_1_data$part_2_data" )
12430 print_screen_output "$graphics_data"
12436 part_1_data="$display_server_string$driver_string"
12437 part_2_data="${C1}$res_tty$SEP3${C2} $screen_resolution $root_x_string"
12438 if [[ -n $( grep -vE '^[[:space:]]*$' <<< $part_1_data$part_2_data ) && \
12439 $( calculate_line_length "$part_1_data $part_2_data" ) -gt $COLS_INNER ]];then
12440 graphics_data=$( create_print_line "$line_starter" "$part_1_data" )
12441 print_screen_output "$graphics_data"
12444 graphics_data=$part_2_data
12446 if [[ -n $( grep -vE '^[[:space:]]*$' <<< $part_1_data$part_2_data ) ]];then
12447 graphics_data=$( create_print_line "$line_starter" "$part_1_data$part_2_data" )
12448 print_screen_output "$graphics_data"
12451 # if [[ -z $glx_renderer || -z $glx_version ]];then
12455 ## note: if glx render or display_version have no content, then mesa is true
12456 # if [[ $B_SHOW_DISPLAY_DATA == 'true' ]] && [[ $b_is_mesa != 'true' ]];then
12457 if [[ $B_SHOW_DISPLAY_DATA == 'true' && $B_ROOT != 'true' ]];then
12458 if [[ -z $glx_renderer ]];then
12461 if [[ -z $glx_version ]];then
12464 if [[ -z $glx_direct_render ]];then
12465 glx_direct_render='N/A'
12467 if [[ $B_HANDLE_CORRUPT_DATA == 'true' || $B_EXTRA_DATA == 'true' ]];then
12468 direct_render_string=" ${C1}Direct Rendering$SEP3${C2} $glx_direct_render"
12470 part_1_data="${C1}GLX Renderer$SEP3${C2} $glx_renderer "
12471 part_2_data="${C1}GLX Version$SEP3${C2} $glx_version$direct_render_string"
12472 # echo $line_starter
12473 if [[ $( calculate_line_length "$part_1_data$part_2_data" ) -gt $COLS_INNER ]];then
12474 graphics_data=$( create_print_line "$line_starter" "$part_1_data" )
12475 print_screen_output "$graphics_data"
12479 if [[ -n $part_1_data$part_2_data ]];then
12480 graphics_data=$( create_print_line "$line_starter" "$part_1_data$part_2_data" )
12481 print_screen_output "$graphics_data"
12487 print_hard_disk_data()
12490 local hdd_data='' hdd_data_2='' a_hdd_working='' hdd_temp_data='' hdd_string=''
12491 local hdd_serial='' dev_string='/dev/'
12492 local dev_data='' size_data='' hdd_model='' usb_data='' hdd_name=''
12493 local Line_Starter='Drives:' # inherited by print_optical_drives
12494 # load A_HDD_DATA - this will also populate the full bsd disk data array values
12496 ## note: if hdd_model is declared prior to use, whatever string you want inserted will
12497 ## be inserted first. In this case, it's desirable to print out (x) before each disk found.
12498 local a_hdd_data_count=$(( ${#A_HDD_DATA[@]} - 1 ))
12500 local a_hdd_basic_working=( ${A_HDD_DATA[$a_hdd_data_count]} )
12501 IFS="$ORIGINAL_IFS"
12502 local hdd_capacity="${a_hdd_basic_working[0]}"
12503 local hdd_used=${a_hdd_basic_working[1]}
12504 local bsd_error="No HDD Info. $FILE_DMESG_BOOT not readable?"
12505 local hdd_name_temp='' part_1_data='' part_2_data=''
12506 local row_starter="${C1}HDD Total Size$SEP3${C2} $hdd_capacity ($hdd_used) "
12507 # in bsd, /dev/wd0c is disk id
12508 if [[ -n $BSD_TYPE ]];then
12512 if [[ $B_SHOW_BASIC_DISK == 'true' || $B_SHOW_DISK == 'true' ]];then
12513 ## note: the output part of this should be in the print hdd data function, not here
12514 get_hard_drive_data_advanced
12516 # temporary message to indicate not yet supported
12517 if [[ $BSD_TYPE == 'bsd' && -z $Dmesg_Boot_Data ]];then
12518 hdd_data=$bsd_error
12519 hdd_data=$( create_print_line "$Line_Starter" "$hdd_data" )
12520 print_screen_output "$hdd_data"
12523 for (( i=0; i < ${#A_HDD_DATA[@]} - 1; i++ ))
12525 # this adds the (x) numbering in front of each disk found, and creates the full disk string
12527 a_hdd_working=( ${A_HDD_DATA[i]} )
12528 IFS="$ORIGINAL_IFS"
12529 if [[ $B_SHOW_DISK == 'true' ]];then
12530 if [[ -n ${a_hdd_working[3]} ]];then
12531 usb_data="${a_hdd_working[3]} "
12535 size_data=" ${C1}size$SEP3${C2} ${a_hdd_working[1]}"
12536 if [[ $B_EXTRA_DATA == 'true' ]];then
12537 hdd_temp_data=${a_hdd_working[5]}
12538 # error handling is done in get data function
12539 if [[ -n $hdd_temp_data ]];then
12540 hdd_temp_data=" ${C1}temp$SEP3${C2} ${hdd_temp_data}C"
12545 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
12546 hdd_serial=${a_hdd_working[4]}
12547 if [[ -z $hdd_serial ]];then
12550 hdd_serial=" ${C1}serial$SEP3${C2} $hdd_serial"
12552 dev_data="$dev_string${a_hdd_working[0]} "
12554 if [[ -n ${a_hdd_working[2]} ]];then
12555 hdd_name_temp=${a_hdd_working[2]}
12557 hdd_name_temp='N/A'
12560 hdd_name="${C1}model$SEP3${C2} $hdd_name_temp"
12561 hdd_string="${C1}ID-$((i+1))$SEP3${C2} $usb_data$dev_data$hdd_name$size_data$hdd_serial$hdd_temp_data"
12562 part_1_data="$hdd_model$hdd_string "
12564 if [[ $i -eq 0 ]];then
12565 if [[ $( calculate_line_length "$row_starter$part_1_data" ) -gt $COLS_INNER ]];then
12566 hdd_data=$( create_print_line "$Line_Starter" "$row_starter" )
12567 print_screen_output "$hdd_data"
12571 hdd_data=$( create_print_line "$Line_Starter" "$part_1_data" )
12572 print_screen_output "$hdd_data"
12576 hdd_data=$( create_print_line "$Line_Starter" "$row_starter$part_1_data" )
12577 print_screen_output "$hdd_data"
12584 if [[ $( calculate_line_length "$row_starter$part_2_data$part_1_data" ) -gt $COLS_INNER ]];then
12585 if [[ -n $( grep -vE '^[[:space:]]*$' <<< $part_2_data ) ]];then
12586 hdd_data=$( create_print_line "$Line_Starter" "$row_starter$part_2_data" )
12587 print_screen_output "$hdd_data"
12593 hdd_data=$( create_print_line "$Line_Starter" "$row_starter$part_1_data" )
12594 print_screen_output "$hdd_data"
12597 elif [[ -n $part_2_data && \
12598 $( calculate_line_length "$row_starter$part_2_data$part_1_data" ) -le $COLS_INNER ]];then
12599 hdd_data=$( create_print_line "$Line_Starter" "$row_starter$part_2_data$part_1_data" )
12600 print_screen_output "$hdd_data"
12607 part_2_data=$part_1_data
12610 # then print any leftover items
12611 if [[ -n $part_2_data ]];then
12612 hdd_data=$( create_print_line "$Line_Starter" "$part_2_data" )
12613 print_screen_output "$hdd_data"
12618 hdd_data="$row_starter"
12619 hdd_data=$( create_print_line "$Line_Starter" "$hdd_data" )
12620 print_screen_output "$hdd_data"
12623 if [[ $B_SHOW_FULL_OPTICAL == 'true' || $B_SHOW_BASIC_OPTICAL == 'true' ]];then
12624 print_optical_drive_data
12634 local info_data='' line_starter='Info:' runlvl_default='' runlvl='' runlvl_title='runlevel'
12635 local init_data='' init_type='' init_version='' rc_type='' rc_version=''
12636 local client_data='' shell_data='' shell_parent='' tty_session=''
12637 local memory="$( get_memory_data )"
12638 local processes=$(( $( wc -l <<< "$Ps_aux_Data" ) - 1 ))
12639 local up_time="$( get_uptime )"
12640 if [[ -z $up_time ]];then
12641 up_time='N/A - missing uptime?'
12643 local patch_version_number=$( get_patch_version_string )
12644 local gcc_installed='' gcc_others='' closing_data=''
12646 if [[ -z $memory ]];then
12650 if [[ $B_EXTRA_DATA == 'true' ]];then
12651 get_gcc_system_version
12652 if [[ ${#A_GCC_VERSIONS[@]} -gt 0 ]];then
12653 if [[ -n ${A_GCC_VERSIONS[0]} ]];then
12654 gcc_installed=${A_GCC_VERSIONS[0]}
12656 gcc_installed='N/A'
12658 if [[ $B_EXTRA_EXTRA_DATA == 'true' && -n ${A_GCC_VERSIONS[1]} ]];then
12659 # gcc_others=" ${C1}alt$SEP3${C2} $( tr ',' '/' <<< ${A_GCC_VERSIONS[1]} )"
12660 gcc_others=" ${C1}alt$SEP3${C2} ${A_GCC_VERSIONS[1]//,//}"
12662 gcc_installed="${C1}Gcc sys$SEP3${C2} $gcc_installed$gcc_others "
12665 if [[ $B_IRC == 'false' ]];then
12666 shell_data=$( get_shell_data )
12667 if [[ -n $shell_data ]];then
12668 # note, if you start this in tty, it will give 'login' as the parent, which we don't want.
12669 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
12670 if [[ $B_RUNNING_IN_DISPLAY != 'true' ]];then
12671 shell_parent=$( get_tty_number )
12672 shell_parent="tty $shell_parent"
12674 shell_parent=$( get_shell_parent )
12676 if [[ $shell_parent == 'login' ]];then
12678 elif [[ -n $shell_parent ]];then
12679 shell_parent=" running in ${shell_parent##*/}"
12682 IRC_CLIENT="$IRC_CLIENT ($shell_data$shell_parent)"
12686 # Some code could look superfluous but BitchX doesn't like lines not ending in a newline. F*&k that bitch!
12687 # long_last=$( echo -ne "${C1}Processes$SEP3${C2} $processes${CN} | ${C1}Uptime$SEP3${C2} $up_time${CN} | ${C1}Memory$SEP3${C2} $MEM${CN}" )
12688 info_data="${C1}Processes$SEP3${C2} $processes ${C1}Uptime$SEP3${C2} $up_time ${C1}Memory$SEP3${C2} $memory "
12690 # this only triggers if no X data is present or if extra data switch is on
12691 if [[ $B_SHOW_DISPLAY_DATA != 'true' || $B_EXTRA_DATA == 'true' ]];then
12693 if [[ ${A_INIT_DATA[0]} == 'systemd' && -z $( grep -E '^[0-9]$' <<< ${A_INIT_DATA[4]} ) ]];then
12694 runlvl_title='target'
12696 init_type=${A_INIT_DATA[0]}
12697 if [[ -z $init_type ]];then
12700 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
12701 init_version=${A_INIT_DATA[1]}
12702 if [[ -z $init_version ]];then
12705 init_version=" ${C1}v$SEP3${C2} $init_version"
12706 rc_version=${A_INIT_DATA[3]}
12707 if [[ -n $rc_version ]];then
12708 rc_version="${C1}v$SEP3${C2} $rc_version "
12710 runlvl_default=${A_INIT_DATA[5]}
12712 # currently only using openrc here, otherwise show nothing
12713 rc_type=${A_INIT_DATA[2]}
12714 if [[ -n $rc_type ]];then
12715 rc_type="${C1}rc$SEP3${C2} $rc_type $rc_version"
12717 init_type="${C1}Init$SEP3${C2} $init_type$init_version "
12718 runlvl=${A_INIT_DATA[4]}
12719 if [[ -n $runlvl ]];then
12720 runlvl="${C1}$runlvl_title$SEP3${C2} $runlvl "
12722 if [[ -n $runlvl_default ]];then
12723 runlvl_default="${C1}default$SEP3${C2} $runlvl_default "
12725 init_data="$init_type$rc_type$runlvl$runlvl_default"
12727 if [[ $SHOW_IRC -gt 0 ]];then
12728 client_data="${C1}Client$SEP3${C2} $IRC_CLIENT$IRC_CLIENT_VERSION "
12730 # info_data="$info_data"
12731 closing_data="$client_data${C1}$SCRIPT_NAME$SEP3${C2} $SCRIPT_VERSION_NUMBER$patch_version_number"
12732 # sometimes gcc is very long, and default runlevel can be long with systemd, so create a gcc-less line first
12733 if [[ $( calculate_line_length "$info_data$init_data$gcc_installed" ) -gt $COLS_INNER ]];then
12734 # info_data=$info_data
12735 info_data=$( create_print_line "$line_starter" "$info_data" )
12736 print_screen_output "$info_data"
12742 if [[ $( calculate_line_length "$init_data$gcc_installed" ) -gt $COLS_INNER ]];then
12743 info_data=$init_data
12744 info_data=$( create_print_line "$line_starter" "$info_data" )
12745 print_screen_output "$info_data"
12751 if [[ $( calculate_line_length "$info_data$init_data$gcc_installed$closing_data" ) -gt $COLS_INNER ]];then
12752 info_data=$info_data$init_data$gcc_installed
12753 info_data=$( create_print_line "$line_starter" "$info_data" )
12754 print_screen_output "$info_data"
12761 info_data="$info_data$init_data$gcc_installed$closing_data"
12763 info_data=$( create_print_line "$line_starter" "$info_data" )
12764 if [[ $SCHEME -gt 0 ]];then
12765 info_data="$info_data ${NORMAL}"
12767 print_screen_output "$info_data"
12771 #print_info_data;exit
12772 print_machine_data()
12776 local system_line='' mobo_line='' bios_line='' chassis_line=''
12777 local mobo_vendor='' mobo_model='' mobo_version='' mobo_serial=''
12778 local bios_vendor='' bios_version='' bios_date='' bios_rom='' error_string=''
12779 local system_vendor='' product_name='' product_version='' product_serial='' product_uuid=''
12780 local chassis_vendor='' chassis_type='' chassis_version='' chassis_serial=''
12781 local b_skip_system='false' b_skip_chassis='false'
12782 local sysDmiNull='No /sys/class/dmi machine data: try newer kernel, or install dmidecode'
12783 # set A_MACHINE_DATA
12787 ## keys for machine data are:
12788 # 0-sys_vendor 1-product_name 2-product_version 3-product_serial 4-product_uuid
12789 # 5-board_vendor 6-board_name 7-board_version 8-board_serial
12790 # 9-bios_vendor 10-bios_version 11-bios_date
12791 ## with extra data:
12792 # 12-chassis_vendor 13-chassis_type 14-chassis_version 15-chassis_serial
12793 # a null array always has a count of 1
12794 if [[ ${#A_MACHINE_DATA[@]} -gt 1 ]];then
12795 # note: in some case a mobo/version will match a product name/version, do not print those
12796 # but for laptops, or even falsely id'ed desktops with batteries, let's print it all if it matches
12797 # there can be false id laptops if battery appears so need to make sure system is filled
12798 if [[ -z ${A_MACHINE_DATA[0]} ]];then
12799 b_skip_system='true'
12801 if [[ $B_PORTABLE != 'true' ]];then
12802 # ibm / ibm can be true; dell / quantum is false, so in other words, only do this
12803 # in case where the vendor is the same and the version is the same and not null,
12804 # otherwise the version information is going to be different in all cases I think
12805 if [[ -n ${A_MACHINE_DATA[0]} && ${A_MACHINE_DATA[0]} == ${A_MACHINE_DATA[5]} ]];then
12806 if [[ -n ${A_MACHINE_DATA[2]} && ${A_MACHINE_DATA[2]} == ${A_MACHINE_DATA[7]} ]] || \
12807 [[ -z ${A_MACHINE_DATA[2]} && ${A_MACHINE_DATA[1]} == ${A_MACHINE_DATA[6]} ]];then
12808 b_skip_system='true'
12813 # no point in showing chassis if system isn't there, it's very unlikely that would be correct
12814 if [[ $B_EXTRA_EXTRA_DATA == 'true' && $b_skip_system != 'true' ]];then
12815 if [[ -n ${A_MACHINE_DATA[7]} && ${A_MACHINE_DATA[14]} == ${A_MACHINE_DATA[7]} ]];then
12816 b_skip_chassis='true'
12818 if [[ -n ${A_MACHINE_DATA[12]} && $b_skip_chassis != 'true' ]];then
12819 # no need to print the vendor string again if it's the same
12820 if [[ ${A_MACHINE_DATA[12]} != ${A_MACHINE_DATA[0]} ]];then
12821 chassis_vendor=" ${A_MACHINE_DATA[12]}"
12823 if [[ -n ${A_MACHINE_DATA[13]} ]];then
12824 chassis_type=" ${C1}type$SEP3${C2} ${A_MACHINE_DATA[13]}"
12826 if [[ -n ${A_MACHINE_DATA[14]} ]];then
12827 chassis_version=" ${C1}v$SEP3${C2} ${A_MACHINE_DATA[14]}"
12829 if [[ -n ${A_MACHINE_DATA[15]} && $B_OUTPUT_FILTER != 'true' ]];then
12830 chassis_serial=" ${C1}serial$SEP3${C2} ${A_MACHINE_DATA[15]}"
12832 if [[ -n "$chassis_vendor$chassis_type$chassis_version$chassis_serial" ]];then
12833 chassis_line="${C1}Chassis$SEP3${C2}$chassis_vendor$chassis_type$chassis_version$chassis_serial"
12837 if [[ -n ${A_MACHINE_DATA[5]} ]];then
12838 mobo_vendor=${A_MACHINE_DATA[5]}
12842 if [[ -n ${A_MACHINE_DATA[6]} ]];then
12843 mobo_model=${A_MACHINE_DATA[6]}
12847 if [[ -n ${A_MACHINE_DATA[7]} ]];then
12848 mobo_version=" ${C1}v$SEP3${C2} ${A_MACHINE_DATA[7]}"
12850 if [[ -n ${A_MACHINE_DATA[8]} && $B_OUTPUT_FILTER != 'true' ]];then
12851 mobo_serial=" ${C1}serial$SEP3${C2} ${A_MACHINE_DATA[8]}"
12853 if [[ -n ${A_MACHINE_DATA[9]} ]];then
12854 bios_vendor=${A_MACHINE_DATA[9]}
12858 if [[ -n ${A_MACHINE_DATA[10]} ]];then
12859 bios_version=${A_MACHINE_DATA[10]}
12860 if [[ -n ${A_MACHINE_DATA[16]} ]];then
12861 bios_version="$bios_version rv ${A_MACHINE_DATA[16]}"
12866 if [[ -n ${A_MACHINE_DATA[11]} ]];then
12867 bios_date=${A_MACHINE_DATA[11]}
12871 if [[ $B_EXTRA_EXTRA_DATA == 'true' && -n ${A_MACHINE_DATA[17]} ]];then
12872 bios_rom=" ${C1}rom size$SEP3${C2} ${A_MACHINE_DATA[17]}"
12874 mobo_line="${C1}Mobo$SEP3${C2} $mobo_vendor ${C1}model$SEP3${C2} $mobo_model$mobo_version$mobo_serial"
12875 bios_line="${C1}Bios$SEP3${C2} $bios_vendor ${C1}v$SEP3${C2} $bios_version ${C1}date$SEP3${C2} $bios_date$bios_rom"
12876 if [[ $( calculate_line_length "$mobo_line$bios_line" ) -lt $COLS_INNER ]];then
12877 mobo_line="$mobo_line $bios_line"
12880 if [[ $b_skip_system == 'true' ]];then
12881 system_line=$mobo_line
12884 # this has already been tested for above so we know it's not null
12885 system_vendor=${A_MACHINE_DATA[0]}
12886 if [[ $B_PORTABLE == 'true' ]];then
12887 system_vendor="$system_vendor (portable)"
12889 if [[ -n ${A_MACHINE_DATA[1]} ]];then
12890 product_name=${A_MACHINE_DATA[1]}
12894 if [[ -n ${A_MACHINE_DATA[2]} ]];then
12895 product_version=" ${C1}v$SEP3${C2} ${A_MACHINE_DATA[2]}"
12897 if [[ -n ${A_MACHINE_DATA[3]} && $B_OUTPUT_FILTER != 'true' ]];then
12898 product_serial=" ${C1}serial$SEP3${C2} ${A_MACHINE_DATA[3]} "
12900 system_line="${C1}System$SEP3${C2} $system_vendor ${C1}product$SEP3${C2} $product_name$product_version$product_serial"
12901 if [[ -n $chassis_line && $( calculate_line_length "$system_line$chassis_line" ) -lt $COLS_INNER ]];then
12902 system_line="$system_line $chassis_line"
12907 system_line="${C2}$sysDmiNull"
12909 IFS="$ORIGINAL_IFS"
12910 # patch to dump all of above if dmidecode was data source and a dmidecode error is present
12911 if [[ ${A_MACHINE_DATA[0]} == 'dmidecode-error-'* ]];then
12912 error_string=$( print_dmidecode_error 'sys' "${A_MACHINE_DATA[0]}" )
12913 system_line=${C2}$error_string
12918 system_line=$( create_print_line "Machine:" "$system_line" )
12919 print_screen_output "$system_line"
12920 if [[ -n $mobo_line ]];then
12921 mobo_line=$( create_print_line " " "$mobo_line" )
12922 print_screen_output "$mobo_line"
12924 if [[ -n $bios_line ]];then
12925 bios_line=$( create_print_line " " "$bios_line" )
12926 print_screen_output "$bios_line"
12928 if [[ -n $chassis_line ]];then
12929 chassis_line=$( create_print_line " " "$chassis_line" )
12930 print_screen_output "$chassis_line"
12936 # args: $1 - module name (could be > 1, so loop it ); $2 - audio (optional)
12937 print_module_version()
12940 local module_versions='' module='' version='' prefix='' modules=$1
12942 # note that sound driver data tends to have upper case, but modules are lower
12943 if [[ $2 == 'audio' ]];then
12944 if [[ -z $( grep -E '^snd' <<< $modules ) ]];then
12945 prefix='snd_' # sound modules start with snd_
12947 modules=$( tr '[A-Z]' '[a-z]' <<< "$modules" )
12948 modules=${modules//-/_}
12949 # special intel processing, generally no version info though
12950 if [[ $modules == 'hda intel' ]];then
12951 modules='hda_intel'
12952 elif [[ $modules == 'intel ich' ]];then
12957 for module in $modules
12959 version=$( get_module_version_number "$prefix$module" )
12960 if [[ -n $version ]];then
12961 module_versions="$module_versions $version"
12965 if [[ -n $module_versions ]];then
12966 echo " ${C1}v$SEP3${C2}$module_versions"
12971 print_networking_data()
12974 local i='' card_id='' network_data='' a_network_working='' port_data='' driver_data=''
12975 local card_string='' port_plural='' module_version='' pci_bus_id='' bus_usb_text=''
12976 local bus_usb_id='' line_starter='Network:' card_string='' card_data='' chip_id=''
12977 local driver='' part_2_data=''
12979 # set A_NETWORK_DATA
12980 if [[ $BSD_TYPE == 'bsd' ]];then
12981 if [[ $B_PCICONF == 'true' ]];then
12982 if [[ $B_PCICONF_SET == 'false' ]];then
12985 get_pciconf_card_data 'network'
12986 elif [[ $B_LSPCI == 'true' ]];then
12987 get_networking_data
12990 get_networking_data
12993 # will never be null because null is handled in get_network_data, but in case we change
12994 # that leaving this test in place.
12995 if [[ -n ${A_NETWORK_DATA[@]} ]];then
12996 for (( i=0; i < ${#A_NETWORK_DATA[@]}; i++ ))
12999 a_network_working=( ${A_NETWORK_DATA[i]} )
13000 IFS="$ORIGINAL_IFS"
13014 if [[ ${#A_NETWORK_DATA[@]} -gt 1 ]];then
13015 card_id="-$(( $i + 1 ))"
13017 if [[ -n ${a_network_working[1]} && $B_EXTRA_DATA == 'true' && $BSD_TYPE != 'bsd' ]];then
13018 module_version=$( print_module_version "${a_network_working[1]}" )
13020 if [[ -n ${a_network_working[1]} ]];then
13021 # note: linux drivers can have numbers, like tg3
13022 if [[ $BSD_TYPE == 'bsd' ]];then
13023 driver=$( sed 's/[0-9]*$//' <<< ${a_network_working[1]} )
13025 driver=${a_network_working[1]}
13027 driver_data="${C1}driver$SEP3${C2} $driver$module_version "
13029 if [[ -n ${a_network_working[2]} && $B_EXTRA_DATA == 'true' ]];then
13030 if [[ $( wc -w <<< ${a_network_working[2]} ) -gt 1 ]];then
13033 port_data="${C1}port$port_plural$SEP3${C2} ${a_network_working[2]} "
13035 if [[ -n ${a_network_working[4]} && $B_EXTRA_DATA == 'true' ]];then
13036 if [[ -z $( grep '^usb-' <<< ${a_network_working[4]} ) ]];then
13037 bus_usb_text='bus-ID'
13038 bus_usb_id=${a_network_working[4]}
13039 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
13040 if [[ $BSD_TYPE != 'bsd' ]];then
13041 chip_id=$( get_lspci_chip_id "${a_network_working[4]}" )
13043 chip_id=${a_network_working[10]}
13047 bus_usb_text='usb-ID'
13048 bus_usb_id=$( cut -d '-' -f '2-4' <<< ${a_network_working[4]} )
13049 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
13050 chip_id=${a_network_working[10]}
13053 pci_bus_id="${C1}$bus_usb_text$SEP3${C2} $bus_usb_id"
13054 if [[ -n $chip_id ]];then
13055 chip_id=" ${C1}chip-ID$SEP3${C2} $chip_id"
13058 card_string="${C1}Card$card_id$SEP3${C2} ${a_network_working[0]} "
13059 card_data="$driver_data$port_data"
13060 part_2_data="$pci_bus_id$chip_id"
13061 if [[ $( calculate_line_length "$card_string$card_data$part_2_data" ) -gt $COLS_INNER ]];then
13062 network_data=$( create_print_line "$line_starter" "$card_string" )
13065 print_screen_output "$network_data"
13067 if [[ $( calculate_line_length "$card_string$card_data$part_2_data" ) -gt $COLS_INNER ]];then
13068 network_data=$( create_print_line "$line_starter" "$card_string$card_data" )
13069 print_screen_output "$network_data"
13075 if [[ -n $card_string$card_data$part_2_data ]];then
13076 network_data=$( create_print_line "$line_starter" "$card_string$card_data$part_2_data" )
13077 print_screen_output "$network_data"
13083 if [[ $B_SHOW_ADVANCED_NETWORK == 'true' ]];then
13084 print_network_advanced_data
13088 network_data="${C1}Card$SEP3${C2} Failed to Detect Network Card! "
13089 network_data=$( create_print_line "$line_starter" "$network_data" )
13090 print_screen_output "$network_data"
13092 if [[ $B_SHOW_IP == 'true' ]];then
13093 print_networking_ip_data
13098 print_network_advanced_data()
13101 local network_data='' if_id='N/A' duplex='N/A' mac_id='N/A' speed='N/A' oper_state='N/A'
13102 local b_is_wifi='false' speed_string='' duplex_string='' part_2_data=''
13104 # first check if it's a known wifi id'ed card, if so, no print of duplex/speed
13105 if [[ -n $( grep -Esi '(wireless|wifi|wi-fi|wlan|802\.11|centrino)' <<< ${a_network_working[0]} ) ]];then
13108 if [[ -n ${a_network_working[5]} ]];then
13109 if_id=${a_network_working[5]}
13111 if [[ -n ${a_network_working[6]} ]];then
13112 oper_state=${a_network_working[6]}
13114 # no print out for wifi since it doesn't have duplex/speed data availabe
13115 # note that some cards show 'unknown' for state, so only testing explicitly
13116 # for 'down' string in that to skip showing speed/duplex
13117 if [[ $b_is_wifi != 'true' && $oper_state != 'down' ]];then
13118 if [[ -n ${a_network_working[7]} ]];then
13119 # make sure the value is strictly numeric before appending Mbps
13120 if [[ -n $( grep -E '^[0-9\.,]+$' <<< "${a_network_working[7]}" ) ]];then
13121 speed="${a_network_working[7]} Mbps"
13123 speed=${a_network_working[7]}
13126 speed_string="${C1}speed$SEP3${C2} $speed "
13127 if [[ -n ${a_network_working[8]} ]];then
13128 duplex=${a_network_working[8]}
13130 duplex_string="${C1}duplex$SEP3${C2} $duplex "
13132 if [[ -n ${a_network_working[9]} ]];then
13133 if [[ $B_OUTPUT_FILTER == 'true' ]];then
13134 mac_id=$FILTER_STRING
13136 mac_id=${a_network_working[9]}
13139 network_data="${C1}IF$SEP3${C2} $if_id ${C1}state$SEP3${C2} $oper_state $speed_string$duplex_string"
13140 part_2_data="${C1}mac$SEP3${C2} $mac_id"
13141 if [[ $( calculate_line_length "$network_data$part_2_data" ) -gt $COLS_INNER ]];then
13142 network_data=$( create_print_line " " "$network_data" )
13143 print_screen_output "$network_data"
13146 if [[ -n $network_data$part_2_data ]];then
13147 network_data=$( create_print_line " " "$network_data$part_2_data" )
13148 print_screen_output "$network_data"
13155 print_networking_ip_data()
13158 local ip=$( get_networking_wan_ip_data )
13159 local wan_ip_data='' a_interfaces_working='' interfaces='' i=0
13160 local if_id='' if_ip='' if_ipv6='' if_ipv6_string='' full_string='' if_string=''
13161 local if_id_string='' if_ip_string='' if_string_holding=''
13163 # set A_INTERFACES_DATA
13164 get_networking_local_ip_data
13165 # first print output for wan ip line. Null is handled in the get function
13166 if [[ -z $ip ]];then
13169 if [[ $B_OUTPUT_FILTER == 'true' ]];then
13173 wan_ip_data="${C1}WAN IP$SEP3${C2} $ip "
13174 # then create the list of local interface/ip
13175 i=0 ## loop starts with 1 by auto-increment so it only shows cards > 1
13176 while [[ -n ${A_INTERFACES_DATA[i]} ]]
13179 a_interfaces_working=(${A_INTERFACES_DATA[i]})
13180 IFS="$ORIGINAL_IFS"
13185 if [[ -z $( grep '^Interface' <<< ${a_interfaces_working[0]} ) ]];then
13186 if [[ -n ${a_interfaces_working[1]} ]];then
13187 if [[ $B_OUTPUT_FILTER == 'true' ]];then
13188 if_ip=$FILTER_STRING
13190 if_ip=${a_interfaces_working[1]}
13193 if_ip_string=" ${C1}ip-v4$SEP3${C2} $if_ip"
13194 if [[ $B_EXTRA_DATA == 'true' ]];then
13195 if [[ -n ${a_interfaces_working[3]} ]];then
13196 if [[ $B_OUTPUT_FILTER == 'true' ]];then
13197 if_ipv6=$FILTER_STRING
13199 if_ipv6=${a_interfaces_working[3]}
13202 if_ipv6_string=" ${C1}ip-v6$SEP3${C2} $if_ipv6"
13205 if [[ -n ${a_interfaces_working[0]} ]];then
13206 if_id=${a_interfaces_working[0]}
13208 if_string="${C1}IF$SEP3${C2} $if_id$if_ip_string$if_ipv6_string "
13209 # first line, print wan on its own line if too long
13210 if [[ $i -eq 0 ]];then
13211 if [[ $( calculate_line_length "$wan_ip_data$if_string" ) -gt $COLS_INNER ]];then
13212 full_string=$( create_print_line " " "$wan_ip_data" )
13213 print_screen_output "$full_string"
13215 full_string=$( create_print_line " " "$if_string" )
13216 print_screen_output "$full_string"
13219 full_string=$( create_print_line " " "$wan_ip_data$if_string" )
13220 print_screen_output "$full_string"
13225 if [[ $( calculate_line_length "$if_string_holding$if_string" ) -gt $COLS_INNER ]];then
13226 if [[ -n $if_string_holding ]];then
13227 full_string=$( create_print_line " " "$if_string_holding" )
13228 print_screen_output "$full_string"
13230 if_string_holding="$if_string"
13232 if_string_holding="$if_string_holding$if_string"
13238 # then print out anything not printed already
13239 if [[ -n $if_string_holding ]];then
13240 full_string=$( create_print_line " " "$if_string_holding" )
13241 print_screen_output "$full_string"
13246 print_optical_drive_data()
13249 local a_drives='' drive_data='' counter='' dev_string='/dev/' speed_string='x'
13250 local drive_id='' drive_links='' vendor='' speed='' multisession='' mcn='' audio=''
13251 local dvd='' state='' rw_support='' rev='' separator='' drive_string='' part_2_data=''
13252 if [[ -z $BSD_TYPE ]];then
13253 get_optical_drive_data
13255 get_optical_drive_data_bsd
13259 # 0 - true dev path, ie, sr0, hdc
13260 # 1 - dev links to true path
13261 # 2 - device vendor - for hdx drives, vendor model are one string from proc
13263 # 4 - device rev version
13264 if [[ ${#A_OPTICAL_DRIVE_DATA[@]} -gt 0 ]];then
13265 for (( i=0; i < ${#A_OPTICAL_DRIVE_DATA[@]}; i++ ))
13268 a_drives=(${A_OPTICAL_DRIVE_DATA[i]})
13269 IFS="$ORIGINAL_IFS"
13283 if [[ ${#A_OPTICAL_DRIVE_DATA[@]} -eq 1 && -z ${a_drives[0]} && -z ${a_drives[1]} ]];then
13284 drive_string="No optical drives detected."
13285 B_SHOW_FULL_OPTICAL='false'
13287 if [[ ${#A_OPTICAL_DRIVE_DATA[@]} -gt 1 ]];then
13288 counter="-$(( i + 1 ))"
13290 if [[ -z ${a_drives[0]} ]];then
13293 drive_id="$dev_string${a_drives[0]}"
13295 drive_links=$( sed 's/~/,/g' <<< ${a_drives[1]} )
13296 if [[ -z $drive_links ]];then
13299 if [[ -n ${a_drives[2]} ]];then
13300 vendor=${a_drives[2]}
13301 if [[ -n ${a_drives[3]} ]];then
13302 vendor="$vendor ${a_drives[3]}"
13305 if [[ -z $vendor ]];then
13306 if [[ -n ${a_drives[3]} ]];then
13307 vendor=${a_drives[3]}
13312 if [[ $B_EXTRA_DATA == 'true' ]];then
13313 if [[ -n ${a_drives[4]} ]];then
13318 rev="${C1}rev$SEP3${C2} $rev "
13320 drive_string="$drive_id ${C1}model$SEP3${C2} $vendor "
13321 part_2_data="$rev${C1}dev-links$SEP3${C2} $drive_links"
13323 drive_data="${C1}Optical${counter}$SEP3${C2} $drive_string"
13324 if [[ $( calculate_line_length "$drive_data$part_2_data" ) -lt $COLS_INNER ]];then
13325 drive_data=$( create_print_line "$Line_Starter" "$drive_data$part_2_data" )
13326 print_screen_output "$drive_data"
13331 if [[ $( calculate_line_length "$drive_data" ) -gt $COLS_INNER ]];then
13332 drive_data=$( create_print_line "$Line_Starter" "$drive_data" )
13333 print_screen_output "$drive_data"
13337 if [[ $( calculate_line_length "$drive_data$part_2_data" ) -lt $COLS_INNER ]];then
13338 drive_data=$( create_print_line "$Line_Starter" "$drive_data$part_2_data" )
13339 print_screen_output "$drive_data"
13344 drive_data=$( create_print_line "$Line_Starter" "$drive_data" )
13345 print_screen_output "$drive_data"
13348 drive_data=$( create_print_line "$Line_Starter" "$part_2_data" )
13349 print_screen_output "$drive_data"
13356 # 6 - multisession support
13365 if [[ $B_SHOW_FULL_OPTICAL == 'true' ]];then
13366 if [[ -z ${a_drives[5]} ]];then
13369 speed="${a_drives[5]}$speed_string"
13371 if [[ -z ${a_drives[8]} ]];then
13373 elif [[ ${a_drives[8]} == 1 ]];then
13378 audio="${C1}audio$SEP3${C2} $audio "
13379 if [[ -z ${a_drives[6]} ]];then
13381 elif [[ ${a_drives[6]} == 1 ]];then
13386 multisession="${C1}multisession$SEP3${C2} $multisession "
13387 if [[ -z ${a_drives[11]} ]];then
13389 elif [[ ${a_drives[11]} == 1 ]];then
13394 if [[ $B_EXTRA_DATA == 'true' ]];then
13395 if [[ -z ${a_drives[14]} ]];then
13398 state="${a_drives[14]}"
13400 state="${C1}state$SEP3${C2} $state "
13402 if [[ -n ${a_drives[9]} && ${a_drives[9]} == 1 ]];then
13406 if [[ -n ${a_drives[10]} && ${a_drives[10]} == 1 ]];then
13407 rw_support="$rw_support${separator}cd-rw"
13410 if [[ -n ${a_drives[12]} && ${a_drives[12]} == 1 ]];then
13411 rw_support="$rw_support${separator}dvd-r"
13414 if [[ -n ${a_drives[13]} && ${a_drives[13]} == 1 ]];then
13415 rw_support="$rw_support${separator}dvd-ram"
13418 if [[ -z $rw_support ]];then
13421 drive_data="${C1}Features: speed$SEP3${C2} $speed $multisession"
13422 part_2_data="$audio${C1}dvd$SEP3${C2} $dvd ${C1}rw$SEP3${C2} $rw_support $state"
13423 if [[ $( calculate_line_length "$drive_data$part_2_data" ) -lt $COLS_INNER ]];then
13424 drive_data=$( create_print_line "$Line_Starter" "$drive_data$part_2_data" )
13425 print_screen_output "$drive_data"
13428 drive_data=$( create_print_line "$Line_Starter" "$drive_data" )
13429 print_screen_output "$drive_data"
13430 drive_data=$( create_print_line "$Line_Starter" "$part_2_data" )
13431 print_screen_output "$drive_data"
13442 print_partition_data()
13445 local a_partition_working='' partition_used='' partition_data=''
13446 local counter=0 i=0 part_id=0 a_partition_data='' line_starter=''
13447 local partitionIdClean='' part_dev='' full_dev='' part_label='' full_label=''
13448 local part_uuid='' full_uuid='' dev_remote='' full_fs=''
13449 local b_non_dev='false' holder=''
13451 # set A_PARTITION_DATA
13454 for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
13457 a_partition_working=(${A_PARTITION_DATA[i]})
13458 IFS="$ORIGINAL_IFS"
13462 if [[ $B_SHOW_PARTITIONS_FULL == 'true' ]] || [[ ${a_partition_working[4]} == 'main' ]];then
13463 if [[ -n ${a_partition_working[2]} ]];then
13464 partition_used="${C1}used$SEP3${C2} ${a_partition_working[2]} (${a_partition_working[3]}) "
13466 partition_used='' # reset partition used to null
13468 if [[ -n ${a_partition_working[5]} ]];then
13469 full_fs="${a_partition_working[5]}"
13471 full_fs='N/A' # reset partition fs type
13473 full_fs="${C1}fs$SEP3${C2} $full_fs "
13474 if [[ -n ${a_partition_working[6]} ]];then
13475 if [[ -z $( grep -E '(^//|:/|non-dev)' <<< ${a_partition_working[6]} ) ]];then
13476 part_dev="/dev/${a_partition_working[6]}"
13478 elif [[ -n $( grep '^non-dev' <<< ${a_partition_working[6]} ) ]];then
13479 holder=$( sed 's/non-dev-//' <<< ${a_partition_working[6]} )
13483 part_dev="${a_partition_working[6]}"
13484 dev_remote='remote'
13490 full_dev="${C1}$dev_remote$SEP3${C2} $part_dev "
13491 if [[ $B_SHOW_LABELS == 'true' || $B_SHOW_UUIDS == 'true' ]];then
13492 if [[ $B_SHOW_LABELS == 'true' && $dev_remote != 'remote' ]];then
13493 if [[ -n ${a_partition_working[7]} ]];then
13494 part_label="${a_partition_working[7]}"
13498 full_label="${C1}label$SEP3${C2} $part_label "
13500 if [[ $B_SHOW_UUIDS == 'true' && $dev_remote != 'remote' ]];then
13501 if [[ -n ${a_partition_working[8]} ]];then
13502 part_uuid="${a_partition_working[8]}"
13506 full_uuid="${C1}uuid$SEP3${C2} $part_uuid"
13509 # don't show user names in output
13510 if [[ $B_OUTPUT_FILTER == 'true' ]];then
13511 partitionIdClean=$( sed $SED_RX "s|/home/([^/]+)/(.*)|/home/$FILTER_STRING/\2|" <<< ${a_partition_working[0]} )
13513 partitionIdClean=${a_partition_working[0]}
13515 id_size_fs="${C1}ID-$((part_id+1))$SEP3${C2} $partitionIdClean ${C1}size$SEP3${C2} ${a_partition_working[1]} $partition_used$full_fs$full_dev"
13516 label_uuid="$full_label$full_uuid"
13517 # label/uuid always print one per line, so only wrap if it's very long
13518 if [[ $B_SHOW_UUIDS == 'true' || $B_SHOW_LABELS == 'true' ]] && \
13519 [[ $( calculate_line_length "${a_partition_data[$counter]}$id_size_fs$label_uuid" ) -gt $COLS_INNER ]];then
13520 a_partition_data[$counter]="$id_size_fs"
13522 a_partition_data[$counter]="$label_uuid"
13524 if [[ $( calculate_line_length "${a_partition_data[$counter]}$id_size_fs$label_uuid" ) -gt $COLS_INNER ]];then
13525 a_partition_data[$counter]="${a_partition_data[$counter]}"
13527 a_partition_data[$counter]="$id_size_fs$label_uuid"
13529 a_partition_data[$counter]="${a_partition_data[$counter]}$id_size_fs$label_uuid"
13536 # print out all lines, line starter on first line
13537 for (( i=0; i < ${#a_partition_data[@]};i++ ))
13539 if [[ $i -eq 0 ]];then
13540 line_starter='Partition:'
13544 if [[ -n ${a_partition_data[$i]} ]];then
13545 partition_data=$( create_print_line "$line_starter" "${a_partition_data[$i]}" )
13546 print_screen_output "$partition_data"
13553 print_program_version()
13555 local patch_version_number=$( get_patch_version_string )
13556 local program_version="${C1}$SCRIPT_NAME$SEP3${C2} $SCRIPT_VERSION_NUMBER$patch_version_number${CN}"
13557 # great trick from: http://ideatrash.net/2011/01/bash-string-padding-with-sed.html
13558 # left pad: sed -e :a -e 's/^.\{1,80\}$/& /;ta'
13559 # right pad: sed -e :a -e 's/^.\{1,80\}$/ &/;ta'
13560 # center pad: sed -e :a -e 's/^.\{1,80\}$/ & /;ta'
13561 #local line_max=$COLS_INNER
13562 #program_version="$( sed -e :a -e "s/^.\{1,$line_max\}$/ &/;ta" <<< $program_version )" # use to create padding if needed
13563 # program_version=$( create_print_line "Version:" "$program_version${CN}" )
13564 print_screen_output "$program_version"
13571 local b_print_first='true'
13573 if [[ $B_SHOW_PS_CPU_DATA == 'true' ]];then
13574 get_ps_tcm_data 'cpu'
13575 print_ps_item 'cpu' "$b_print_first"
13576 b_print_first='false'
13578 if [[ $B_SHOW_PS_MEM_DATA == 'true' ]];then
13579 get_ps_tcm_data 'mem'
13580 print_ps_item 'mem' "$b_print_first"
13586 # args: $1 - cpu/mem; $2 true/false
13590 local a_ps_data='' ps_data='' line_starter='' line_start_data='' full_line=''
13591 local app_name='' app_pid='' app_cpu='' app_mem='' throttled='' app_daemon=''
13592 local b_print_first=$2 line_counter=0 i=0 count_nu='' extra_data='' memory='' extra_text=''
13594 if [[ -n $PS_THROTTLED ]];then
13595 throttled=" ${C1} - throttled from${C2} $PS_THROTTLED"
13597 # important: ${C2} $PS_COUNT must have space after ${C2} for irc output or the number vanishes
13600 if [[ $B_EXTRA_DATA == 'true' ]];then
13601 extra_text=" ${C1}- Memory$SEP3 MB / % used"
13602 if [[ $B_SHOW_INFO == 'false' && $B_SHOW_PS_MEM_DATA == 'false' ]];then
13603 memory=" - ${C1}Used/Total$SEP3${C2} $( get_memory_data )"
13606 line_start_data="${C1}CPU$SEP3 % used$extra_text$memory${C1} - top${C2} $PS_COUNT ${C1}active$throttled"
13609 if [[ $B_EXTRA_DATA == 'true' ]];then
13610 extra_text=" ${C1}- CPU$SEP3 % used"
13612 if [[ $B_SHOW_INFO == 'false' ]];then
13613 memory=" - ${C1}Used/Total$SEP3${C2} $( get_memory_data )"
13615 line_start_data="${C1}Memory$SEP3 MB / % used$memory$extra_text${C1} - top${C2} $PS_COUNT ${C1}active$throttled"
13619 if [[ $b_print_first == 'true' ]];then
13620 line_starter='Processes:'
13625 # appName, appPath, appStarterName, appStarterPath, cpu, mem, pid, vsz, user
13626 ps_data=$( create_print_line "$line_starter" "$line_start_data" )
13627 print_screen_output "$ps_data"
13629 for (( i=0; i < ${#A_PS_DATA[@]}; i++ ))
13632 a_ps_data=(${A_PS_DATA[i]})
13633 IFS="$ORIGINAL_IFS"
13635 # handle the converted app names, with ~..~ means it didn't have a path
13636 if [[ -n $( grep -E '^~.*~$' <<< ${a_ps_data[0]} ) ]];then
13637 app_daemon='daemon'
13639 app_daemon='command'
13642 app_name=" ${C1}$app_daemon$SEP3${C2} ${a_ps_data[0]}"
13643 if [[ ${a_ps_data[0]} != ${a_ps_data[2]} ]];then
13644 app_name="$app_name ${C1}(started by$SEP3${C2} ${a_ps_data[2]}${C1})${C2}"
13646 app_pid=" ${C1}pid$SEP3${C2} ${a_ps_data[6]}"
13647 # ${C1}user$SEP3${C2} ${a_ps_data[8]}
13650 app_cpu=" ${C1}cpu$SEP3${C2} ${a_ps_data[4]}%"
13651 if [[ $B_EXTRA_DATA == 'true' ]];then
13652 extra_data=" ${C1}mem$SEP3${C2} ${a_ps_data[7]}MB (${a_ps_data[5]}%)${C2}"
13656 app_mem=" ${C1}mem$SEP3${C2} ${a_ps_data[7]}MB (${a_ps_data[5]}%)${C2}"
13657 if [[ $B_EXTRA_DATA == 'true' ]];then
13658 extra_data=" ${C1}cpu$SEP3${C2} ${a_ps_data[4]}%"
13662 (( line_counter++ ))
13663 count_nu="${C1}$line_counter$SEP3${C2}"
13664 full_line="$count_nu$app_cpu$app_mem$app_name$app_pid$extra_data"
13665 ps_data=$( create_print_line " " "$full_line" )
13666 print_screen_output "$ps_data"
13675 local device='' device_string='' device_state='' raid_level='' device_components=''
13676 local device_report='' u_data='' blocks='' super_blocks='' algorithm='' chunk_size=''
13677 local bitmap_values='' recovery_progress_bar='' recovery_percent='' recovered_sectors=''
13678 local finish_time='' recovery_speed='' raid_counter=0 device_counter=1 basic_counter=1
13679 local a_raid_working='' raid_data='' kernel_support='' read_ahead='' unused_devices=''
13680 local basic_raid='' basic_raid_separator='' basic_raid_plural='' inactive=''
13681 local component_separator='' device_id='' print_string='' loop_limit=0 array_count_unused=''
13682 local array_count='' raid_event='' b_print_lines='true'
13683 local no_raid_detected='' dev_string='/dev/'
13684 local empty_raid_data='' report_size='report' blocks_avail='blocks' chunk_raid_usage='chunk size'
13686 if [[ -n $BSD_TYPE ]];then
13687 no_raid_detected='No zfs software RAID detected-other types not yet supported.'
13688 empty_raid_data='No zfs RAID data available-other types not yet supported.'
13690 blocks_avail='available'
13691 chunk_raid_usage='allocated'
13693 no_raid_detected="No RAID data: $FILE_MDSTAT missing-is md_mod kernel module loaded?"
13694 empty_raid_data="No RAID devices: $FILE_MDSTAT, md_mod kernel module present"
13697 if [[ $BSD_TYPE == 'bsd' ]];then
13700 if [[ $B_RAID_SET != 'true' ]];then
13704 for (( i=0; i < ${#A_RAID_DATA[@]}; i++ ))
13707 a_raid_working=(${A_RAID_DATA[i]})
13708 IFS="$ORIGINAL_IFS"
13710 # reset on each iteration
13714 component_separator=''
13716 device_components=''
13725 recovery_percent=''
13726 recovery_progress_bar=''
13727 recovered_sectors=''
13733 if [[ -n $( grep '^md' <<< ${a_raid_working[0]} ) && -z $BSD_TYPE ]] || \
13734 [[ -n $BSD_TYPE && ${a_raid_working[0]} != '' ]];then
13735 if [[ $B_SHOW_BASIC_RAID == 'true' ]];then
13736 if [[ $basic_raid != '' ]];then
13737 basic_raid_plural='s'
13739 if [[ ${a_raid_working[1]} == 'inactive' ]];then
13740 inactive=" - ${a_raid_working[1]}"
13742 basic_raid="$basic_raid$basic_raid_separator${C1}$basic_counter$SEP3${C2} $dev_string${a_raid_working[0]}$inactive"
13743 basic_raid_separator=' '
13744 (( basic_counter++ ))
13746 device_id="-$device_counter"
13747 device="$dev_string${a_raid_working[0]}"
13749 (( device_counter++ ))
13750 if [[ ${a_raid_working[1]} != '' ]];then
13751 device_state=" - ${a_raid_working[1]}"
13754 if [[ ${a_raid_working[2]} == '' ]];then
13757 raid_level=${a_raid_working[2]}
13759 # there's one case: md0 : inactive that has to be protected against
13760 if [[ ${a_raid_working[2]} == '' && ${a_raid_working[1]} == 'inactive' ]];then
13763 raid_level=" ${C1}raid$SEP3${C2} $raid_level"
13765 if [[ ${a_raid_working[4]} != '' ]];then
13766 device_report="${a_raid_working[4]}"
13768 device_report="N/A"
13770 if [[ $B_EXTRA_DATA == 'true' ]];then
13771 if [[ ${a_raid_working[6]} != '' ]];then
13772 blocks=${a_raid_working[6]}
13776 blocks=" ${C1}$blocks_avail$SEP3${C2} $blocks"
13778 if [[ ${a_raid_working[9]} != '' ]];then
13779 chunk_size=${a_raid_working[9]}
13783 chunk_size=" ${C1}$chunk_raid_usage$SEP3${C2} $chunk_size"
13784 if [[ ${a_raid_working[10]} != '' ]];then
13785 bitmap_value='true'
13786 bitmap_value=" ${C1}bitmap$SEP3${C2} $bitmap_value"
13789 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
13790 if [[ ${a_raid_working[5]} != '' ]];then
13791 u_data=" ${a_raid_working[5]}"
13793 if [[ ${a_raid_working[7]} != '' ]];then
13794 super_blocks=" ${C1}super blocks$SEP3${C2} ${a_raid_working[7]}"
13796 if [[ ${a_raid_working[8]} != '' ]];then
13797 algorithm=" ${C1}algorithm$SEP3${C2} ${a_raid_working[8]}"
13800 if [[ ${a_raid_working[3]} == '' ]];then
13801 if [[ ${a_raid_working[1]} != 'inactive' ]];then
13802 device_components=" ${C1}components$SEP3${C2} N/A"
13805 for component in ${a_raid_working[3]}
13807 if [[ $B_EXTRA_DATA != 'true' ]];then
13808 component=$( sed 's/\[[0-9]\+\]//' <<< $component )
13810 # NOTE: for bsd zfs, states are: ONLINE,DEGRADED,OFFLINE (at least)
13811 if [[ -n $( grep -E '(F|DEGRADED)' <<< $component ) ]];then
13812 component=$( sed -e 's/(F)//' -e 's/F//' -e 's/DEGRADED//' <<< $component )
13813 failed="$failed $component"
13815 elif [[ -n $( grep -E '(S|OFFLINE)' <<< $component ) ]];then
13816 component=$( sed -e 's/(S)//' -e 's/S//' -e 's/OFFLINE//' <<< $component )
13817 spare="$spare $component"
13820 device_components="$device_components$component_separator$component"
13821 component_separator=' '
13824 if [[ $failed != '' ]];then
13825 failed=" ${C1}FAILED$SEP3${C2}$failed${C2}"
13827 if [[ $spare != '' ]];then
13828 spare=" ${C1}spare$SEP3${C2}$spare${C2}"
13830 if [[ -n $device_components || -n $spare || -n $failed ]];then
13831 if [[ $B_EXTRA_DATA != 'true' && -z $BSD_TYPE ]];then
13832 if [[ $device_report != 'N/A' && -n $device_components ]];then
13833 device_components="$device_report - $device_components"
13836 if [[ $device_components == '' ]];then
13837 device_components='none'
13839 device_components="${C1}online$SEP3${C2} $device_components"
13840 device_components=" ${C1}components$SEP3${C2} $device_components$failed$spare"
13843 a_raid_data[$raid_counter]="${C1}Device$device_id$SEP3${C2} $device$device_state$raid_level$device_components"
13845 if [[ $B_EXTRA_DATA == 'true' && ${a_raid_working[1]} != 'inactive' ]];then
13846 a_raid_data[$raid_counter]="${C1}Device$device_id$SEP3${C2} $device$device_state$device_components"
13847 (( raid_counter++ ))
13848 print_string="${C1}Info$SEP3${C2}$raid_level ${C1}$report_size$SEP3${C2} $device_report$u_data"
13849 print_string="$print_string$blocks$chunk_size$bitmap_value$super_blocks$algorithm"
13850 a_raid_data[$raid_counter]="$print_string"
13852 a_raid_data[$raid_counter]="${C1}Device$device_id$SEP3${C2} $device$device_state$raid_level$device_components"
13854 (( raid_counter++ ))
13856 # now let's do the recover line if required
13857 if [[ ${a_raid_working[12]} != '' ]];then
13858 recovery_percent=$( cut -d '~' -f 2 <<< ${a_raid_working[12]} )
13859 if [[ ${a_raid_working[14]} != '' ]];then
13860 finish_time=${a_raid_working[14]}
13864 finish_time=" ${C1}time remaining$SEP3${C2} $finish_time"
13865 if [[ $B_EXTRA_DATA == 'true' ]];then
13866 if [[ ${a_raid_working[13]} != '' ]];then
13867 recovered_sectors=" ${C1}sectors$SEP3${C2} ${a_raid_working[13]}"
13870 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
13871 if [[ ${a_raid_working[11]} != '' ]];then
13872 recovery_progress_bar=" ${a_raid_working[11]}"
13874 if [[ ${a_raid_working[15]} != '' ]];then
13875 recovery_speed=" ${C1}speed$SEP3${C2} ${a_raid_working[15]}"
13878 a_raid_data[$raid_counter]="${C1}Recovering$SEP3${C2} $recovery_percent$recovery_progress_bar$recovered_sectors$finish_time$recovery_speed"
13879 (( raid_counter++ ))
13882 elif [[ ${a_raid_working[0]} == 'KernelRaidSupport' ]];then
13883 if [[ ${a_raid_working[1]} == '' ]];then
13884 kernel_support='N/A'
13886 kernel_support=${a_raid_working[1]}
13888 kernel_support=" ${C1}supported$SEP3${C2} $kernel_support"
13889 elif [[ ${a_raid_working[0]} == 'ReadAhead' ]];then
13890 if [[ ${a_raid_working[1]} != '' ]];then
13891 read_ahead=${a_raid_working[1]}
13892 read_ahead=" ${C1}read ahead$SEP3${C2} $read_ahead"
13894 elif [[ ${a_raid_working[0]} == 'UnusedDevices' ]];then
13895 if [[ ${a_raid_working[1]} == '' ]];then
13896 unused_devices='N/A'
13898 unused_devices=${a_raid_working[1]}
13900 unused_devices="${C1}Unused Devices$SEP3${C2} $unused_devices"
13901 elif [[ ${a_raid_working[0]} == 'raidEvent' ]];then
13902 if [[ ${a_raid_working[1]} != '' ]];then
13903 raid_event=${a_raid_working[1]}
13904 raid_event=" ${C1}Raid Event$SEP3${C2} ${a_raid_working[1]}"
13909 if [[ $B_SHOW_BASIC_RAID == 'true' && $basic_raid != '' ]];then
13910 a_raid_data[0]="${C1}Device$basic_raid_plural$SEP3${C2} $basic_raid"
13912 # note bsd temp test hack to make it run
13913 if [[ $B_MDSTAT_FILE != 'true' && -z $BSD_TYPE ]] || \
13914 [[ -n $BSD_TYPE && $B_BSD_RAID == 'false' ]];then
13915 if [[ $B_SHOW_RAID_R == 'true' ]];then
13916 a_raid_data[0]="$no_raid_detected"
13918 b_print_lines='false'
13921 if [[ ${a_raid_data[0]} == '' ]];then
13922 if [[ $B_SHOW_BASIC_RAID != 'true' ]];then
13923 a_raid_data[0]="$empty_raid_data"
13925 b_print_lines='false'
13928 # now let's add on the system line and the unused device line. Only print on -xx
13929 if [[ $kernel_support$read_ahead$raid_event != '' ]];then
13930 array_count=${#a_raid_data[@]}
13931 a_raid_data[array_count]="${C1}System$SEP3${C2}$kernel_support$read_ahead$raid_event"
13934 if [[ $unused_devices != '' ]];then
13935 array_count_unused=${#a_raid_data[@]}
13936 a_raid_data[array_count_unused]="$unused_devices"
13941 # we don't want to print anything if it's -b and no data is present, just a waste of a line
13942 if [[ $b_print_lines == 'true' ]];then
13943 # print out all lines, line starter on first line
13944 for (( i=0; i < ${#a_raid_data[@]} - $loop_limit;i++ ))
13946 if [[ $i -eq 0 ]];then
13947 line_starter='RAID:'
13951 if [[ $B_EXTRA_EXTRA_DATA == 'true' && $array_count != '' ]];then
13952 if [[ $i == 0 ]];then
13953 raid_data=$( create_print_line "$line_starter" "${a_raid_data[array_count]}" )
13954 print_screen_output "$raid_data"
13958 raid_data=$( create_print_line "$line_starter" "${a_raid_data[i]}" )
13959 print_screen_output "$raid_data"
13960 if [[ $B_EXTRA_EXTRA_DATA == 'true' && $array_count_unused != '' ]];then
13961 if [[ $i == $(( array_count_unused - 2 )) ]];then
13962 raid_data=$( create_print_line "$line_starter" "${a_raid_data[array_count_unused]}" )
13963 print_screen_output "$raid_data"
13975 local memory_line='' line_2='' line_3='' b_module_present='true'
13976 local error_string='' a_memory_item='' line_starter='Memory:' array_counter=1 device_counter=1
13977 local dmidecodeNull='No dmidecode memory data: try newer kernel.'
13979 local manufacturer='' part_nu='' serial_nu='' device_speed='' configured_speed='' bus_width=
13980 local data_width='' total_width='' device_type='' device_type_detail='' bank='' slot='' form_factor=''
13981 local device_size='' array_use='' location='' error_correction='' max_capacity='' nu_of_devices=''
13982 local max_module_size='' module_voltage='' bank_connection=''
13985 #echo ${#A_MEMORY_DATA[@]}
13986 #echo ${A_MEMORY_DATA[0]}
13987 if [[ ${#A_MEMORY_DATA[@]} -gt 0 ]];then
13988 if [[ ${A_MEMORY_DATA[0]} == 'dmidecode-error-'* ]];then
13989 error_string=$( print_dmidecode_error 'default' "${A_MEMORY_DATA[0]}" )
13990 memory_line="${C2}$error_string"
13992 for (( i=0;i<${#A_MEMORY_DATA[@]};i++ ))
13995 a_memory_item=(${A_MEMORY_DATA[i]})
13996 IFS="$ORIGINAL_IFS"
14009 # memory-array,0x0012,System Board,8 GB,4,System Memory,None,max size,moudule voltage
14010 if [[ ${a_memory_item[0]} == 'memory-array' ]];then
14011 if [[ -n ${a_memory_item[4]} ]];then
14012 nu_of_devices=${a_memory_item[4]}
14014 nu_of_devices='N/A'
14016 if [[ -n ${a_memory_item[3]} ]];then
14017 max_capacity=${a_memory_item[3]}
14021 if [[ -n ${a_memory_item[6]} ]];then
14022 error_correction=${a_memory_item[6]}
14024 error_correction='N/A'
14026 if [[ $B_EXTRA_DATA == 'true' ]];then
14027 if [[ -n ${a_memory_item[7]} ]];then
14028 max_module_size="${C1}max module size${SEP3}${C2} ${a_memory_item[7]} "
14031 if [[ $B_EXTRA_EXTRA_EXTRA_DATA == 'true' ]];then
14032 if [[ -n ${a_memory_item[8]} ]];then
14033 module_voltage="${C1}module voltage$SEP3${C2} ${a_memory_item[8]}"
14036 memory_line="${C1}Array-$array_counter capacity$SEP3${C2} $max_capacity ${C1}devices$SEP3${C2} $nu_of_devices ${C1}EC$SEP3${C2} $error_correction "
14037 line_2="$max_module_size$module_voltage"
14038 if [[ -n $line_2 && $( calculate_line_length "$memory_line$line_2" ) -gt $COLS_INNER ]];then
14039 memory_line=$( create_print_line "$line_starter" "$memory_line" )
14040 print_screen_output "$memory_line"
14041 memory_line="$line_2"
14045 memory_line="$memory_line$line_2"
14048 (( array_counter++ ))
14049 device_counter=1 # reset so device matches device count per array
14052 # if [[ -n ${a_memory_item[3333]} ]];then
14053 # if [[ -z ${a_memory_item[3]/BANK*/} ]];then
14054 # #bank=${a_memory_item[3]#BANK}
14055 # bank=${a_memory_item[3]}
14058 # bank=${a_memory_item[3]}
14063 # # not used for now
14064 # if [[ -n ${a_memory_item[44444]} ]];then
14065 # if [[ -z ${a_memory_item[4]/SLOT*/} ]];then
14066 # #slot=${a_memory_item[4]#SLOT}
14067 # slot=${a_memory_item[4]}
14070 # slot=${a_memory_item[4]}
14075 if [[ -n ${a_memory_item[15]} ]];then
14076 locator=${a_memory_item[15]}
14077 locator=${locator## }
14081 if [[ -n ${a_memory_item[2]} ]];then
14082 device_size=${a_memory_item[2]}
14083 if [[ $device_size == 'No Module Installed' ]];then
14084 b_module_present='false'
14086 b_module_present='true'
14091 if [[ -n ${a_memory_item[6]} ]];then
14092 device_type=${a_memory_item[6]}
14093 if [[ $B_EXTRA_EXTRA_EXTRA_DATA == 'true' && -n ${a_memory_item[7]} \
14094 && ${a_memory_item[7]} != 'Other' ]];then
14095 device_type="$device_type (${a_memory_item[7]})"
14100 device_type="${C1}type$SEP3${C2} $device_type "
14101 if [[ -n ${a_memory_item[8]} ]];then
14102 if [[ -n ${a_memory_item[9]} ]];then
14103 device_speed=${a_memory_item[9]}
14105 device_speed=${a_memory_item[8]}
14110 if [[ $b_module_present == 'true' ]];then
14111 device_speed="${C1}speed$SEP3${C2} $device_speed "
14115 # memory-device,0x002C,8192 MB,ChannelD,ChannelD_Dimm2,DIMM,DDR3,Synchronous,2400 MHz,2400 MHz,64 bits,64 bits,Undefined,F3-19200C10-8GBZH,00000000
14116 if [[ $b_module_present == 'true' ]];then
14117 if [[ $B_EXTRA_DATA == 'true' ]];then
14118 if [[ -n ${a_memory_item[13]} ]];then
14119 part_nu=${a_memory_item[13]}
14123 part_nu="${C1}part$SEP3${C2} $part_nu "
14125 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
14126 if [[ -n ${a_memory_item[12]} ]];then
14127 manufacturer=${a_memory_item[12]}
14131 manufacturer="${C1}manufacturer$SEP3${C2} $manufacturer "
14132 if [[ -n ${a_memory_item[14]} ]];then
14133 serial_nu=${a_memory_item[14]}
14137 serial_nu="${C1}serial$SEP3${C2} $serial_nu "
14139 if [[ $device_size != 'N/A' && -n ${a_memory_item[16]} ]];then
14140 bank_connection=" ${a_memory_item[16]}"
14144 if [[ $B_EXTRA_EXTRA_EXTRA_DATA == 'true' ]];then
14145 if [[ $b_module_present == 'true' ]] || \
14146 [[ -n ${a_memory_item[11]} || -n ${a_memory_item[10]} ]];then
14147 # only create this if the total exists and is > data width
14148 if [[ -n ${a_memory_item[10]/ bits/} && -n ${a_memory_item[11]/ bits} && \
14149 ${a_memory_item[11]/ bits/} -gt ${a_memory_item[10]/ bits/} ]];then
14150 total_width=" (total$SEP3 ${a_memory_item[11]})"
14152 if [[ -n ${a_memory_item[10]} ]];then
14153 data_width=${a_memory_item[10]}
14157 bus_width="${C1}bus width$SEP3${C2} $data_width$total_width "
14160 memory_line="${C1}Device-$device_counter$SEP3${C2} $locator ${C1}size$SEP3${C2} $device_size$bank_connection $device_speed"
14161 if [[ $( calculate_line_length "$memory_line$device_type" ) -le $COLS_INNER ]];then
14162 memory_line="$memory_line$device_type"
14165 line_3="$manufacturer$part_nu$serial_nu"
14166 line_2="$device_type$bus_width"
14167 # echo $( calculate_line_length "$memory_line" )
14168 # echo $( calculate_line_length "$memory_line$line_2" )
14169 if [[ $( calculate_line_length "$memory_line$line_2$line_3" ) -gt $COLS_INNER ]];then
14170 memory_line=$( create_print_line "$line_starter" "$memory_line" )
14171 print_screen_output "$memory_line"
14172 memory_line="$line_2"
14174 if [[ -n $memory_line && -n $line_3 && $( calculate_line_length "$memory_line$line_3" ) -gt $COLS_INNER ]];then
14175 memory_line=$( create_print_line "$line_starter" "$memory_line" )
14176 print_screen_output "$memory_line"
14177 memory_line="$line_3"
14179 memory_line="$memory_line$line_3"
14182 memory_line="$memory_line$line_2$line_3"
14184 (( device_counter++ ))
14186 memory_line=$( create_print_line "$line_starter" "$memory_line" )
14187 print_screen_output "$memory_line"
14193 memory_line="${C2}$dmidecodeNull"
14195 IFS="$ORIGINAL_IFS"
14196 memory_line=${memory_line## }
14197 if [[ -n $memory_line ]];then
14198 memory_line=$( create_print_line "$line_starter" "$memory_line" )
14199 print_screen_output "$memory_line"
14206 # currently only apt using distros support this feature, but over time we can add others
14210 local repo_count=0 repo_line='' file_name='' file_content='' file_name_holder=''
14211 local repo_full='' b_print_next_line='false' repo_type=''
14215 if [[ -n $REPO_DATA ]];then
14216 # loop through the variable's lines one by one, update counter each iteration
14217 while read repo_line
14220 repo_type=$( cut -d '^' -f 1 <<< $repo_line )
14221 file_name=$( cut -d '^' -f 2 <<< $repo_line )
14222 file_content=$( cut -d '^' -f 3-7 <<< $repo_line )
14223 # this will dump unwanted white space line starters. Some irc channels
14224 # use bots that show page title for urls, so need to break the url by adding
14226 if [[ $B_IRC == 'true' ]];then
14227 file_content=$( echo ${file_content/:\/\//: \/\/} )
14229 file_content=$( echo $file_content )
14231 # echo $file_name : $file_name_holder : $repo_type : $file_content
14232 # check file name, if different, update the holder for print out
14233 if [[ $file_name != $file_name_holder ]];then
14234 if [[ $repo_type == 'pisi repo' || $repo_type == 'urpmq repo' ]];then
14235 repo_full="${C1}$repo_type$SEP3${C2} $file_name"
14237 repo_full="${C1}Active $repo_type in file$SEP3${C2} $file_name"
14239 file_name_holder=$file_name
14240 b_print_next_line='true'
14242 repo_full="${C2}$file_content"
14244 # first line print Repos:
14245 if [[ $repo_count -eq 1 ]];then
14246 repo_full=$( create_print_line "Repos:" "$repo_full" )
14248 repo_full=$( create_print_line " " "$repo_full" )
14250 print_screen_output "$repo_full"
14251 # this prints the content of the file as well as the file name
14252 if [[ $b_print_next_line == 'true' ]];then
14253 repo_full=$( create_print_line " " "$file_content" )
14254 print_screen_output "$repo_full"
14255 b_print_next_line='false'
14257 done <<< "$REPO_DATA"
14259 if [[ $BSD_TYPE == 'bsd' ]];then
14260 repo_type='OS type'
14262 repo_type="package manager"
14264 repo_full=$( create_print_line "Repos:" "${C1}Error$SEP3${C2} No repo data detected. Does $SCRIPT_NAME support your $repo_type?" )
14265 print_screen_output "$repo_full"
14270 print_sensors_data()
14273 local mobo_temp='' cpu_temp='' psu_temp='' cpu_fan='' mobo_fan='' ps_fan='' sys_fans='' sys_fans2=''
14274 local temp_data='' fan_data='' fan_data2='' b_is_error='false' fan_count=0 gpu_temp=''
14275 local a_sensors_working=''
14276 local no_sensors_message='None detected - is lm-sensors installed and configured?'
14277 local Sensors_Data="$( get_sensors_output )"
14280 if [[ $BSD_TYPE == 'bsd' ]];then
14281 no_sensors_message='This feature is not yet supported for BSD systems.'
14285 a_sensors_working=( ${A_SENSORS_DATA[0]} )
14286 IFS="$ORIGINAL_IFS"
14287 # initial error cases, for missing app or unconfigured sensors. Note that array 0
14288 # always has at least 3 items, cpu/mobo/psu temp in it. If the count is 0, then
14289 # no sensors are installed/configured
14290 if [[ ${#a_sensors_working[@]} -eq 0 ]];then
14291 cpu_temp=$no_sensors_message
14294 for (( i=0; i < ${#A_SENSORS_DATA[@]}; i++ ))
14297 a_sensors_working=( ${A_SENSORS_DATA[i]} )
14298 IFS="$ORIGINAL_IFS"
14300 # first the temp data
14302 if [[ -n ${a_sensors_working[0]} ]];then
14303 cpu_temp=${a_sensors_working[0]}
14307 cpu_temp="${C1}System Temperatures: cpu$SEP3${C2} $cpu_temp "
14309 if [[ -n ${a_sensors_working[1]} ]];then
14310 mobo_temp=${a_sensors_working[1]}
14314 mobo_temp="${C1}mobo$SEP3${C2} $mobo_temp "
14316 if [[ -n ${a_sensors_working[2]} ]];then
14317 psu_temp="${C1}psu$SEP3${C2} ${a_sensors_working[2]} "
14319 gpu_temp=$( get_gpu_temp_data )
14320 # dump the unneeded screen data for single gpu systems
14321 if [[ $( wc -w <<< $gpu_temp ) -eq 1 && $B_EXTRA_DATA != 'true' ]];then
14322 gpu_temp=${gpu_temp#*:}
14324 if [[ -n $gpu_temp ]];then
14325 gpu_temp="${C1}gpu$SEP3${C2} $gpu_temp "
14328 # then the fan data from main fan array
14330 for (( j=0; j < ${#a_sensors_working[@]}; j++ ))
14334 # we need to make sure it's either cpu fan OR cpu fan and sys fan 1
14335 if [[ -n ${a_sensors_working[0]} ]];then
14336 cpu_fan="${a_sensors_working[0]}"
14337 elif [[ -z ${a_sensors_working[0]} && -n ${a_sensors_working[1]} ]];then
14338 cpu_fan="${a_sensors_working[1]}"
14342 cpu_fan="${C1}Fan Speeds (in rpm): cpu$SEP3${C2} $cpu_fan "
14346 if [[ -n ${a_sensors_working[1]} ]];then
14347 mobo_fan="${C1}mobo$SEP3${C2} ${a_sensors_working[1]} "
14352 if [[ -n ${a_sensors_working[2]} ]];then
14353 ps_fan="${C1}psu$SEP3${C2} ${a_sensors_working[2]} "
14358 if [[ -n ${a_sensors_working[$j]} ]];then
14359 fan_number=$(( $j - 2 )) # sys fans start on array key 5
14360 # wrap after fan 6 total
14361 if [[ $fan_count -lt 7 ]];then
14362 sys_fans="$sys_fans${C1}sys-$fan_number$SEP3${C2} ${a_sensors_working[$j]} "
14364 sys_fans2="$sys_fans2${C1}sys-$fan_number$SEP3${C2} ${a_sensors_working[$j]} "
14373 for (( j=0; j < ${#a_sensors_working[@]}; j++ ))
14377 if [[ -n ${a_sensors_working[$j]} ]];then
14378 fan_number=$(( $j + 1 )) # sys fans start on array key 5
14379 # wrap after fan 6 total
14380 if [[ $fan_count -lt 7 ]];then
14381 sys_fans="$sys_fans${C1}fan-$fan_number$SEP3${C2} ${a_sensors_working[$j]} "
14383 sys_fans2="$sys_fans2${C1}fan-$fan_number$SEP3${C2} ${a_sensors_working[$j]} "
14394 # turning off all output for case where no sensors detected or no sensors output
14395 # unless -s used explicitly. So for -F type output won't show unless valid or -! 1 used
14396 if [[ $b_is_error != 'true' || $B_SHOW_SENSORS == 'true' || $B_TESTING_1 == 'true' ]];then
14397 temp_data="$cpu_temp$mobo_temp$psu_temp$gpu_temp"
14398 temp_data=$( create_print_line "Sensors:" "$temp_data" )
14399 print_screen_output "$temp_data"
14400 # don't print second or subsequent lines if error data
14401 fan_data="$cpu_fan$mobo_fan$ps_fan$sys_fans"
14402 if [[ $b_is_error != 'true' && -n $fan_data ]];then
14403 fan_data=$( create_print_line " " "$fan_data" )
14404 print_screen_output "$fan_data"
14405 # and then second wrapped fan line if needed
14406 if [[ -n $sys_fans2 ]];then
14407 fan_data2=$( create_print_line " " "$sys_fans2" )
14408 print_screen_output "$fan_data2"
14415 print_system_data()
14418 local system_data='' bits='' desktop_environment='' dm_data='' de_extra_data=''
14419 local de_string='' distro_string='' line_starter='System:'
14420 local host_kernel_string='' host_string='' desktop_type='Desktop'
14421 local host_name=$HOSTNAME
14422 local current_kernel=$( get_kernel_version )
14423 local distro="$( get_distro_data )"
14424 local tty_session='' compiler_string='' distro_os='Distro'
14426 if [[ -n $BSD_TYPE ]];then
14430 # I think these will work, maybe, if logged in as root and in X
14431 if [[ $B_RUNNING_IN_DISPLAY == 'true' ]];then
14432 desktop_environment=$( get_desktop_environment )
14433 if [[ -z $desktop_environment ]];then
14434 desktop_environment='N/A'
14437 if [[ $B_EXTRA_EXTRA_EXTRA_DATA == 'true' ]];then
14438 de_extra_data=$( get_desktop_extra_data )
14439 if [[ -n $de_extra_data ]];then
14440 de_extra_data=" ${C1}info$SEP3${C2} $de_extra_data"
14444 tty_session=$( get_tty_number )
14445 if [[ -z $tty_session && $B_CONSOLE_IRC == 'true' ]];then
14446 tty_session=$( get_tty_console_irc )
14448 if [[ -n $tty_session ]];then
14449 tty_session=" $tty_session"
14451 desktop_environment="tty$tty_session"
14452 desktop_type='Console'
14454 # having dm type can be useful if you are accessing remote system
14455 # or are out of X and don't remember which dm is running the system
14456 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
14457 dm_data=$( get_display_manager )
14458 # here we only want the dm info to show N/A if in X
14459 if [[ -z $dm_data && $B_RUNNING_IN_DISPLAY == 'true' ]];then
14462 # only print out of X if dm_data has info, then it's actually useful, but
14463 # for headless servers, no need to print dm stuff.
14464 if [[ -n $dm_data ]];then
14465 dm_data=" ${C1}dm$SEP3${C2} $dm_data"
14468 if [[ $B_EXTRA_DATA == 'true' ]];then
14469 compiler_string=$( get_kernel_compiler_version )
14470 if [[ -n $compiler_string ]];then
14471 compiler_string=" ${C1}${compiler_string%^*}$SEP3${C2} ${compiler_string#*^}"
14474 # check for 64 bit first
14475 if [[ -n $( uname -m | grep -E '(x86_64|amd64)' ) ]];then
14480 bits=" ($bits bit$compiler_string)"
14481 if [[ $B_SHOW_HOST == 'true' ]];then
14482 if [[ -z $HOSTNAME ]];then
14483 if [[ -n $( type p hostname ) ]];then
14484 host_name=$( hostname )
14486 if [[ -z $host_name ]];then
14490 host_string="${C1}Host$SEP3${C2} $host_name "
14492 host_kernel_string="$host_string${C1}Kernel$SEP3${C2} $current_kernel$bits "
14493 de_string="${C1}$desktop_type$SEP3${C2} $desktop_environment$de_extra_data$dm_data "
14494 distro_string="${C1}$distro_os$SEP3${C2} $distro "
14496 if [[ $( calculate_line_length "$host_kernel_string$de_string" ) -gt $COLS_INNER ]];then
14497 system_data=$( create_print_line "$line_starter" "$host_kernel_string" )
14498 print_screen_output "$system_data"
14499 host_kernel_string=''
14502 if [[ $( calculate_line_length "$host_kernel_string$de_string$distro_string" ) -gt $COLS_INNER ]];then
14503 system_data=$( create_print_line "$line_starter" "$host_kernel_string$de_string" )
14504 print_screen_output "$system_data"
14505 host_kernel_string=''
14509 system_data="$host_kernel_string$de_string$distro_string"
14510 if [[ -n $system_data ]];then
14511 system_data="$host_kernel_string$de_string$distro_string"
14512 system_data=$( create_print_line "$line_starter" "$system_data" )
14513 print_screen_output "$system_data"
14519 print_unmounted_partition_data()
14522 local a_unmounted_data='' line_starter='' unmounted_data='' full_fs=''
14523 local full_dev='' full_size='' full_label='' full_uuid='' full_string=''
14524 local bsd_unsupported='This feature is not yet supported for BSD systems.'
14525 local line_starter='Unmounted:' part_2_data=''
14527 if [[ -z ${A_PARTITION_DATA} ]];then
14530 get_unmounted_partition_data
14531 if [[ ${#A_UNMOUNTED_PARTITION_DATA[@]} -ge 1 ]];then
14532 for (( i=0; i < ${#A_UNMOUNTED_PARTITION_DATA[@]}; i++ ))
14537 a_unmounted_data=(${A_UNMOUNTED_PARTITION_DATA[i]})
14538 IFS="$ORIGINAL_IFS"
14539 if [[ -z ${a_unmounted_data[0]} ]];then
14542 full_dev="/dev/${a_unmounted_data[0]}"
14544 full_dev="${C1}ID-$((i+1))$SEP3${C2} $full_dev "
14545 if [[ -z ${a_unmounted_data[1]} ]];then
14548 full_size=${a_unmounted_data[1]}
14550 full_size="${C1}size$SEP3${C2} $full_size "
14551 if [[ -z ${a_unmounted_data[2]} ]];then
14554 full_label=${a_unmounted_data[2]}
14556 full_label="${C1}label$SEP3${C2} $full_label "
14557 if [[ -z ${a_unmounted_data[3]} ]];then
14560 full_uuid=${a_unmounted_data[3]}
14562 full_uuid="${C1}uuid$SEP3${C2} $full_uuid "
14563 if [[ -z ${a_unmounted_data[4]} ]];then
14566 full_fs="${C1}fs$SEP3${C2} ${a_unmounted_data[4]} "
14568 # temporary message to indicate not yet supported
14569 if [[ $BSD_TYPE == 'bsd' ]];then
14570 full_string=$bsd_unsupported
14572 full_string="$full_dev$full_size"
14573 part_2_data="$full_fs$full_label$full_uuid"
14575 if [[ $( calculate_line_length "$full_string$part_2_data" ) -gt $COLS_INNER ]];then
14576 unmounted_data=$( create_print_line "$line_starter" "$full_string" )
14577 print_screen_output "$unmounted_data"
14579 unmounted_data=$( create_print_line "$line_starter" "$part_2_data" )
14580 print_screen_output "$unmounted_data"
14582 unmounted_data=$( create_print_line "$line_starter" "$full_string$part_2_data" )
14583 print_screen_output "$unmounted_data"
14588 unmounted_data=$( create_print_line "$line_starter" "No unmounted partitions detected" )
14589 print_screen_output "$unmounted_data"
14595 print_weather_data()
14599 local weather_data='' location_string='' local_time='' time_string='' pressure=''
14600 local a_location='' a_weather='' weather_string='' weather='' temp='' winds='' humidity=''
14601 local time_zone='' observation_time='' city='' state='' country='' altitude=''
14602 local heat_index='' wind_chill='' dewpoint='' xxx_humidity=''
14603 local openP='(' closeP=')'
14605 if [[ $B_IRC == 'true' ]];then
14612 # city ";" regionCode ";" regionName ";" countryName ";" countryCode ";" countryCode3
14613 # ";" latitude "," longitude ";" postalCode ";" timeZone
14615 # observationTime ";" localTime ";" weather ";" tempString ";" humidity
14616 # ";" windString ";" pressureString ";" dewpointString ";" heatIndexString
14617 # ";" windChillString ";" siteElevation
14619 if [[ ${#A_WEATHER_DATA[@]} -eq 2 ]];then
14621 a_location=(${A_WEATHER_DATA[0]})
14622 a_weather=(${A_WEATHER_DATA[1]})
14623 IFS="$ORIGINAL_IFS"
14625 if [[ -n ${a_weather[3]} ]];then
14626 temp=${a_weather[3]}
14630 if [[ -n ${a_weather[2]} ]];then
14631 weather=" - ${a_weather[2]}"
14635 if [[ $B_EXTRA_DATA == 'true' ]];then
14636 if [[ -n ${a_weather[5]} ]];then
14637 winds=" ${C1}Wind$SEP3${C2} ${a_weather[5]}"
14640 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
14641 if [[ -n ${a_weather[4]} ]];then
14642 humidity=" ${C1}Humidity$SEP3${C2} ${a_weather[4]}"
14644 if [[ -n ${a_weather[6]} ]];then
14645 pressure="${C1}Pressure$SEP3${C2} ${a_weather[6]} "
14648 weather_string="${C1}Conditions$SEP3${C2} $temp$weather$winds$humidity"
14650 if [[ -n ${a_weather[1]} ]];then
14651 local_time=" ${a_weather[1]}"
14653 local_time=" $(date)"
14655 if [[ $B_EXTRA_DATA == 'true' && -n ${a_location[8]} ]];then
14656 time_zone=" (${a_location[8]})"
14658 time_string="${C1}Time$SEP3${C2}$local_time$time_zone"
14660 if [[ $B_EXTRA_DATA != 'true' ]];then
14661 weather_data="$weather_string $time_string"
14662 weather_data=$( create_print_line "Weather:" "$weather_data" )
14663 print_screen_output "$weather_data"
14665 weather_data="$weather_string"
14666 weather_data=$( create_print_line "Weather:" "$weather_data" )
14667 print_screen_output "$weather_data"
14668 if [[ $B_EXTRA_EXTRA_EXTRA_DATA == 'true' ]];then
14669 if [[ -n ${a_weather[8]} ]];then
14670 heat_index="${C1}Heat Index$SEP3${C2} ${a_weather[8]} "
14672 if [[ -n ${a_weather[9]} ]];then
14673 wind_chill="${C1}Wind Chill$SEP3${C2} ${a_weather[9]} "
14675 if [[ -n ${a_weather[7]} ]];then
14676 dew_point="${C1}Dew Point$SEP3${C2} ${a_weather[7]} "
14678 if [[ -n ${a_weather[0]} ]];then
14679 observation_time=" ${C1}Observation Time$SEP3${C2} ${a_weather[0]} "
14681 if [[ $B_OUTPUT_FILTER != 'true' ]];then
14682 if [[ -n ${a_location[0]} ]];then
14683 city=" ${a_location[0]}"
14685 if [[ -n ${a_location[1]} ]];then
14686 state=" ${a_location[1]}"
14688 if [[ -n ${a_location[5]} ]];then
14689 country=" $openP${a_location[5]}$closeP"
14691 if [[ -n ${a_weather[10]} ]];then
14692 altitude=" ${C1}Altitude$SEP3${C2} ${a_weather[10]}"
14694 location_string="${C1}Location$SEP3${C2}$city$state$country$altitude "
14696 location_string=$time_string$observation_time
14698 observation_time=''
14700 # the last three are oftenblank
14701 if [[ -z "$heat_index$wind_chill$dew_point" ]];then
14702 weather_data=$( create_print_line " " "$pressure$location_string" )
14703 print_screen_output "$weather_data"
14705 weather_data=$( create_print_line " " "$pressure$heat_index$wind_chill$dew_point" )
14706 print_screen_output "$weather_data"
14707 if [[ $B_OUTPUT_FILTER != 'true' ]];then
14708 weather_data=$( create_print_line " " "$location_string" )
14709 print_screen_output "$weather_data"
14712 if [[ -n $time_string$observation_time ]];then
14713 weather_data=$( create_print_line " " "$time_string$observation_time" )
14714 print_screen_output "$weather_data"
14717 if [[ -n $pressure$time_string ]];then
14718 weather_data="$pressure$time_string"
14719 weather_data=$( create_print_line " " "$weather_data" )
14720 print_screen_output "$weather_data"
14725 weather_data=$( create_print_line "Weather:" "${C2}Weather data failure: $(date)" )
14726 print_screen_output "$weather_data"
14727 weather_data=$( create_print_line " " "${C2}${A_WEATHER_DATA}" )
14728 print_screen_output "$weather_data"
14733 ########################################################################
14734 #### SCRIPT EXECUTION
14735 ########################################################################
14737 main $@ ## From the End comes the Beginning
14739 ## note: this EOF is needed for smxi handling, this is what triggers the full download ok