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-2014 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/svn: http://inxi.googlecode.com
29 #### Script forums: http://techpatterns.com/forums/forum-33.html
30 #### IRC support: irc.oftc.net channel #smxi
32 #### This program is free software; you can redistribute it and/or modify
33 #### it under the terms of the GNU General Public License as published by
34 #### the Free Software Foundation; either version 3 of the License, or
35 #### (at your option) any later version.
37 #### This program is distributed in the hope that it will be useful,
38 #### but WITHOUT ANY WARRANTY; without even the implied warranty of
39 #### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 #### GNU General Public License for more details.
42 #### You should have received a copy of the GNU General Public License
43 #### along with this program. If not, see <http://www.gnu.org/licenses/>.
45 #### If you don't understand what Free Software is, please read (or reread)
46 #### this page: http://www.gnu.org/philosophy/free-sw.html
47 ########################################################################
48 #### * Package names in (...) are the Debian Squeeze package name. Check your
49 #### distro for proper package name by doing this: which <application>
50 #### then find what package owns that application file. Or run --recommends
51 #### which shows package names for Debian/Ubuntu, Arch, and Fedora/Redhat/Suse
54 #### * bash >=3.0 (bash); df, readlink, stty, tr, uname, wc (coreutils);
55 #### gawk (gawk); grep (grep); lspci (pciutils);
56 #### ps, uptime (procps); find (findutils)
57 #### * Also the proc filesystem should be present and mounted
58 #### * Some features, like -M and -d will not work, or will work incompletely,
59 #### if /sys is missing
61 #### Apparently unpatched bash 3.0 has arrays broken; bug reports:
62 #### http://ftp.gnu.org/gnu/bash/bash-3.0-patches/bash30-008
63 #### http://lists.gnu.org/archive/html/bug-bash/2004-08/msg00144.html
64 #### Bash 3.1 for proper array use
66 #### Arrays work in bash 2.05b, but "grep -Em" does not
68 #### RECOMMENDS (Needed to run certain features, listed by option)
69 #### -A - for output of usb audio information: lsusb (usbutils)
70 #### -Ax -Nx - for audio/network module version: modinfo (module-init-tools)
71 #### -Dx - for hdd temp output (root only default): hddtemp (hddtemp)
72 #### For user level hdd temp output: sudo (sudo)
73 #### Note: requires user action for this feature to run as user (edit /etc/sudoers file)
74 #### -G - full graphics output requires: glxinfo (mesa-utils); xdpyinfo (X11-utils);
75 #### xrandr (x11-xserver-utils)
76 #### -i - IP information, local/wan - ip (iproute) legacy, not used if ip present: ifconfig (net-tools)
77 #### -Ix - view current runlevel while not in X window system (or with -x): runlevel (sysvinit)
78 #### -M - for older systems whose kernel does not have /sys data for machine, dmidecode (dmidecode)
79 #### -o - for unmounted file system information in unmounted drives (root only default): file (file)
80 #### Note: requires user action for this feature to run as user (edit /etc/sudoers file)
81 #### For user level unmounted file system type output: sudo (sudo)
82 #### -s For any sensors output, fan, temp, etc: sensors (lm-sensors)
83 #### Note: requires setup of lm-sensors (sensors-detect and adding modules/modprobe/reboot,
84 #### and ideally, pwmconfig) prior to full output being available.
85 #### -S For desktop environment, user must be in X and have xprop installed (in X11-utils)
86 ########################################################################
88 #### * sed -i '' form supported by using SED_I="-i ''".
89 #### * Note: New BSD sed supports using -r instead of -E for compatibility with gnu sed
90 #### However, older, like FreeBSD 7.x, does not have -r so using SED_RX='-E' for this.
91 #### * Gnu grep options can be used if the function component is only run in linux
92 #### These are the options that bsd grep does not support that inxi uses: -m <number> -o
93 #### so make sure if you use those to have them in gnu/linux only sections.
94 #### It appears that freebsd uses gnu grep but openbsd uses bsd grep, however.
95 #### * BSD ps does not support --without-headers option, and also does not support --sort <option>
96 #### Tests show that -m fails to sort memory as expected, but -r does sort cpu percentage.
97 #### * BSD_TYPE is set with values null, debian-bsd (debian gnu/kfreebsd), bsd (all other bsds)
98 #### * Subshell and array closing ) must not be on their own line unless you use an explicit \
99 #### to indicate that logic continues to next line where closing ) or )) are located.
100 ########################################################################
102 #### * Character Encoding: UTF-8 - this file contains special characters that must be opened and saved as UTF8
103 #### * Indentation: TABS
104 #### * Do not use `....` (back quotes), those are totally non-reabable, use $(....).
105 #### * Do not use one liner flow controls.
106 #### The ONLY time you should use ';' (semi-colon) is in this single case: if [[ condition ]];then.
107 #### Never use compound 'if': ie, if [[ condition ]] && statement.
108 #### * Note: [[ -n $something ]] - double brackets does not require quotes for variables: ie, "$something".
109 #### * Always use quotes, double or single, for all string values.
110 #### * All new code/methods must be in a function.
111 #### * For all boolean tests, use 'true' / 'false'.
112 #### !! Do NOT use 0 or 1 unless it's a function return.
113 #### * Avoid complicated tests in the if condition itself.
114 #### * To 'return' a value in a function, use 'echo <var>'.
115 #### * For gawk: use always if ( num_of_cores > 1 ) { hanging { starter for all blocks
116 #### This lets us use one method for all gawk structures, including BEGIN/END, if, for, etc
118 #### VARIABLE/FUNCTION NAMING:
119 #### * All functions should follow standard naming--verb adjective noun.
120 #### ie, get_cpu_data
121 #### * All variables MUST be initialized / declared explicitly, either top of file, for Globals, or using local
122 #### * All variables should clearly explain what they are, except counters like i, j.
123 #### * Each word of Bash variable must be separated by '_' (underscore) (camel form), like: cpu_data
124 #### * Each word of Gawk variable must be like this (first word lower, following start with upper): cpuData
125 #### * Global variables are 'UPPER CASE', at top of this file.
126 #### ie, SOME_VARIABLE=''
127 #### * Local variables are 'lower case' and declared at the top of the function using local, always.
128 #### ie: local some_variable=''
129 #### * Locals that will be inherited by child functions have first char capitalized (so you know they are inherited).
130 #### ie, Some_Variable
131 #### * Booleans should start with b_ (local) or B_ (global) and state clearly what is being tested.
132 #### * Arrays should start with a_ (local) or A_ (global).
135 #### * The color variable ${C2} must always be followed by a space unless you know what
136 #### character is going to be next for certain. Otherwise irc color codes can be accidentally
137 #### activated or altered.
138 #### * For native script konversation support (check distro for correct konvi scripts path):
139 #### ln -s <path to inxi> /usr/share/apps/konversation/scripts/inxi
140 #### DCOP doesn't like \n, so avoid using it for most output unless required, as in error messages.
141 #### * print_screen_output " " # requires space, not null, to avoid error in for example in irssi
142 #### * For logging of array data, array must be placed into the temp_array, otherwise only the first key logs
143 #### * In gawk search patterns, . is a wildcard EXCEPT in [0-9.] type containers, then it's a literal
144 #### So outside of bracketed items, it must be escaped, \. but inside, no need. Outside of gawk it should
145 #### be escaped in search patterns if you are using it as a literal.
147 #### PACKAGE MANAGER DATA (note, while inxi tries to avoid using package managers to get data, sometimes
148 #### it's the only way to get some data):
149 #### * dpkg options: http://www.cyberciti.biz/howto/question/linux/dpkg-cheat-sheet.php
150 #### * pacman options: https://wiki.archlinux.org/index.php/Pacman_Rosetta
152 #### As with all 'rules' there are acceptions, these are noted where used.
153 ###################################################################################
154 #### KDE Konversation information. Moving from dcop(qt3/KDE3) to dbus(qt4/KDE4)
155 ###################################################################################
156 #### * dcop and dbus -- these talk back to Konversation from this program
157 #### * Scripting info -- http://konversation.berlios.de/docs/scripting.html
158 #### -- http://www.kde.org.uk/apps/konversation/
159 #### * dbus info -- http://dbus.freedesktop.org/doc/dbus-tutorial.html
160 #### view dbus info -- https://fedorahosted.org/d-feet/
162 #### * Konvi dbus/usage-- qdbus org.kde.konversation /irc say <server> <target-channel> <output>
163 #### * Python usage -- http://wiki.python.org/moin/DbusExamples (just in case)
165 #### Because webpages come and go, the above information needs to be moved to inxi's wiki
166 ########################################################################
167 #### Valuable Resources
168 #### CPU flags: http://unix.stackexchange.com/questions/43539/what-do-the-flags-in-proc-cpuinfo-mean
169 #### Advanced Bash: http://wiki.bash-hackers.org/syntax/pe
170 #### gawk arrays: http://www.math.utah.edu/docs/info/gawk_12.html
171 #### raid mdstat: http://www-01.ibm.com/support/docview.wss?uid=isg3T1011259
172 #### http://www.howtoforge.com/replacing_hard_disks_in_a_raid1_array
173 #### https://raid.wiki.kernel.org/index.php/Mdstat
174 ########################################################################
176 #### inxi supports advanced testing triggers to do various things, using -! <arg>
177 #### -! 1 - triggers default B_TESTING_1='true' to trigger some test or other
178 #### -! 2 - triggers default B_TESTING_2='true' to trigger some test or other
179 #### -! 3 - triggers B_TESTING_1='true' and B_TESTING_2='true'
180 #### -! 10 - triggers an update from the primary dev download server instead of svn
181 #### -! 11 - triggers an update from svn branch one - if present, of course
182 #### -! 12 - triggers an update from svn branch two - if present, of course
183 #### -! 13 - triggers an update from svn branch three - if present, of course
184 #### -! 14 - triggers an update from svn branch four - if present, of course
185 #### -! <http://......> - Triggers an update from whatever server you list.
186 #### LOG FLAGS (logs to $HOME/.inxi/inxi.log with rotate 3 total)
187 #### -@ 8 - Basic data logging of generated data / array values
188 #### -@ 9 - Full logging of all data used, including cat of files and system data
189 #### -@ 10 - Basic data logging plus color code logging
190 ########################################################################
192 ########################################################################
194 ## NOTE: we can use hwinfo if it's available in all systems, or most, to get
195 ## a lot more data and verbosity levels going
197 ### DISTRO MAINTAINER FLAGS ###
198 # flag to allow distro maintainers to turn off update features. If false, turns off
199 # -U and -! testing/advanced update options, as well as removing the -U help menu item
200 # NOTE: Usually you want to create these in /etc/inxi.conf to avoid having to update each time
201 B_ALLOW_UPDATE='true'
202 B_ALLOW_WEATHER='true'
204 ### USER CONFIGS: SET IN inxi.conf file see wiki for directions ###
205 # http://code.google.com/p/inxi/wiki/script_configuration_files
206 # override in user config if desired, seems like less than .3 doesn't work as reliably
208 FILTER_STRING='<filter>'
210 # for features like help/version will fit to terminal / console screen width. Console
211 # widths will be dynamically set in main() based on cols in term/console
212 COLS_MAX_CONSOLE='115'
215 # change to less, or more if you have very slow connection
217 ### END USER CONFIGS ###
219 ### LOCALIZATION - DO NOT CHANGE! ###
220 # set to default LANG to avoid locales errors with , or .
222 # Make sure every program speaks English.
228 # Clear nullglob, because it creates unpredictable situations with IFS=$'\n' ARR=($VAR) IFS="$ORIGINAL_IFS"
229 # type constructs. Stuff like [rev a1] is now seen as a glob expansion pattern, and fails, and
230 # therefore results in nothing.
232 ## info on bash built in: $IFS - http://tldp.org/LDP/abs/html/internalvariables.html
233 # Backup the current Internal Field Separator
242 A_CPU_TYPE_PCNT_CCNT=''
246 A_GRAPHICS_CARD_DATA=''
253 A_OPTICAL_DRIVE_DATA=''
259 A_UNMOUNTED_PARTITION_DATA=''
261 A_DISPLAY_SERVER_DATA=''
264 ## standard boolean flags ##
266 B_COLOR_SCHEME_SET='false'
267 B_CONSOLE_IRC='false'
268 # triggers full display of cpu flags
269 B_CPU_FLAGS_FULL='false'
270 # test for dbus irc client
271 B_DBUS_CLIENT='false'
274 # Debug flood override: make 'true' to allow long debug output
275 B_DEBUG_FLOOD='false'
276 B_DMIDECODE_SET='false'
277 # show extra output data
280 B_EXTRA_EXTRA_DATA='false'
282 # override certain errors due to currupted data
283 B_HANDLE_CORRUPT_DATA='false'
287 B_LOG_FULL_DATA='false'
289 B_OUTPUT_FILTER='false'
290 B_OVERRIDE_FILTER='false'
292 B_PCICONF_SET='false'
298 B_RUN_COLOR_SELECTOR='false'
299 B_RUNNING_IN_DISPLAY='false' # in x type display server
300 if tty >/dev/null;then
301 B_RUNNING_IN_SHELL='true'
303 B_RUNNING_IN_SHELL='false'
305 # this sets the debug buffer
307 B_SHOW_ADVANCED_NETWORK='false'
308 # Show sound card data
310 B_SHOW_BASIC_RAID='false'
311 B_SHOW_BASIC_CPU='false'
312 B_SHOW_BASIC_DISK='false'
313 B_SHOW_BASIC_OPTICAL='false'
315 B_SHOW_DISPLAY_DATA='false'
316 B_SHOW_DISK_TOTAL='false'
318 # Show full hard disk output
319 B_SHOW_FULL_HDD='false'
320 B_SHOW_FULL_OPTICAL='false'
321 B_SHOW_GRAPHICS='false'
322 # Set this to 'false' to avoid printing the hostname, can be set false now
326 B_SHOW_LABELS='false'
327 B_SHOW_MACHINE='false'
328 B_SHOW_NETWORK='false'
329 # either -v > 3 or -P will show partitions
330 B_SHOW_PARTITIONS='false'
331 B_SHOW_PARTITIONS_FULL='false'
332 B_SHOW_PS_CPU_DATA='false'
333 B_SHOW_PS_MEM_DATA='false'
335 # because many systems have no mdstat file, -b/-F should not show error if no raid file found
336 B_SHOW_RAID_R='false'
338 B_SHOW_SENSORS='false'
339 # triggers only short inxi output
340 B_SHOW_SHORT_OUTPUT='false'
341 B_SHOW_SYSTEM='false'
342 B_SHOW_UNMOUNTED_PARTITIONS='false'
344 B_SHOW_WEATHER='false'
346 # triggers various debugging and new option testing
349 B_UPLOAD_DEBUG_DATA='false'
350 B_USB_NETWORKING='false'
351 # set to true here for debug logging from script start
352 B_USE_LOGGING='false'
356 ## Directory/file exist flags; test as [[ $(boolean) ]] not [[ $boolean ]]
357 B_ASOUND_DEVICE_FILE='false'
358 B_ASOUND_VERSION_FILE='false'
360 B_CPUINFO_FILE='false'
361 B_DMESG_BOOT_FILE='false' # bsd only
363 B_MDSTAT_FILE='false'
364 B_MEMINFO_FILE='false'
365 B_MODULES_FILE='false' #
366 B_MOUNTS_FILE='false'
367 B_OS_RELEASE_FILE='false' # new default distro id file? will this one work where lsb-release didn't?
368 B_PARTITIONS_FILE='false' #
372 ## app tested for and present, to avoid repeat tests
373 B_FILE_TESTED='false'
374 B_HDDTEMP_TESTED='false'
375 B_MODINFO_TESTED='false'
376 B_SUDO_TESTED='false'
378 ### CONSTANTS/INITIALIZE - SOME MAY BE RESET LATER ###
380 DEBUG=0 # Set debug levels from 1-10 (8-10 trigger logging levels)
381 # Debug Buffer Index, index into a debug buffer storing debug messages until inxi is 'all up'
383 ## note: the debugger rerouting to /dev/null has been moved to the end of the get_parameters function
384 ## so -@[number] debug levels can be set if there is a failure, otherwise you can't even see the errors
385 SED_I='-i' # for gnu sed, will be set to -i '' for bsd sed
386 SED_RX='-r' # for gnu sed, will be set to -E for bsd sed for backward compatibility
388 # default to false, no konversation found, 1 is native konvi (qt3/KDE3) script mode, 2 is /cmd inxi start,
389 ## 3 is Konversation > 1.2 (qt4/KDE4)
391 # NO_CPU_COUNT=0 # Wether or not the string "dual" or similar is found in cpuinfo output. If so, avoid dups.
392 # This is a variable that controls how many parameters inxi will parse in a /proc/<pid>/cmdline file before stopping.
394 SCHEME=0 # set default scheme - do not change this, it's set dynamically
395 # this is set in user prefs file, to override dynamic temp1/temp2 determination of sensors output in case
396 # cpu runs colder than mobo
398 # SHOW_IRC=1 to avoid showing the irc client version number, or SHOW_IRC=0 to disable client information completely.
400 # Verbosity level defaults to 0, this can also be set with -v0, -v2, -v3, etc as a parameter.
402 # Supported number of verbosity levels, including 0
406 ## logging eval variables, start and end function: Insert to LOGFS LOGFE when debug level >= 8
407 LOGFS_STRING='log_function_data fs $FUNCNAME "$( echo $@ )"'
408 LOGFE_STRING='log_function_data fe $FUNCNAME'
411 # uncomment for debugging from script start
412 # LOGFS=$LOGFS_STRING
413 # LOGFE=$LOGFE_STRING
415 ### FILE NAMES/PATHS/URLS - must be non root writable ###
416 # File's used when present
417 FILE_ASOUND_DEVICE='/proc/asound/cards'
418 FILE_ASOUND_MODULES='/proc/asound/modules' # not used but maybe for -A?
419 FILE_ASOUND_VERSION='/proc/asound/version'
420 FILE_CPUINFO='/proc/cpuinfo'
421 FILE_DMESG_BOOT='/var/run/dmesg.boot'
422 FILE_LSB_RELEASE='/etc/lsb-release'
423 FILE_MDSTAT='/proc/mdstat'
424 FILE_MEMINFO='/proc/meminfo'
425 FILE_MODULES='/proc/modules'
426 FILE_MOUNTS='/proc/mounts'
427 FILE_OS_RELEASE='/etc/os-release'
428 FILE_PARTITIONS='/proc/partitions'
429 FILE_SCSI='/proc/scsi/scsi'
430 FILE_XORG_LOG='/var/log/Xorg.0.log' # if not found, search and replace with actual location
437 SCRIPT_DATA_DIR="$HOME/.inxi"
438 ALTERNATE_FTP='' # for data uploads
439 ALTERNATE_WEATHER_LOCATION='' # weather alternate location
440 LOG_FILE="$SCRIPT_DATA_DIR/inxi.log"
441 LOG_FILE_1="$SCRIPT_DATA_DIR/inxi.1.log"
442 LOG_FILE_2="$SCRIPT_DATA_DIR/inxi.2.log"
443 MAN_FILE_DOWNLOAD='http://inxi.googlecode.com/svn/trunk/inxi.1.gz'
444 MAN_FILE_LOCATION='/usr/share/man/man1'
446 SCRIPT_PATCH_NUMBER=''
447 SCRIPT_PATH='' #filled-in in Main
448 SCRIPT_VERSION_NUMBER="" #filled-in in Main
449 SCRIPT_DOWNLOAD='http://inxi.googlecode.com/svn/trunk/'
450 SCRIPT_DOWNLOAD_BRANCH_1='http://inxi.googlecode.com/svn/branches/one/'
451 SCRIPT_DOWNLOAD_BRANCH_2='http://inxi.googlecode.com/svn/branches/two/'
452 SCRIPT_DOWNLOAD_BRANCH_3='http://inxi.googlecode.com/svn/branches/three/'
453 SCRIPT_DOWNLOAD_BRANCH_4='http://inxi.googlecode.com/svn/branches/four/'
454 SCRIPT_DOWNLOAD_BRANCH_BSD='http://inxi.googlecode.com/svn/branches/bsd/'
455 SCRIPT_DOWNLOAD_BRANCH_GNUBSD='http://inxi.googlecode.com/svn/branches/gnubsd/'
456 SCRIPT_DOWNLOAD_DEV='http://smxi.org/test/'
457 # note, you can use any ip url here as long as it's the only line on the output page.
458 # Also the ip address must be the last thing on that line.
459 WAN_IP_URL='http://smxi.org/opt/ip.php'
460 KONVI_CFG="konversation/scripts/$SCRIPT_NAME.conf" # relative path to $(kde-config --path data)
462 ### INITIALIZE VARIABLES NULL ###
473 IRC_CLIENT_VERSION=''
478 # These two determine separators in single line output, to force irc clients not to break off sections
481 # these will assign a separator to non irc states. Important! Using ':' can trigger stupid emoticon
482 # behaviors in output on IRC, so do not use those.
485 SEP3='' # do not set, will be set dynamically
487 # Default indentation level. NOTE: actual indent is 1 greater to allow for spacing
490 ### COLUMN WIDTHS ###
491 COLS_INNER='' ## for width minus INDENT
497 # http://stackoverflow.com/questions/1780483/lines-and-columns-environmental-variables-lost-in-a-script
498 if [[ -n $( type -p tput ) ]];then
499 TERM_COLUMNS=$(tput cols)
500 TERM_LINES=$(tput lines)
502 # double check, just in case it's missing functionality or whatever
503 if [[ -n ${TERM_COLUMNS##[0-9]*} ]];then
508 # Only for legacy user config files se we can test and convert the var name
513 # Defaults to 2, make this 1 for normal, 0 for no colorcodes at all. Use following variables in config
514 # files to change defaults for each type, or global
515 # Same as runtime parameter.
516 DEFAULT_COLOR_SCHEME=2
517 ## color variables - set dynamically
522 ## Always leave these blank, these are only going to be set in inxi.conf files, that makes testing
523 ## for user changes easier after sourcing the files
524 GLOBAL_COLOR_SCHEME=''
526 IRC_CONS_COLOR_SCHEME=''
527 IRC_X_TERM_COLOR_SCHEME=''
528 CONSOLE_COLOR_SCHEME=''
529 VIRT_TERM_COLOR_SCHEME=''
532 # A more elegant way to have a scheme that doesn't print color codes (neither ANSI nor mIRC) at all. See below.
534 # DGREY BLACK RED DRED GREEN DGREEN YELLOW DYELLOW
535 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"
536 IRC_COLORS=" \x0314 \x0301 \x0304 \x0305 \x0309 \x0303 \x0308 \x0307"
537 # BLUE DBLUE MAGENTA DMAGENTA CYAN DCYAN WHITE GREY NORMAL
538 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"
539 IRC_COLORS=" $IRC_COLORS \x0312 \x0302 \x0313 \x0306 \x0311 \x0310 \x0300 \x0315 \x03"
541 #ANSI_COLORS=($ANSI_COLORS); IRC_COLORS=($IRC_COLORS)
542 A_COLORS_AVAILABLE=( DGREY BLACK RED DRED GREEN DGREEN YELLOW DYELLOW BLUE DBLUE MAGENTA DMAGENTA CYAN DCYAN WHITE GREY NORMAL )
544 # See above for notes on EMPTY
545 ## note: group 1: 0, 1 are null/normal
546 ## Following: group 2: generic, light/dark or dark/light; group 3: dark on light; group 4 light on dark;
547 # this is the count of the first two groups, starting at zero
559 DYELLOW,NORMAL,NORMAL
562 MAGENTA,NORMAL,NORMAL
567 DBLUE,DMAGENTA,NORMAL
570 DGREEN,DYELLOW,NORMAL
572 DMAGENTA,BLACK,NORMAL
582 MAGENTA,YELLOW,NORMAL
588 # WARNING: In the main part below (search for 'KONVI')
589 # there's a check for Konversation-specific config files.
590 # Any one of these can override the above if inxi is run
594 # In cases of derived distros where the version file of the base distro can also be found under /etc,
595 # the derived distro's version file should go first. (Such as with Sabayon / Gentoo)
596 DISTROS_DERIVED="antix-version aptosid-version kanotix-version knoppix-version mandrake-release pardus-release sabayon-release siduction-version sidux-version solusos-release turbolinux-release zenwalk-version"
597 # debian_version excluded from DISTROS_PRIMARY so Debian can fall through to /etc/issue detection. Same goes for Ubuntu.
598 DISTROS_EXCLUDE_LIST="debian_version ubuntu_version"
599 DISTROS_PRIMARY="arch-release gentoo-release redhat-release slackware-version SuSE-release"
600 DISTROS_LSB_GOOD="mandrake-release mandriva-release mandrakelinux-release"
601 # this is being used both by core distros and derived distros now, eg, solusos 1 uses it for solusos id, while
602 # debian, solusos base, uses it as well, so we have to know which it is.
603 DISTROS_OS_RELEASE_GOOD="arch-release SuSE-release"
604 ## Distros with known problems
605 # DSL (Bash 2.05b: grep -m doesn't work; arrays won't work) --> unusable output
606 # Puppy Linux 4.1.2 (Bash 3.0: arrays won't work) --> works partially
608 ## OUTPUT FILTERS/SEARCH ##
609 # Note that \<ltd\> bans only words, not parts of strings; in \<corp\> you can't use punctuation characters like . or ,
610 # we're saving about 10+% of the total script exec time by hand building the ban lists here, using hard quotes.
611 BAN_LIST_NORMAL='chipset|components|computing|computer|corporation|communications|electronics|electrical|electric|gmbh|group|industrial|international|revision|semiconductor|software|technologies|technology|ltd\.|\<ltd\>|inc\.|\<inc\>|intl\.|co\.|\<co\>|corp\.|\<corp\>|\(tm\)|\(r\)|®|\(rev ..\)'
612 BAN_LIST_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]'
614 SENSORS_GPU_SEARCH='intel|radeon|nouveau'
616 ### USB networking search string data, because some brands can have other products than
617 ### wifi/nic cards, they need further identifiers, with wildcards.
618 ### putting the most common and likely first, then the less common, then some specifics
619 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"
620 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"
621 # then a few known hard to ID ones added
622 # belkin=050d; d-link=07d1; netgear=0846; ralink=148f; realtek=0bda;
623 USB_NETWORK_SEARCH="$USB_NETWORK_SEARCH|050d:935b|0bda:8189|0bda:8197"
625 ########################################################################
626 #### MAIN: Where it all begins
627 ########################################################################
632 local color_scheme=''
633 # this will be used by all functions following
634 local Ps_aux_Data="$( ps aux )"
636 # This function just initializes variables
639 # Source global config overrides, needs to be here because some things
640 # can be reset that were set in initialize, but check_required_apps needs
641 if [[ -s /etc/$SCRIPT_NAME.conf ]];then
642 source /etc/$SCRIPT_NAME.conf
644 # Source user config variables override /etc/inxi.conf variables
645 if [[ -s $HOME/.$SCRIPT_NAME/$SCRIPT_NAME.conf ]];then
646 source $HOME/.$SCRIPT_NAME/$SCRIPT_NAME.conf
648 # Convert to new variable names if set in config files, legacy test
649 if [[ -n $LINE_MAX_CONSOLE ]];then
650 COLS_MAX_CONSOLE=$LINE_MAX_CONSOLE
652 if [[ -n $LINE_MAX_IRC ]];then
653 COLS_MAX_IRC=$LINE_MAX_IRC
655 # TERM_COLUMNS is set in top globals, using tput cols
656 if [[ $TERM_COLUMNS -lt $COLS_MAX_CONSOLE ]];then
657 COLS_MAX_CONSOLE=$TERM_COLUMNS
659 # adjust, some terminals will wrap if output cols == term cols
660 COLS_MAX_CONSOLE=$(( $COLS_MAX_CONSOLE - 2 ))
662 # comes after source for user set stuff
663 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
664 COLS_MAX=$COLS_MAX_CONSOLE
667 # too hard to read if no colors, so force that for users on irc
668 if [[ $SCHEME == 0 ]];then
673 COLS_MAX=$COLS_MAX_IRC
675 COLS_INNER=$(( $COLS_MAX - $INDENT - 4 ))
677 # Check for dependencies BEFORE running ANYTHING else except above functions
678 # Not all distro's have these depends installed by default. Don't want to run
679 # this if the user is requesting to see this information in the first place
680 # Only continue if required apps tests ok
681 if [[ $1 != '--recommends' ]];then
683 check_recommended_apps
686 SCRIPT_VERSION_NUMBER=$( parse_version_data 'main' )
687 SCRIPT_PATCH_NUMBER=$( parse_version_data 'patch' )
689 # previous source location, check for bugs
691 ## this needs to run before the KONVI stuff is set below
692 ## Konversation 1.2 apparently does not like the $PPID test in get_start_client
693 ## So far there is no known way to detect if qt4_konvi is the parent process
694 ## this method will infer qt4_konvi as parent
697 # note: this only works if it's run from inside konversation as a script builtin or something
698 # only do this if inxi has been started as a konversation script, otherwise bypass this
699 # KONVI=3 ## for testing puroses
700 if [[ $KONVI -eq 1 || $KONVI -eq 3 ]];then
701 if [[ $KONVI -eq 1 ]]; then ## dcop Konversation (ie 1.x < 1.2(qt3))
706 elif [[ $KONVI -eq 3 ]]; then ## dbus Konversation (> 1.2 (qt4))
707 DCSERVER="$1" ##dbus testing
708 DCTARGET="$2" ##dbus testing
712 # The section below is on request of Argonel from the Konversation developer team:
713 # it sources config files like $HOME/.kde/share/apps/konversation/scripts/inxi.conf
715 for kde_config in $( kde-config --path data )
717 if [[ -r ${kde_config}${KONVI_CFG} ]];then
718 source "${kde_config}${KONVI_CFG}"
725 ## leave this for debugging dcop stuff if we get that working
726 # print_screen_output "DCPORT: $DCPORT"
727 # print_screen_output "DCSERVER: $DCSERVER"
728 # print_screen_output "DCTARGET: $DCTARGET"
730 # first init function must be set first for colors etc. Remember, no debugger
731 # stuff works on this function unless you set the debugging flag manually.
732 # Debugging flag -@ [number] will not work until get_parameters runs.
734 # "$@" passes every parameter separately quoted, "$*" passes all parameters as one quoted parameter.
735 # must be here to allow debugger and other flags to be set.
738 # If no colorscheme was set in the parameter handling routine, then set the default scheme
739 if [[ $B_COLOR_SCHEME_SET != 'true' ]];then
740 # This let's user pick their color scheme. For IRC, only shows the color schemes, no interactive
741 # The override value only will be placed in user config files. /etc/inxi.conf can also override
742 if [[ $B_RUN_COLOR_SELECTOR == 'true' ]];then
743 select_default_color_scheme
745 # set the default, then override as required
746 color_scheme=$DEFAULT_COLOR_SCHEME
747 if [[ -n $GLOBAL_COLOR_SCHEME ]];then
748 color_scheme=$GLOBAL_COLOR_SCHEME
750 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
751 if [[ -n $CONSOLE_COLOR_SCHEME && -z $DISPLAY ]];then
752 color_scheme=$CONSOLE_COLOR_SCHEME
753 elif [[ -n $VIRT_TERM_COLOR_SCHEME ]];then
754 color_scheme=$VIRT_TERM_COLOR_SCHEME
757 if [[ -n $IRC_X_TERM_COLOR_SCHEME && $B_CONSOLE_IRC == 'true' && -n $B_RUNNING_IN_DISPLAY ]];then
758 color_scheme=$IRC_X_TERM_COLOR_SCHEME
759 elif [[ -n $IRC_CONS_COLOR_SCHEME && -z $DISPLAY ]];then
760 color_scheme=$IRC_CONS_COLOR_SCHEME
761 elif [[ -n $IRC_COLOR_SCHEME ]];then
762 color_scheme=$IRC_COLOR_SCHEME
766 set_color_scheme $color_scheme
770 # all the pre-start stuff is in place now
772 script_debugger "Debugger: $SCRIPT_NAME is up and running..."
774 # then create the output
778 if [[ $B_RUNNING_IN_SHELL == 'true' && $SCHEME -gt 0 ]];then
782 # weechat's executor plugin forced me to do this, and rightfully so, because else the exit code
783 # from the last command is taken..
787 #### -------------------------------------------------------------------
788 #### basic tests: set script data, booleans, PATH, version numbers
789 #### -------------------------------------------------------------------
791 # Set PATH data so we can access all programs as user. Set BAN lists.
792 # initialize some boleans, these directories are used throughout the script
793 # some apps are used for extended functions any directory used, should be
794 # checked here first.
799 BSD_VERSION=$( uname -s 2>/dev/null | tr '[A-Z]' '[a-z]' )
801 # note: archbsd says they are a freebsd distro, so assuming it's the same as freebsd
802 if [[ -n $( grep 'bsd' <<< "$BSD_VERSION" ) ]];then
803 # GNU/kfreebsd will by definition have GNU tools like sed/grep
804 if [[ -n $( grep 'kfreebsd' <<< "$BSD_VERSION" ) ]];then
805 BSD_TYPE='debian-bsd' # debian gnu bsd
807 BSD_TYPE='bsd' # all other bsds
812 # now set the script BOOLEANS for files required to run features
813 # note that freebsd has /proc but it's empty
814 if [[ -d "/proc/" && -z $BSD_TYPE ]];then
816 elif [[ -n $BSD_TYPE ]];then
824 if [[ -n $BSD_TYPE ]];then
825 if [[ -e $FILE_DMESG_BOOT ]];then
826 B_DMESG_BOOT_FILE='true'
829 # found a case of battery existing but having nothing in it on desktop mobo
830 # not all laptops show the first,
831 if [[ -n $( ls /proc/acpi/battery 2>/dev/null ) ]];then
837 if [[ -e $FILE_CPUINFO ]]; then
838 B_CPUINFO_FILE='true'
841 if [[ -e $FILE_MEMINFO ]];then
842 B_MEMINFO_FILE='true'
845 if [[ -e $FILE_ASOUND_DEVICE ]];then
846 B_ASOUND_DEVICE_FILE='true'
849 if [[ -e $FILE_ASOUND_VERSION ]];then
850 B_ASOUND_VERSION_FILE='true'
853 if [[ -f $FILE_LSB_RELEASE ]];then
857 if [[ -f $FILE_OS_RELEASE ]];then
858 B_OS_RELEASE_FILE='true'
861 if [[ -e $FILE_SCSI ]];then
865 if [[ -n $DISPLAY ]];then
866 B_SHOW_DISPLAY_DATA='true'
867 B_RUNNING_IN_DISPLAY='true'
870 if [[ -e $FILE_MDSTAT ]];then
874 if [[ -e $FILE_MODULES ]];then
875 B_MODULES_FILE='true'
878 if [[ -e $FILE_MOUNTS ]];then
882 if [[ -e $FILE_PARTITIONS ]];then
883 B_PARTITIONS_FILE='true'
885 # default to the normal location, then search for it
886 if [[ -e $FILE_XORG_LOG ]];then
889 # Detect location of the Xorg log file
890 if [[ -n $( type -p xset ) ]]; then
891 FILE_XORG_LOG=$( xset q 2>/dev/null | grep -i 'Log file' | gawk '{print $3}')
892 if [[ -e $FILE_XORG_LOG ]];then
897 # gfx output will require this flag
898 if [[ $( whoami ) == 'root' ]];then
904 # arg: $1 - version number: main/patch/date
907 local version_data=''
909 # note, using ####[[:space:]]+ to avoid having this function also trip the version datas
912 version_data="$( gawk -F ': ' '
913 /####[[:space:]]+Date:/ {
915 }' $SCRIPT_PATH/$SCRIPT_NAME )"
918 version_data="$( gawk '
919 /####[[:space:]]+Version:/ {
921 }' $SCRIPT_PATH/$SCRIPT_NAME )"
924 version_data="$( gawk '
925 /####[[:space:]]+Patch Number:/ {
927 }' $SCRIPT_PATH/$SCRIPT_NAME )"
935 local path='' added_path='' b_path_found='' sys_path=''
936 # Extra path variable to make execute failures less likely, merged below
937 local extra_paths="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
939 # this needs to be set here because various options call the parent initialize function directly.
940 SCRIPT_PATH=$( dirname $0 )
942 # Fallback paths put into $extra_paths; This might, among others, help on gentoo.
943 # Now, create a difference of $PATH and $extra_paths and add that to $PATH:
945 for path in $extra_paths
948 for sys_path in $PATH
950 if [[ $path == $sys_path ]];then
954 if [[ $b_path_found == 'false' ]];then
955 added_path="$added_path:$path"
960 PATH="${PATH}${added_path}"
961 ##echo "PATH='$PATH'"
962 ##/bin/sh -c 'echo "PATH in subshell=\"$PATH\""'
966 check_recommended_apps()
969 local bash_array_test=( "one" "two" )
971 # check for array ability of bash, this is only good for the warning at this time
972 # the boolean could be used later
973 # bash version 2.05b is used in DSL
974 # bash version 3.0 is used in Puppy Linux; it has a known array bug <reference to be placed here>
975 # versions older than 3.1 don't handle arrays
976 # distro's using below 2.05b are unknown, released in 2002
977 if [[ ${bash_array_test[1]} -eq "two" ]];then
980 script_debugger "Suggestion: update to Bash v3.1 for optimal inxi output"
982 # test for a few apps that bsds may not have after initial tests
983 if [[ -n $( type -p lspci ) ]];then
986 if [[ -n $BSD_TYPE ]];then
987 if [[ -n $( type -p sysctl ) ]];then
990 if [[ -n $( type -p pciconf ) ]];then
994 # now setting qdbus/dcop for first run, some systems can have both by the way
995 if [[ -n $( type -p qdbus ) ]];then
998 if [[ -n $( type -p dcop ) ]];then
1004 # Determine if any of the absolutely necessary tools are absent
1006 check_required_apps()
1009 local app_name='' app_path=''
1010 # bc removed from deps for now
1011 local depends="df gawk grep ps readlink tr uname uptime wc"
1013 if [[ -z $BSD_TYPE ]];then
1014 depends="$depends lspci"
1015 elif [[ $BSD_TYPE == 'bsd' ]];then
1016 depends="$depends sysctl"
1017 # debian-bsd has lspci but you must be root to run it
1018 elif [[ $BSD_TYPE == 'debian-bsd' ]];then
1019 depends="$depends sysctl lspci"
1021 # no need to add xprop because it will just give N/A if not there, but if we expand use of xprop,
1022 # should add that here as a test, then use the B_SHOW_DISPLAY_DATA flag to trigger the tests in de function
1023 local x_apps="xrandr xdpyinfo glxinfo"
1025 if [[ $B_RUNNING_IN_DISPLAY == 'true' ]];then
1026 for app_name in $x_apps
1028 app_path=$( type -p $app_name )
1029 if [[ -z $app_path ]];then
1030 script_debugger "Resuming in non X mode: $app_name not found. For package install advice run: $SCRIPT_NAME --recommends"
1031 B_SHOW_DISPLAY_DATA='false'
1039 for app_name in $depends
1041 app_path=$( type -p $app_name )
1042 if [[ -z $app_path ]];then
1043 error_handler 5 "$app_name"
1049 ## note: this is now running inside each gawk sequence directly to avoid exiting gawk
1050 ## looping in bash through arrays, then re-entering gawk to clean up, then writing back to array
1051 ## in bash. For now I'll leave this here because there's still some interesting stuff to get re methods
1052 # Enforce boilerplate and buzzword filters
1053 # args: $1 - BAN_LIST_NORMAL/BAN_LIST_CPU; $2 - string to sanitize
1054 sanitize_characters()
1057 # Cannot use strong quotes to unquote a string with pipes in it!
1058 # bash will interpret the |'s as usual and try to run a subshell!
1059 # Using weak quotes instead, or use '"..."'
1066 gsub(/ [ ]+/,\" \") ## ([ ]+) with (space)
1067 gsub(/^ +| +$/,\"\") ## (pipe char) with (nothing)
1068 print ## prints (returns) cleaned input
1073 # Set the colorscheme
1074 # args: $1 = <scheme number>|<"none">
1078 local i='' a_output_colors='' a_color_codes=''
1080 if [[ $1 -ge ${#A_COLOR_SCHEMES[@]} ]];then
1083 # Set a global variable to allow checking for chosen scheme later
1085 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1086 a_color_codes=( $ANSI_COLORS )
1088 a_color_codes=( $IRC_COLORS )
1090 for (( i=0; i < ${#A_COLORS_AVAILABLE[@]}; i++ ))
1092 eval "${A_COLORS_AVAILABLE[i]}=\"${a_color_codes[i]}\""
1095 a_output_colors=( ${A_COLOR_SCHEMES[$1]} )
1097 # then assign the colors globally
1098 C1="${!a_output_colors[0]}"
1099 C2="${!a_output_colors[1]}"
1100 CN="${!a_output_colors[2]}"
1101 # ((COLOR_SCHEME++)) ## note: why is this? ##
1105 select_default_color_scheme()
1108 local spacer=' ' options='' user_selection='' config_variable=''
1109 local config_file="$HOME/.$SCRIPT_NAME/$SCRIPT_NAME.conf"
1110 local irc_clear="
\e[0m"
1111 local irc_gui='Unset' irc_console='Unset' irc_x_term='Unset'
1112 local console='Unset' virt_term='Unset' global='Unset'
1114 if [[ -n $IRC_COLOR_SCHEME ]];then
1115 irc_gui="Set: $IRC_COLOR_SCHEME"
1117 if [[ -n $IRC_CONS_COLOR_SCHEME ]];then
1118 irc_console="Set: $IRC_CONS_COLOR_SCHEME"
1120 if [[ -n $IRC_X_TERM_COLOR_SCHEME ]];then
1121 irc_x_term="Set: $IRC_X_TERM_COLOR_SCHEME"
1123 if [[ -n $VIRT_TERM_COLOR_SCHEME ]];then
1124 virt_term="Set: $VIRT_TERM_COLOR_SCHEME"
1126 if [[ -n $CONSOLE_COLOR_SCHEME ]];then
1127 console="Set: $CONSOLE_COLOR_SCHEME"
1129 if [[ -n $GLOBAL_COLOR_SCHEME ]];then
1130 global="Set: $GLOBAL_COLOR_SCHEME"
1133 # don't want these printing in irc since they show literally
1134 if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
1137 # first make output neutral so it's just plain default for console client
1138 set_color_scheme "0"
1139 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1140 print_screen_output "Welcome to $SCRIPT_NAME! Please select the default $COLOR_SELECTION color scheme."
1141 # print_screen_output "You will see this message only one time per user account, unless you set preferences in: /etc/$SCRIPT_NAME.conf"
1142 print_screen_output " "
1144 print_screen_output "Because there is no way to know your $COLOR_SELECTION foreground/background colors, you can"
1145 print_screen_output "set your color preferences from color scheme option list below. 0 is no colors, 1 neutral."
1146 print_screen_output "After these, there are 3 sets: 1-dark or light backgrounds; 2-light backgrounds; 3-dark backgrounds."
1147 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1148 print_screen_output "Please note that this will set the $COLOR_SELECTION preferences only for user: $(whoami)"
1150 print_screen_output "------------------------------------------------------------------------------"
1151 for (( i=0; i < ${#A_COLOR_SCHEMES[@]}; i++ ))
1153 if [[ $i -gt 9 ]];then
1156 # only offer the safe universal defaults
1157 case $COLOR_SELECTION in
1158 global|irc|irc-console|irc-virtual-terminal)
1159 if [[ $i -gt $SAFE_COLOR_COUNT ]];then
1165 print_screen_output "$irc_clear $i)$spacer${C1}Card:${C2} nVidia G86 [GeForce 8400 GS] ${C1}X.Org${C2} 1.7.7"
1169 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1171 print_screen_output "$irc_clear $i)${spacer}Remove all color settings. Restore $SCRIPT_NAME default."
1172 print_screen_output "$irc_clear $(($i+1)))${spacer}Continue, no changes or config file setting."
1173 print_screen_output "$irc_clear $(($i+2)))${spacer}Exit, use another terminal, or set manually."
1174 print_screen_output "------------------------------------------------------------------------------"
1175 print_screen_output "Simply type the number for the color scheme that looks best to your eyes for your $COLOR_SELECTION settings"
1176 print_screen_output "and hit ENTER. NOTE: You can bring this option list up by starting $SCRIPT_NAME with option: -c plus one of these numbers:"
1177 print_screen_output "94 (console, no X - $console); 95 (terminal, X - $virt_term); 96 (irc, gui, X - $irc_gui);"
1178 print_screen_output "97 (irc, X, in terminal - $irc_x_term); 98 (irc, no X - $irc_console); 99 (global - $global)"
1179 print_screen_output "Your selection(s) will be stored here: $config_file"
1180 print_screen_output "Global overrides all individual color schemes. Individual schemes remove the global setting."
1181 print_screen_output "------------------------------------------------------------------------------"
1183 if [[ -n $( grep -Es '^([0-9]+)$' <<< "$user_selection" ) && $user_selection -lt $i ]];then
1184 case $COLOR_SELECTION in
1186 config_variable='IRC_COLOR_SCHEME'
1189 config_variable='IRC_CONS_COLOR_SCHEME'
1191 irc-virtual-terminal)
1192 config_variable='IRC_X_TERM_COLOR_SCHEME'
1195 config_variable='CONSOLE_COLOR_SCHEME'
1198 config_variable='VIRT_TERM_COLOR_SCHEME'
1201 config_variable='GLOBAL_COLOR_SCHEME'
1204 set_color_scheme $user_selection
1205 # make file/directory first if missing
1206 if [[ ! -f $config_file ]];then
1207 if [[ ! -d $HOME/.$SCRIPT_NAME ]];then
1208 mkdir $HOME/.$SCRIPT_NAME
1212 if [[ -z $( grep -s "$config_variable=" $config_file ) ]];then
1213 print_screen_output "Creating and updating config file for $COLOR_SELECTION color scheme now..."
1214 echo "$config_variable=$user_selection" >> $config_file
1216 print_screen_output "Updating config file for $COLOR_SELECTION color scheme now..."
1217 sed $SED_I "s/$config_variable=.*/$config_variable=$user_selection/" $config_file
1219 # file exists now so we can go on to cleanup
1220 case $COLOR_SELECTION in
1221 irc|irc-console|irc-virtual-terminal|console|virtual-terminal)
1222 sed $SED_I '/GLOBAL_COLOR_SCHEME=/d' $config_file
1225 sed $SED_I -e '/VIRT_TERM_COLOR_SCHEME=/d' -e '/CONSOLE_COLOR_SCHEME=/d' -e '/IRC_COLOR_SCHEME=/d' \
1226 -e '/IRC_CONS_COLOR_SCHEME=/d' -e '/IRC_X_TERM_COLOR_SCHEME=/d' $config_file
1229 elif [[ $user_selection == $i ]];then
1230 print_screen_output "Removing all color settings from config file now..."
1231 sed $SED_I -e '/VIRT_TERM_COLOR_SCHEME=/d' -e '/GLOBAL_COLOR_SCHEME=/d' -e '/CONSOLE_COLOR_SCHEME=/d' \
1232 -e '/IRC_COLOR_SCHEME=/d' -e '/IRC_CONS_COLOR_SCHEME=/d' -e '/IRC_X_TERM_COLOR_SCHEME=/d' $config_file
1233 set_color_scheme $DEFAULT_COLOR_SCHEME
1234 elif [[ $user_selection == $(( $i+1 )) ]];then
1235 print_screen_output "Ok, continuing $SCRIPT_NAME unchanged. You can set the colors anytime by starting with: -c 95 to 99"
1236 if [[ -n $CONSOLE_COLOR_SCHEME && -z $DISPLAY ]];then
1237 set_color_scheme $CONSOLE_COLOR_SCHEME
1238 elif [[ -n $VIRT_TERM_COLOR_SCHEME ]];then
1239 set_color_scheme $VIRT_TERM_COLOR_SCHEME
1241 set_color_scheme $DEFAULT_COLOR_SCHEME
1243 elif [[ $user_selection == $(( $i+2 )) ]];then
1244 set_color_scheme $DEFAULT_COLOR_SCHEME
1245 print_screen_output "Ok, exiting $SCRIPT_NAME now. You can set the colors later."
1248 print_screen_output "Error - Invalid Selection. You entered this: $user_selection"
1249 print_screen_output " "
1250 select_default_color_scheme
1253 print_screen_output "------------------------------------------------------------------------------"
1254 print_screen_output "After finding the scheme number you like, simply run this again in a terminal to set the configuration"
1255 print_screen_output "data file for your irc client. You can set color schemes for the following: start inxi with -c plus:"
1256 print_screen_output "94 (console, no X - $console); 95 (terminal, X - $virt_term); 96 (irc, gui, X - $irc_gui);"
1257 print_screen_output "97 (irc, X, in terminal - $irc_x_term); 98 (irc, no X - $irc_console); 99 (global - $global)"
1264 ########################################################################
1265 #### UTILITY FUNCTIONS
1266 ########################################################################
1268 #### -------------------------------------------------------------------
1269 #### error handler, debugger, script updater
1270 #### -------------------------------------------------------------------
1273 # args: $1 - error number; $2 - optional, extra information; $3 - optional extra info
1277 local error_message=''
1279 # assemble the error message
1281 2) error_message="large flood danger, debug buffer full!"
1283 3) error_message="unsupported color scheme number: $2"
1285 4) error_message="unsupported verbosity level: $2"
1287 5) error_message="dependency not met: $2 not found in path.\nFor distribution installation package names and missing apps information, run: $SCRIPT_NAME --recommends"
1289 6) error_message="/proc not found! Quitting..."
1291 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"
1293 8) error_message="the self-updater failed, wget 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"
1295 9) error_message="unsupported debugging level: $2"
1298 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/"
1301 error_message="unsupported testing option argument: -! $2"
1304 error_message="the svn 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 http://code.google.com/p/inxi\nto verify the branch status."
1307 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"
1310 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"
1313 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"
1316 error_message="$SCRIPT_NAME downloaded but the file data is corrupted. Purged data and using current version."
1319 error_message="All $SCRIPT_NAME self updater features have been disabled by the distribution\npackage maintainer. This includes the option you used: $2"
1322 error_message="The argument you provided for $2 does not have supported syntax.\nPlease use the following formatting:\n$3"
1325 error_message="The option $2 has been deprecated. Please use $3 instead.\nSee -h for instructions and syntax."
1328 error_message="The option you selected has been deprecated. $2\nSee the -h (help) menu for currently supported options."
1330 *) error_message="error unknown: $@"
1334 # then print it and exit
1335 print_screen_output "Error $1: $error_message"
1340 # prior to script up set, pack the data into an array
1341 # then we'll print it out later.
1342 # args: $1 - $@ debugging string text
1346 if [[ $B_SCRIPT_UP == 'true' ]];then
1347 # only return if debugger is off and no pre start up errors have occured
1348 if [[ $DEBUG -eq 0 && $DEBUG_BUFFER_INDEX -eq 0 ]];then
1350 # print out the stored debugging information if errors occured
1351 elif [[ $DEBUG_BUFFER_INDEX -gt 0 ]];then
1352 for (( DEBUG_BUFFER_INDEX=0; DEBUG_BUFFER_INDEX < ${#A_DEBUG_BUFFER[@]}; DEBUG_BUFFER_INDEX++ ))
1354 print_screen_output "${A_DEBUG_BUFFER[$DEBUG_BUFFER_INDEX]}"
1356 DEBUG_BUFFER_INDEX=0
1358 # or print out normal debugger messages if debugger is on
1359 if [[ $DEBUG -gt 0 ]];then
1360 print_screen_output "$1"
1363 if [[ $B_DEBUG_FLOOD == 'true' && $DEBUG_BUFFER_INDEX -gt 10 ]];then
1365 # this case stores the data for later printout, will print out only
1366 # at B_SCRIPT_UP == 'true' if array index > 0
1368 A_DEBUG_BUFFER[$DEBUG_BUFFER_INDEX]="$1"
1369 # increment count for next pre script up debugging error
1370 (( DEBUG_BUFFER_INDEX++ ))
1376 # NOTE: no logging available until get_parameters is run, since that's what sets logging
1377 # in order to trigger earlier logging manually set B_USE_LOGGING to true in top variables.
1378 # $1 alone: logs data; $2 with or without $3 logs func start/end.
1379 # $1 type (fs/fe/cat/raw) or logged data; [$2 is $FUNCNAME; [$3 - function args]]
1382 if [ "$B_USE_LOGGING" == 'true' ];then
1383 local logged_data='' spacer=' ' line='----------------------------------------'
1386 logged_data="Function: $2 - Primary: Start"
1388 logged_data="$logged_data\n${spacer}Args: $3"
1393 logged_data="Function: $2 - Primary: End"
1397 if [[ $B_LOG_FULL_DATA == 'true' ]];then
1398 logged_data="\n$line\nFull file data: cat $2\n\n$( cat $2 )\n$line\n"
1403 if [[ $B_LOG_FULL_DATA == 'true' ]];then
1404 logged_data="\n$line\nRaw system data:\n\n$2\n$line\n"
1412 # Create any required line breaks and strip out escape color code, either ansi (case 1)or irc (case 2).
1413 # This pattern doesn't work for irc colors, if we need that someone can figure it out
1414 if [[ -n $logged_data ]];then
1415 if [[ $B_LOG_COLORS != 'true' ]];then
1416 echo -e "${spacer}$logged_data" | sed $SED_RX 's/\x1b\[[0-9]{1,2}(;[0-9]{1,2}){0,2}m//g' >> $LOG_FILE
1418 echo -e "${spacer}$logged_data" >> $LOG_FILE
1424 # called in the initial -@ 10 script args setting so we can get logging as soon as possible
1425 # will have max 3 files, inxi.log, inxi.1.log, inxi.2.log
1426 create_rotate_logfiles()
1428 if [[ ! -d $SCRIPT_DATA_DIR ]];then
1429 mkdir $SCRIPT_DATA_DIR
1431 # do the rotation if logfile exists
1432 if [[ -f $LOG_FILE ]];then
1433 # copy if present second to third
1434 if [[ -f $LOG_FILE_1 ]];then
1435 mv -f $LOG_FILE_1 $LOG_FILE_2
1437 # then copy initial to second
1438 mv -f $LOG_FILE $LOG_FILE_1
1440 # now create the logfile
1442 # and echo the start data
1443 echo "=========================================================" >> $LOG_FILE
1444 echo "START $SCRIPT_NAME LOGGING:" >> $LOG_FILE
1445 echo "Script started: $( date +%Y-%m-%d-%H:%M:%S )" >> $LOG_FILE
1446 echo "=========================================================" >> $LOG_FILE
1449 # args: $1 - download url, not including file name; $2 - string to print out
1450 # $3 - update type option
1451 # note that $1 must end in / to properly construct the url path
1452 script_self_updater()
1455 local wget_error=0 file_contents='' wget_man_error=0
1456 local man_file_path="$MAN_FILE_LOCATION/inxi.1.gz"
1458 if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
1459 print_screen_output "Sorry, you can't run the $SCRIPT_NAME self updater option (-$3) in an IRC client."
1463 print_screen_output "Starting $SCRIPT_NAME self updater."
1464 print_screen_output "Currently running $SCRIPT_NAME version number: $SCRIPT_VERSION_NUMBER"
1465 print_screen_output "Current version patch number: $SCRIPT_PATCH_NUMBER"
1466 print_screen_output "Updating $SCRIPT_NAME in $SCRIPT_PATH using $2 as download source..."
1468 file_contents="$( wget -q -O - $1$SCRIPT_NAME )" || wget_error=$?
1469 # then do the actual download
1470 if [[ $wget_error -eq 0 ]];then
1471 # make sure the whole file got downloaded and is in the variable
1472 if [[ -n $( grep '###\*\*EOF\*\*###' <<< "$file_contents" ) ]];then
1473 echo "$file_contents" > $SCRIPT_PATH/$SCRIPT_NAME || error_handler 14 "$?"
1474 chmod +x $SCRIPT_PATH/$SCRIPT_NAME || error_handler 15 "$?"
1475 SCRIPT_VERSION_NUMBER=$( parse_version_data 'main' )
1476 SCRIPT_PATCH_NUMBER=$( parse_version_data 'patch' )
1477 print_screen_output "Successfully updated to $2 version: $SCRIPT_VERSION_NUMBER"
1478 print_screen_output "New $2 version patch number: $SCRIPT_PATCH_NUMBER"
1479 print_screen_output "To run the new version, just start $SCRIPT_NAME again."
1480 print_screen_output "----------------------------------------"
1481 print_screen_output "Starting download of man page file now."
1482 if [[ ! -d $MAN_FILE_LOCATION ]];then
1483 print_screen_output "The required man directory was not detected on your system, unable to continue: $MAN_FILE_LOCATION"
1485 if [[ $B_ROOT == 'true' ]];then
1486 print_screen_output "Checking Man page download URL..."
1487 if [[ -f /usr/share/man/man8/inxi.8.gz ]];then
1488 print_screen_output "Updating man page location to man1."
1489 mv -f /usr/share/man/man8/inxi.8.gz /usr/share/man/man1/inxi.1.gz
1490 if [[ -n $( type -p mandb ) ]];then
1491 exec $( type -p mandb ) -q
1494 wget -q --spider $MAN_FILE_DOWNLOAD || wget_man_error=$?
1495 if [[ $wget_man_error -eq 0 ]];then
1496 print_screen_output "Man file download URL verified: $MAN_FILE_DOWNLOAD"
1497 print_screen_output "Downloading Man page file now."
1498 wget -q -O $man_file_path $MAN_FILE_DOWNLOAD || wget_man_error=$?
1499 if [[ $wget_man_error -gt 0 ]];then
1500 print_screen_output "Oh no! Something went wrong downloading the Man gz file at: $MAN_FILE_DOWNLOAD"
1501 print_screen_output "Check the error messages for what happened. Error: $wget_man_error"
1503 print_screen_output "Download/install of man page successful. Check to make sure it works: man inxi"
1506 print_screen_output "Man file download URL failed, unable to continue: $MAN_FILE_DOWNLOAD"
1509 print_screen_output "Updating / Installing the Man page requires root user, writing to: $MAN_FILE_LOCATION"
1510 print_screen_output "If you want the man page, you'll have to run $SCRIPT_NAME -$3 as root."
1517 # now run the error handlers on any wget failure
1519 if [[ $2 == 'svn server' ]];then
1520 error_handler 8 "$wget_error"
1521 elif [[ $2 == 'alt server' ]];then
1522 error_handler 10 "$1"
1524 error_handler 12 "$1"
1530 # args: $1 - debug data type: sys|xorg|disk
1531 debug_data_collector()
1533 local xiin_app='' xiin_data_file='' xiin_download='' error='' b_run_xiin='false'
1534 local debug_data_dir='' bsd_string=''
1535 local completed_gz_file='' xiin_file='xiin.py' ftp_upload='ftp.techpatterns.com/incoming'
1536 local Line='-------------------------'
1537 local start_directory=$( pwd )
1539 if [[ -n $BSD_TYPE ]];then
1540 bsd_string="$BSD_TYPE-"
1543 debug_data_dir="inxi-$bsd_string$(tr ' ' '-' <<< $HOSTNAME | tr '[A-Z]' '[a-z]' )-$1-$(date +%Y%m%d)"
1545 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1546 if [[ -n $ALTERNATE_FTP ]];then
1547 ftp_upload=$ALTERNATE_FTP
1549 echo "Starting debugging data collection type: $1"
1550 echo -n "Checking/creating required directories... "
1551 if [[ ! -d $SCRIPT_DATA_DIR ]];then
1552 mkdir $SCRIPT_DATA_DIR
1556 if [[ -d $SCRIPT_DATA_DIR/$debug_data_dir ]];then
1557 echo 'Deleting previous xiin data directory...'
1558 rm -rf $SCRIPT_DATA_DIR/$debug_data_dir
1560 mkdir $SCRIPT_DATA_DIR/$debug_data_dir
1561 if [[ -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz ]];then
1562 echo 'Deleting previous tar.gz file...'
1563 rm -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz
1566 echo 'Collecting system info: sensors, lsusb, lspci, lspci -v data, plus /proc data'
1567 echo 'also checking for dmidecode data: note, you must be root to have dmidecode work.'
1568 echo "Data going into: $SCRIPT_DATA_DIR/$debug_data_dir"
1570 pciconf -vl &> $debug_data_dir/bsd-pciconf-vl.txt
1571 sysctl -a &> $debug_data_dir/bsd-sysctl-a.txt
1573 dmidecode &> $debug_data_dir/dmidecode.txt
1575 lscpu &> $debug_data_dir/lscpu.txt
1576 lspci &> $debug_data_dir/lspci.txt
1577 lspci -n &> $debug_data_dir/lspci-n.txt
1578 lspci -v &> $debug_data_dir/lspci-v.txt
1579 lsusb &> $debug_data_dir/lsusb.txt
1580 ps aux &> $debug_data_dir/ps-aux.txt
1581 runlevel &> $debug_data_dir/runlevel.txt
1582 systemctl list-units &> $debug_data_dir/systemctl-list-units.txt
1583 systemctl list-units --type=target &> $debug_data_dir/systemctl-list-units-target.txt
1584 initctl list &> $debug_data_dir/initctl-list.txt
1585 sensors &> $debug_data_dir/sensors.txt
1586 strings --version &> $debug_data_dir/strings.txt
1587 nvidia-smi -q &> $debug_data_dir/nvidia-smi-q.txt
1588 nvidia-smi -q -x &> $debug_data_dir/nvidia-smi-xq.txt
1590 ls /usr/bin/gcc* &> $debug_data_dir/gcc-sys-versions.txt
1591 gcc --version &> $debug_data_dir/gcc-version.txt
1592 cat /etc/issue &> $debug_data_dir/etc-issue.txt
1593 cat $FILE_LSB_RELEASE &> $debug_data_dir/lsb-release.txt
1594 cat $FILE_OS_RELEASE &> $debug_data_dir/os-release.txt
1595 cat $FILE_ASOUND_DEVICE &> $debug_data_dir/proc-asound-device.txt
1596 cat $FILE_ASOUND_VERSION &> $debug_data_dir/proc-asound-version.txt
1597 cat $FILE_CPUINFO &> $debug_data_dir/proc-cpu-info.txt
1598 cat $FILE_MEMINFO &> $debug_data_dir/proc-meminfo.txt
1599 cat $FILE_MODULES &> $debug_data_dir/proc-modules.txt
1600 cat /proc/net/arp &> $debug_data_dir/proc-net-arp.txt
1602 cat /var/run/dmesg.boot &> $debug_data_dir/bsd-var-run-dmesg.boot.txt
1604 check_recommends_user_output &> $debug_data_dir/check-recommends-user-output.txt
1605 # first download and verify xiin
1606 if [[ $B_UPLOAD_DEBUG_DATA == 'true' || $1 == 'disk' || $1 == 'sys' || $1 == 'all' ]];then
1607 touch $SCRIPT_DATA_DIR/$debug_data_dir/xiin-error.txt
1608 echo "Downloading required tree traverse tool $xiin_file..."
1609 if [[ -f xiin && ! -f $xiin_file ]];then
1610 mv -f xiin $xiin_file
1612 # -Nc is creating really weird download anomolies, so using -O instead
1613 xiin_download="$( wget -q -O - http://inxi.googlecode.com/svn/branches/xiin/$xiin_file )"
1614 # if nothing got downloaded kick out error, otherwise we'll use an older version
1615 if [[ $? -gt 0 && ! -f $xiin_file ]];then
1616 echo -e "ERROR: Failed to download required file: $xiin_file\nMaybe the remote site is down or your networking is broken?"
1617 echo "Continuing with incomplete data collection."
1618 echo "$xiin_file download failed and no existing $xiin_file" >> $debug_data_dir/xiin-error.txt
1619 elif [[ -n $( grep -s '# EOF' <<< "$xiin_download" ) || -f $xiin_file ]];then
1620 if [[ -n $( grep -s '# EOF' <<< "$xiin_download" ) ]];then
1621 echo "Updating $xiin_file from remote location"
1622 echo "$xiin_download" > $xiin_file
1624 echo "Using local $xiin_file due to download failure"
1628 echo -e "ERROR: $xiin_file downloaded but the program file data is corrupted.\nContinuing with incomplete data collection."
1629 echo "$xiin_file downloaded but the program file data is corrupted." >> $debug_data_dir/xiin-error.txt
1632 # note, only bash 4> supports ;;& for case, so using if/then here
1633 if [[ $1 == 'disk' || $1 == 'sys' || $1 == 'all' ]];then
1634 xiin_data_file=$SCRIPT_DATA_DIR/$debug_data_dir/xiin-sys.txt
1635 echo 'Collecting networking data...'
1636 ifconfig &> $debug_data_dir/ifconfig.txt
1637 ip addr &> $debug_data_dir/ip-addr.txt
1638 if [[ $b_run_xiin == 'true' && -z $BSD_TYPE ]];then
1640 echo "Running $xiin_file tool now on /sys..."
1641 echo "Using Python version:" && python --version
1642 python --version &> $debug_data_dir/python-version.txt
1643 python ./$xiin_file -d /sys -f $xiin_data_file
1644 if [[ $? -ne 0 ]];then
1646 echo -e "ERROR: $xiin_file exited with error $error - removing data file.\nContinuing with incomplete data collection."
1647 echo "Continuing with incomplete data collection."
1648 rm -f $xiin_data_file
1649 echo "$xiin_file data generation failed with python error $error" >> $debug_data_dir/xiin-error.txt
1654 if [[ $1 == 'xorg' || $1 == 'all' ]];then
1655 if [[ $B_RUNNING_IN_DISPLAY != 'true' ]];then
1656 echo 'Warning: only some of the data collection can occur if you are not in X'
1657 touch $debug_data_dir/warning-user-not-in-x
1659 if [[ $B_ROOT == 'true' ]];then
1660 echo 'Warning: only some of the data collection can occur if you are running as Root user'
1661 touch $debug_data_dir/warning-root-user
1663 echo 'Collecting Xorg log and xorg.conf files'
1664 if [[ -e $FILE_XORG_LOG ]];then
1665 cat $FILE_XORG_LOG &> $debug_data_dir/xorg-log-file.txt
1667 touch $debug_data_dir/no-xorg-log-file
1669 if [[ -e /etc/X11/xorg.conf ]];then
1670 cp /etc/X11/xorg.conf $SCRIPT_DATA_DIR/$debug_data_dir
1672 touch $debug_data_dir/no-xorg-conf-file
1674 if [[ -n $( ls /etc/X11/xorg.conf.d/ 2>/dev/null ) ]];then
1675 ls /etc/X11/xorg.conf.d &> $debug_data_dir/ls-etc-x11-xorg-conf-d.txt
1676 cp /etc/X11/xorg.conf.d $SCRIPT_DATA_DIR/$debug_data_dir
1678 touch $debug_data_dir/no-xorg-conf-d-files
1680 echo 'Collecting X, xprop, glxinfo, xrandr, xdpyinfo data...'
1681 xprop -root &> $debug_data_dir/xprop_root.txt
1682 glxinfo &> $debug_data_dir/glxinfo.txt
1683 xdpyinfo &> $debug_data_dir/xdpyinfo.txt
1684 xrandr &> $debug_data_dir/xrandr.txt
1685 X -version &> $debug_data_dir/x-version.txt
1686 Xorg -version &> $debug_data_dir/xorg-version.txt
1687 echo $GNOME_DESKTOP_SESSION_ID &> $debug_data_dir/gnome-desktop-session-id.txt
1689 echo $KDE_FULL_SESSION &> $debug_data_dir/kde3-ful-session.txt
1690 echo $KDE_SESSION_VERSION &> $debug_data_dir/kde456-session-version.txt
1691 echo "$(kded$KDE_SESSION_VERSION --version )" &> $debug_data_dir/kde-version-data.txt
1692 echo $XDG_CURRENT_DESKTOP &> $debug_data_dir/xdg-current-desktop.txt
1694 if [[ $1 == 'disk' || $1 == 'all' ]];then
1695 echo 'Collecting dev, label, disk, uuid data, df...'
1696 ls -l /dev &> $debug_data_dir/dev-data.txt
1697 ls -l /dev/disk &> $debug_data_dir/dev-disk-data.txt
1698 ls -l /dev/disk/by-id &> $debug_data_dir/dev-disk-id-data.txt
1699 ls -l /dev/disk/by-label &> $debug_data_dir/dev-disk-label-data.txt
1700 ls -l /dev/disk/by-uuid &> $debug_data_dir/dev-disk-uuid-data.txt
1701 ls -l /dev/disk/by-path &> $debug_data_dir/dev-disk-path-data.txt
1702 ls -l /dev/mapper &> $debug_data_dir/dev-disk-mapper-data.txt
1703 readlink /dev/root &> $debug_data_dir/dev-root.txt
1704 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
1705 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
1706 df -H -T &> $debug_data_dir/bsd-df-H-T-no-excludes.txt
1707 df -H &> $debug_data_dir/bsd-df-H-no-excludes.txt
1709 mount &> $debug_data_dir/mount.txt
1710 gpart list &> $debug_data_dir/bsd-gpart-list.txt
1711 gpart show &> $debug_data_dir/bsd-gpart-show.txt
1712 gpart status &> $debug_data_dir/bsd-gpart-status.txt
1713 swapctl -l &> $debug_data_dir/bsd-swapctl-l.txt
1714 swapon -s &> $debug_data_dir/swapon-s.txt
1715 sysctl -b kern.geom.conftxt &> $debug_data_dir/bsd-sysctl-b-kern.geom.conftxt.txt
1716 sysctl -b kern.geom.confxml &> $debug_data_dir/bsd-sysctl-b-kern.geom.confxml.txt
1717 zfs list &> $debug_data_dir/bsd-zfs-list.txt
1718 zpool list &> $debug_data_dir/bsd-zpool-list.txt
1719 zpool list -v &> $debug_data_dir/bsd-zpool-list-v.txt
1720 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
1721 df -P &> $debug_data_dir/bsd-df-P-no-excludes.txt
1722 cat /proc/mdstat &> $debug_data_dir/proc-mdstat.txt
1723 cat $FILE_PARTITIONS &> $debug_data_dir/proc-partitions.txt
1724 cat $FILE_SCSI &> $debug_data_dir/proc-scsi.txt
1725 cat $FILE_MOUNTS &> $debug_data_dir/proc-mounts.txt
1726 cat /proc/sys/dev/cdrom/info &> $debug_data_dir/proc-cdrom-info.txt
1727 ls /proc/ide/ &> $debug_data_dir/proc-ide.txt
1728 cat /proc/ide/*/* &> $debug_data_dir/proc-ide-hdx-cat.txt
1729 cat /etc/fstab &> $debug_data_dir/etc-fstab.txt
1730 cat /etc/mtab &> $debug_data_dir/etc-mtab.txt
1732 echo 'Creating inxi output file now. This can take a few seconds...'
1733 echo "Starting $SCRIPT_NAME from: $start_directory"
1735 $SCRIPT_PATH/$SCRIPT_NAME -FRploudxxx -c 0 -@ 8 > $SCRIPT_DATA_DIR/$debug_data_dir/inxi-FRploudxxx.txt
1736 cp $LOG_FILE $SCRIPT_DATA_DIR/$debug_data_dir
1737 if [[ -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz ]];then
1738 echo "Found and removing previous tar.gz data file: $debug_data_dir.tar.gz"
1739 rm -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz
1742 echo 'Creating tar.gz compressed file of this material now. Contents:'
1744 tar -cvzf $debug_data_dir.tar.gz $debug_data_dir
1746 echo 'Cleaning up leftovers...'
1747 rm -rf $debug_data_dir
1748 echo 'Testing gzip file integrity...'
1749 gzip -t $debug_data_dir.tar.gz
1750 if [[ $? -gt 0 ]];then
1751 echo 'Data in gz is corrupted, removing gzip file, try running data collector again.'
1752 rm -f $debug_data_dir.tar.gz
1753 echo "Data in gz is corrupted, removed gzip file" >> $debug_data_dir/gzip-error.txt
1755 echo 'All done, you can find your data gzipped directory here:'
1756 completed_gz_file=$SCRIPT_DATA_DIR/$debug_data_dir.tar.gz
1757 echo $completed_gz_file
1758 if [[ $B_UPLOAD_DEBUG_DATA == 'true' ]];then
1760 if [[ $b_run_xiin == 'true' ]];then
1761 echo "Running automatic upload of data to remote server $ftp_upload now..."
1762 python ./$xiin_file --version
1763 python ./$xiin_file -u $completed_gz_file $ftp_upload
1764 if [[ $? -gt 0 ]];then
1766 echo "Error: looks like the ftp upload failed. Error number: $?"
1767 echo "The ftp upload failed. Error number: $?" >> $debug_data_dir/xiin-error.txt
1770 echo 'Unable to run the automoatic ftp upload because of an error with the xiin download.'
1771 echo "Unable to run the automoatic ftp upload because of an error with the xiin download" >> $debug_data_dir/xiin-error.txt
1774 echo 'You can upload this here using most file managers: ftp.techpatterns.com/incoming'
1775 echo 'then let a maintainer know it is uploaded.'
1779 echo 'This feature only available in console or shell client! Exiting now.'
1784 check_recommends_user_output()
1786 local Line='-----------------------------------------------------------------------------------------'
1787 local gawk_version='N/A' sed_version='N/A' sudo_version='N/A' python_version='N/A'
1789 if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
1790 print_screen_output "Sorry, you can't run this option in an IRC client."
1796 echo "$SCRIPT_NAME will now begin checking for the programs it needs to operate. First a check of"
1797 echo "the main languages and tools $SCRIPT_NAME uses. Python is only for debugging data collection."
1799 echo "Bash version: $( bash --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^GNU bash/ {print $4}' )"
1800 if [[ -n $( type -p gawk ) ]];then
1801 gawk_version=$( gawk --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^GNU Awk/ {print $3}' )
1803 if [[ -n $( type -p sed ) ]];then
1804 sed_version=$( sed --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^GNU sed version/ {print $4}' )
1805 if [[ -z $sed_version ]];then
1806 # note: bsd sed shows error with --version flag
1807 sed_version=$( sed --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^sed: illegal option/ {print "BSD sed"}' )
1810 if [[ -n $( type -p sudo ) ]];then
1811 sudo_version=$( sudo -V 2>&1 | awk 'BEGIN {IGNORECASE=1} /^Sudo version/ {print $3}' )
1813 if [[ -n $( type -p python ) ]];then
1814 python_version=$( python --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^Python/ {print $2}' )
1816 echo "Gawk version: $gawk_version"
1817 echo "Sed version: $sed_version"
1818 echo "Sudo version: $sudo_version"
1819 echo "Python version: $python_version"
1821 echo "Test One: Required System Directories."
1822 echo "If one of these system directories is missing, $SCRIPT_NAME cannot operate:"
1824 check_recommends_items 'required-dirs'
1825 echo "Test Two: Required Core Applications."
1826 echo "If one of these applications is missing, $SCRIPT_NAME cannot operate:"
1828 check_recommends_items 'required-apps'
1829 echo 'Test Three: Script Recommends for Graphics Features. If you do not use X these do not matter.'
1830 echo "If one of these applications is missing, $SCRIPT_NAME will have incomplete output:"
1832 check_recommends_items 'recommended-x-apps'
1833 echo 'Test Four: Script Recommends for Remaining Features.'
1834 echo "If one of these applications is missing, $SCRIPT_NAME will have incomplete output:"
1836 check_recommends_items 'recommended-apps'
1837 echo 'Test Five: System Directories for Various Information.'
1838 echo "If one of these directories is missing, $SCRIPT_NAME will have incomplete output:"
1840 check_recommends_items 'system-dirs'
1841 echo 'All tests completed.'
1843 # args: $1 - check item
1844 check_recommends_items()
1846 local item='' item_list='' item_string='' missing_items='' missing_string=''
1847 local package='' application='' feature='' type='' starter='' finisher=''
1848 local package_deb='' package_pacman='' package_rpm=''
1849 local print_string='' separator=''
1850 local required_dirs='/proc /sys'
1851 # package-owner: 1 - debian/ubuntu; 2 - arch; 3 - yum/rpm
1852 # pardus: pisi sf -q /usr/bin/package
1853 local required_apps='
1854 df:coreutils~coreutils~coreutils~:partition_data
1855 gawk:gawk~gawk~gawk~:core_tool
1856 grep:grep~grep~grep~:string_search
1857 lspci:pciutils~pciutils~pciutils~:hardware_data
1858 ps:procps~procps~procps~:process_data
1859 readlink:coreutils~coreutils~coreutils~:
1860 sed:sed~sed~sed~:string_replace
1861 tr:coreutils~coreutils~coreutils~:character_replace
1862 uname:uname~coreutils~coreutils~:kernel_data
1863 uptime:procps~procps~procps~:
1864 wc:coreutils~coreutils~coreutils~:word_character_count
1866 local x_recommends='
1867 glxinfo:mesa-utils~mesa-demos~glx-utils_(openSUSE_12.3_and_later_Mesa-demo-x)~:-G_glx_info
1868 xdpyinfo:X11-utils~xorg-xdpyinfo~xorg-x11-utils~:-G_multi_screen_resolution
1869 xprop:X11-utils~xorg-xprop~x11-utils~:-S_desktop_data
1870 xrandr:x11-xserver-utils~xrandr~x11-server-utils~:-G_single_screen_resolution
1872 local recommended_apps='
1873 dmidecode:dmidecode~dmidecode~dmidecode~:-M_if_no_sys_machine_data
1874 file:file~file~file~:-o_unmounted_file_system
1875 hddtemp:hddtemp~hddtemp~hddtemp~:-Dx_show_hdd_temp
1876 ifconfig:net-tools~net-tools~net-tools~:-i_ip_lan-deprecated
1877 ip:iproute~iproute2~iproute~:-i_ip_lan
1878 sensors:lm-sensors~lm_sensors~lm-sensors~:-s_sensors_output
1879 strings:binutils~~~:-I_sysvinit_version
1880 lsusb:usbutils~usbutils~usbutils~:-A_usb_audio;-N_usb_networking
1881 modinfo:module-init-tools~module-init-tools~module-init-tools~:-Ax,-Nx_module_version
1882 runlevel:sysvinit~sysvinit~systemd~:-I_runlevel
1883 sudo:sudo~sudo~sudo~:-Dx_hddtemp-user;-o_file-user
1885 local recommended_dirs='
1886 /sys/class/dmi/id:-M_system,_motherboard,_bios
1887 /dev:-l,-u,-o,-p,-P,-D_disk_partition_data
1888 /dev/disk/by-label:-l,-o,-p,-P_partition_labels
1889 /dev/disk/by-uuid:-u,-o,-p,-P_partition_uuid
1890 /var/run/dmesg.boot:-C,-f_(BSD_only)
1895 item_list=$required_dirs
1896 item_string='Required file system'
1897 missing_string='system directories'
1901 item_list=$required_apps
1902 item_string='Required application'
1903 missing_string='applications, and their corresponding packages,'
1907 item_list=$x_recommends
1908 item_string='Recommended X application'
1909 missing_string='applications, and their corresponding packages,'
1913 item_list=$recommended_apps
1914 item_string='Recommended application'
1915 missing_string='applications, and their corresponding packages,'
1919 item_list=$recommended_dirs
1920 item_string='System directory'
1921 missing_string='system directories'
1925 # great trick from: http://ideatrash.net/2011/01/bash-string-padding-with-sed.html
1926 # left pad: sed -e :a -e 's/^.\{1,80\}$/& /;ta'
1927 # right pad: sed -e :a -e 's/^.\{1,80\}$/ &/;ta'
1928 # center pad: sed -e :a -e 's/^.\{1,80\}$/ & /;ta'
1930 for item in $item_list
1932 if [[ $( awk -F ":" '{print NF-1}' <<< $item ) -eq 0 ]];then
1937 elif [[ $( awk -F ":" '{print NF-1}' <<< $item ) -eq 1 ]];then
1938 application=$( cut -d ':' -f 1 <<< $item )
1940 feature=$( cut -d ':' -f 2 <<< $item )
1943 application=$( cut -d ':' -f 1 <<< $item )
1944 package=$( cut -d ':' -f 2 <<< $item )
1945 location=$( type -p $application )
1946 if [[ $( awk -F ":" '{print NF-1}' <<< $item ) -eq 2 ]];then
1947 feature=$( cut -d ':' -f 3 <<< $item )
1952 if [[ -n $feature ]];then
1953 print_string="$item_string: $application (info: $( sed 's/_/ /g' <<< $feature ))"
1955 print_string="$item_string: $application"
1958 starter="$( sed -e :a -e 's/^.\{1,75\}$/&./;ta' <<< $print_string )"
1959 if [[ -z $( grep '^/' <<< $application ) && -n $location ]] || [[ -d $application ]];then
1960 if [[ -n $location ]];then
1961 finisher=" $location"
1967 missing_items="$missing_items$separator$application:$package"
1971 echo "$starter$finisher"
1974 if [[ -n $missing_items ]];then
1975 echo "The following $type are missing from your system:"
1976 for item in $missing_items
1978 application=$( cut -d ':' -f 1 <<< $item )
1979 if [[ $type == 'applications' ]];then
1980 # echo '--------------------------------------------------------'
1982 package=$( cut -d ':' -f 2 <<< $item )
1983 package_deb=$( cut -d '~' -f 1 <<< $package )
1984 package_pacman=$( cut -d '~' -f 2 <<< $package )
1985 package_rpm=$( cut -d '~' -f 3 <<< $package )
1986 echo "Application: $application"
1987 echo "To add to your system, install the proper distribution package for your system:"
1988 echo "Debian/Ubuntu: $package_deb :: Arch Linux: $package_pacman :: Redhat/Fedora/Suse: $package_rpm"
1990 echo "Directory: $application"
1993 if [[ $item_string == 'System directory' ]];then
1994 echo "These directories are created by the kernel, so don't worry if they are not present."
1997 echo "All the $( cut -d ' ' -f 1 <<< $item_string | sed -e 's/Re/re/' -e 's/Sy/sy/' ) $type are present."
2002 #### -------------------------------------------------------------------
2003 #### print / output cleaners
2004 #### -------------------------------------------------------------------
2006 # inxi speaks through here. When run by Konversation script alias mode, uses DCOP
2007 # for dcop to work, must use 'say' operator, AND colors must be evaluated by echo -e
2008 # note: dcop does not seem able to handle \n so that's being stripped out and replaced with space.
2009 print_screen_output()
2012 # the double quotes are needed to avoid losing whitespace in data when certain output types are used
2013 local print_data="$( echo -e "$1" )"
2015 # just using basic debugger stuff so you can tell which thing is printing out the data. This
2016 # should help debug kde 4 konvi issues when that is released into sid, we'll see. Turning off
2017 # the redundant debugger output which as far as I can tell does exactly nothing to help debugging.
2018 if [[ $DEBUG -gt 5 ]];then
2019 if [[ $KONVI -eq 1 ]];then
2020 # konvi doesn't seem to like \n characters, it just prints them literally
2021 # print_data="$( tr '\n' ' ' <<< "$print_data" )"
2022 # dcop "$DCPORT" "$DCOPOBJ" say "$DCSERVER" "$DCTARGET" "konvi='$KONVI' saying : '$print_data'"
2023 print_data="KP-$KONVI: $print_data"
2024 elif [[ $KONVI -eq 2 ]];then
2025 # echo "konvi='$KONVI' saying : '$print_data'"
2026 print_data="KP-$KONVI: $print_data"
2028 # echo "printing out: '$print_data'"
2029 print_data="P: $print_data"
2033 if [[ $KONVI -eq 1 && $B_DCOP == 'true' ]]; then ## dcop Konversation (<= 1.1 (qt3))
2034 # konvi doesn't seem to like \n characters, it just prints them literally
2035 $print_data="$( tr '\n' ' ' <<< "$print_data" )"
2036 dcop "$DCPORT" "$DCOPOBJ" say "$DCSERVER" "$DCTARGET" "$print_data"
2038 elif [[ $KONVI -eq 3 && $B_QDBUS == 'true' ]]; then ## dbus Konversation (> 1.2 (qt4))
2039 qdbus org.kde.konversation /irc say "$DCSERVER" "$DCTARGET" "$print_data"
2041 # elif [[ $IRC_CLIENT == 'X-Chat' ]]; then
2042 # qdbus org.xchat.service print "$print_data\n"
2045 # the -n is needed to avoid double spacing of output in terminal
2046 echo -ne "$print_data\n"
2051 ## this handles all verbose line construction with indentation/line starter
2052 ## args: $1 - null (, actually: " ") or line starter; $2 - line content
2056 printf "${C1}%-${INDENT}s${C2} %s" "$1" "$2"
2060 # this removes newline and pipes.
2061 # args: $1 - string to clean
2062 remove_erroneous_chars()
2065 ## RS is input record separator
2066 ## gsub is substitute;
2072 gsub(/\n$/,"") ## (newline; end of string) with (nothing)
2073 gsub(/\n/," "); ## (newline) with (space)
2074 gsub(/^ *| *$/, "") ## (pipe char) with (nothing)
2075 gsub(/ +/, " ") ## ( +) with (space)
2076 gsub(/ [ ]+/, " ") ## ([ ]+) with (space)
2077 gsub(/^ +| +$/, "") ## (pipe char) with (nothing)
2079 }' "$1" ## prints (returns) cleaned input
2083 #### -------------------------------------------------------------------
2084 #### parameter handling, print usage functions.
2085 #### -------------------------------------------------------------------
2087 # Get the parameters. Note: standard options should be lower case, advanced or testing, upper
2088 # args: $1 - full script startup args: $@
2092 local opt='' wget_test='' debug_data_type='' weather_flag='wW:'
2093 local use_short='true' # this is needed to trigger short output, every v/d/F/line trigger sets this false
2095 # if distro maintainers don't want the weather feature disable it
2096 if [[ $B_ALLOW_WEATHER == 'false' ]];then
2100 if [[ $1 == '--version' ]];then
2103 elif [[ $1 == '--help' ]];then
2106 elif [[ $1 == '--recommends' ]];then
2107 check_recommends_user_output
2109 # the short form only runs if no args output args are used
2110 # no need to run through these if there are no args
2111 # reserved for future use: -g for extra Graphics; -m for extra Machine; -d for extra Disk
2112 elif [[ -n $1 ]];then
2113 while getopts Abc:CdDfFGhHiIlMnNopPrRsSt:uUv:V${weather_flag}xzZ%@:!: opt
2116 A) B_SHOW_AUDIO='true'
2119 b) use_short='false'
2120 B_SHOW_BASIC_CPU='true'
2121 B_SHOW_BASIC_RAID='true'
2122 B_SHOW_DISK_TOTAL='true'
2123 B_SHOW_GRAPHICS='true'
2125 B_SHOW_MACHINE='true'
2126 B_SHOW_NETWORK='true'
2127 B_SHOW_SYSTEM='true'
2129 c) if [[ -n $( grep -E '^[0-9][0-9]?$' <<< $OPTARG ) ]];then
2132 B_RUN_COLOR_SELECTOR='true'
2133 COLOR_SELECTION='global'
2136 B_RUN_COLOR_SELECTOR='true'
2137 COLOR_SELECTION='irc-console'
2140 B_RUN_COLOR_SELECTOR='true'
2141 COLOR_SELECTION='irc-virtual-terminal'
2144 B_RUN_COLOR_SELECTOR='true'
2145 COLOR_SELECTION='irc'
2148 B_RUN_COLOR_SELECTOR='true'
2149 COLOR_SELECTION='virtual-terminal'
2152 B_RUN_COLOR_SELECTOR='true'
2153 COLOR_SELECTION='console'
2156 B_COLOR_SCHEME_SET='true'
2157 ## note: not sure about this, you'd think user values should be overridden, but
2158 ## we'll leave this for now
2159 if [[ -z $COLOR_SCHEME ]];then
2160 set_color_scheme "$OPTARG"
2165 error_handler 3 "$OPTARG"
2168 C) B_SHOW_CPU='true'
2171 d) B_SHOW_DISK='true'
2172 B_SHOW_FULL_OPTICAL='true'
2174 # error_handler 20 "-d has been replaced by -b"
2176 D) B_SHOW_DISK='true'
2179 f) B_SHOW_CPU='true'
2180 B_CPU_FLAGS_FULL='true'
2183 F) # B_EXTRA_DATA='true'
2184 B_SHOW_ADVANCED_NETWORK='true'
2186 # B_SHOW_BASIC_OPTICAL='true'
2189 B_SHOW_GRAPHICS='true'
2191 B_SHOW_MACHINE='true'
2192 B_SHOW_NETWORK='true'
2193 B_SHOW_PARTITIONS='true'
2195 B_SHOW_SENSORS='true'
2196 B_SHOW_SYSTEM='true'
2199 G) B_SHOW_GRAPHICS='true'
2203 B_SHOW_NETWORK='true'
2204 B_SHOW_ADVANCED_NETWORK='true'
2207 I) B_SHOW_INFO='true'
2210 l) B_SHOW_LABELS='true'
2211 B_SHOW_PARTITIONS='true'
2214 M) B_SHOW_MACHINE='true'
2217 n) B_SHOW_ADVANCED_NETWORK='true'
2218 B_SHOW_NETWORK='true'
2221 N) B_SHOW_NETWORK='true'
2224 o) B_SHOW_UNMOUNTED_PARTITIONS='true'
2227 p) B_SHOW_PARTITIONS_FULL='true'
2228 B_SHOW_PARTITIONS='true'
2231 P) B_SHOW_PARTITIONS='true'
2234 r) B_SHOW_REPOS='true'
2237 R) B_SHOW_RAID='true'
2238 # it turns out only users with mdraid software installed will have raid,
2239 # so unless -R is explicitly called, blank -b/-F/-v6 and less output will not show
2240 # error if file is missing.
2241 B_SHOW_RAID_R='true'
2244 s) B_SHOW_SENSORS='true'
2247 S) B_SHOW_SYSTEM='true'
2250 t) if [[ -n $( grep -E '^(c|m|cm|mc)([1-9]|1[0-9]|20)?$' <<< $OPTARG ) ]];then
2252 if [[ -n $( grep -E '[0-9]+' <<< $OPTARG ) ]];then
2253 PS_COUNT=$( sed 's/[^0-9]//g' <<< $OPTARG )
2255 if [[ -n $( grep 'c' <<< $OPTARG ) ]];then
2256 B_SHOW_PS_CPU_DATA='true'
2258 if [[ -n $( grep 'm' <<< $OPTARG ) ]];then
2259 B_SHOW_PS_MEM_DATA='true'
2262 error_handler 13 "$OPTARG"
2265 u) B_SHOW_UUIDS='true'
2266 B_SHOW_PARTITIONS='true'
2269 v) if [[ -n $( grep -E "^[0-9][0-9]?$" <<< $OPTARG ) && $OPTARG -le $VERBOSITY_LEVELS ]];then
2270 if [[ $OPTARG -ge 1 ]];then
2272 B_SHOW_BASIC_CPU='true'
2273 B_SHOW_DISK_TOTAL='true'
2274 B_SHOW_GRAPHICS='true'
2276 B_SHOW_SYSTEM='true'
2278 if [[ $OPTARG -ge 2 ]];then
2279 B_SHOW_BASIC_DISK='true'
2280 B_SHOW_BASIC_RAID='true'
2281 B_SHOW_MACHINE='true'
2282 B_SHOW_NETWORK='true'
2284 if [[ $OPTARG -ge 3 ]];then
2285 B_SHOW_ADVANCED_NETWORK='true'
2289 if [[ $OPTARG -ge 4 ]];then
2291 B_SHOW_PARTITIONS='true'
2293 if [[ $OPTARG -ge 5 ]];then
2295 B_SHOW_BASIC_OPTICAL='true'
2296 B_SHOW_SENSORS='true'
2297 B_SHOW_LABELS='true'
2301 if [[ $OPTARG -ge 6 ]];then
2302 B_SHOW_FULL_OPTICAL='true'
2303 B_SHOW_PARTITIONS_FULL='true'
2304 B_SHOW_UNMOUNTED_PARTITIONS='true'
2305 B_EXTRA_EXTRA_DATA='true'
2307 if [[ $OPTARG -ge 7 ]];then
2308 B_EXTRA_EXTRA_EXTRA_DATA='true'
2310 B_SHOW_RAID_R='true'
2313 error_handler 4 "$OPTARG"
2316 U) if [[ $B_ALLOW_UPDATE == 'true' ]];then
2317 script_self_updater "$SCRIPT_DOWNLOAD" 'svn server' "$opt"
2319 error_handler 17 "-$opt"
2322 V) print_version_info
2325 w) B_SHOW_WEATHER=true
2328 W) ALTERNATE_WEATHER_LOCATION=$( sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' <<< $OPTARG )
2329 if [[ -n $( grep -Esi '([^,]+,.+|[0-9-]+)' <<< $ALTERNATE_WEATHER_LOCATION ) ]];then
2333 error_handler 18 "-$opt: '$OPTARG'" "city,state OR latitude,longitude OR postal/zip code."
2336 # this will trigger either with x, xx, xxx or with Fx but not with xF
2337 x) if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
2338 B_EXTRA_EXTRA_EXTRA_DATA='true'
2339 elif [[ $B_EXTRA_DATA == 'true' ]];then
2340 B_EXTRA_EXTRA_DATA='true'
2345 z) B_OUTPUT_FILTER='true'
2347 Z) B_OVERRIDE_FILTER='true'
2352 H) show_options 'full'
2355 ## debuggers and testing tools
2356 %) B_HANDLE_CORRUPT_DATA='true'
2358 @) if [[ -n $( grep -E "^([1-9]|1[0-4])$" <<< $OPTARG ) ]];then
2360 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
2361 B_UPLOAD_DEBUG_DATA='true'
2364 # switch on logging only for -@ 8-10
2367 if [[ $OPTARG -eq 10 ]];then
2369 elif [[ $OPTARG -eq 9 ]];then
2370 B_LOG_FULL_DATA='true'
2372 B_USE_LOGGING='true'
2373 # pack the logging data for evals function start/end
2376 create_rotate_logfiles # create/rotate logfiles before we do anything else
2381 debug_data_type='sys'
2384 debug_data_type='xorg'
2387 debug_data_type='disk'
2390 debug_data_type='all'
2394 debug_data_collector $debug_data_type
2398 error_handler 9 "$OPTARG"
2401 !) # test for various supported methods
2403 1) B_TESTING_1='true'
2405 2) B_TESTING_2='true'
2407 3) B_TESTING_1='true'
2411 if [[ $B_ALLOW_UPDATE == 'true' ]];then
2414 script_self_updater "$SCRIPT_DOWNLOAD_DEV" 'dev server' "$opt $OPTARG"
2417 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_1" 'svn: branch one server' "$opt $OPTARG"
2420 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_2" 'svn: branch two server' "$opt $OPTARG"
2423 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_3" 'svn: branch three server' "$opt $OPTARG"
2426 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_4" 'svn: branch four server' "$opt $OPTARG"
2429 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_BSD" 'svn: branch bsd server' "$opt $OPTARG"
2432 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_GNUBSD" 'svn: branch gnubsd server' "$opt $OPTARG"
2435 script_self_updater "$OPTARG" 'alt server' "$opt <http...>"
2439 error_handler 17 "-$opt $OPTARG"
2443 B_RUNNING_IN_SHELL='true'
2452 ALTERNATE_FTP="$OPTARG"
2454 # for weather function, allows user to set an alternate weather location
2456 error_handler 19 "-$opt location=" "-W"
2458 *) error_handler 11 "$OPTARG"
2462 *) error_handler 7 "$1"
2467 ## this must occur here so you can use the debugging flag to show errors
2468 ## Reroute all error messages to the bitbucket (if not debugging)
2469 if [[ $DEBUG -eq 0 ]];then
2472 #((DEBUG)) && exec 2>&1 # This is for debugging konversation
2474 # after all the args have been processed, if no long output args used, run short output
2475 if [[ $use_short == 'true' ]];then
2476 B_SHOW_SHORT_OUTPUT='true'
2478 # just in case someone insists on using -zZ
2479 if [[ $B_OVERRIDE_FILTER == 'true' ]];then
2480 B_OUTPUT_FILTER='false'
2482 # change basic to full if user requested it or if arg overrides it
2483 if [[ $B_SHOW_RAID == 'true' && $B_SHOW_BASIC_RAID == 'true' ]];then
2484 B_SHOW_BASIC_RAID='false'
2491 ## print out help menu, not including Testing or Debugger stuff because it's not needed
2494 local color_scheme_count=$(( ${#A_COLOR_SCHEMES[@]} - 1 ))
2495 local partition_string='partition' partition_string_u='Partition'
2497 if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
2498 print_screen_output "Sorry, you can't run the help option in an IRC client."
2501 if [[ -n $BSD_TYPE ]];then
2502 partition_string='slice'
2503 partition_string_u='Slice'
2505 # print_lines_basic "0" "" ""
2506 # print_lines_basic "1" "" ""
2507 # print_lines_basic "2" "" ""
2508 # print_screen_output " "
2509 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."
2510 print_screen_output " "
2511 print_lines_basic "0" "" "The following options if used without -F, -b, or -v will show just option line(s): A, C, D, G, I, M, N, P, R, S, f, i, 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."
2513 print_screen_output "- - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
2514 print_screen_output "Output Control Options:"
2515 print_lines_basic "1" "-A" "Audio/sound card information."
2516 print_lines_basic "1" "-b" "Basic output, short form. Like $SCRIPT_NAME^-v^2, only minus hard disk names."
2517 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."
2518 print_lines_basic "1" "" "Supported color schemes: 0-$color_scheme_count Example: $SCRIPT_NAME^-c^11"
2519 print_lines_basic "1" "" "Color selectors for each type display (NOTE: irc and global only show safe color set):"
2520 # print_screen_output " Supported color schemes: 0-$color_scheme_count Example: $SCRIPT_NAME -c 11"
2521 # print_screen_output " Color selectors for each type display (NOTE: irc and global only show safe color set):"
2522 print_lines_basic "2" "94" "Console, out of X"
2523 print_lines_basic "2" "95" "Terminal, running in X - like xTerm"
2524 print_lines_basic "2" "96" "Gui IRC, running in X - like Xchat, Quassel, Konversation etc."
2525 print_lines_basic "2" "97" "Console IRC running in X - like irssi in xTerm"
2526 print_lines_basic "2" "98" "Console IRC not in X"
2527 print_lines_basic "2" "99" "Global - Overrides/removes all settings. Setting specific removes global."
2528 print_lines_basic "1" "-C" "CPU output, including per CPU clockspeed (if available)."
2529 print_lines_basic "1" "-d" "Optical drive data. Same as -Dd. See also -x and -xx."
2530 print_lines_basic "1" "-D" "Full hard Disk info, not only model, ie: /dev/sda ST380817AS 80.0GB. See also -x and -xx."
2531 print_lines_basic "1" "-f" "All cpu flags, triggers -C. Not shown with -F to avoid spamming. ARM cpus show 'features'."
2532 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 -x -d -f -u -l -o -p -t -r"
2533 print_lines_basic "1" "-G" "Graphic card information (card, display server type/version, resolution, glx renderer, version)."
2534 print_lines_basic "1" "-i" "Wan IP address, and shows local interfaces (requires ifconfig network tool). Same as -Nni. Not shown with -F for user security reasons, you shouldn't paste your local/wan IP."
2535 print_lines_basic "1" "-I" "Information: processes, uptime, memory, irc client (or shell type), $SCRIPT_NAME version."
2536 print_lines_basic "1" "-l" "${partition_string_u} labels. Default: short ${partition_string} -P. For full -p output, use: -pl (or -plu)."
2537 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."
2538 print_lines_basic "1" "-n" "Advanced Network card information. Same as -Nn. Shows interface, speed, mac id, state, etc."
2539 print_lines_basic "1" "-N" "Network card information. With -x, shows PCI BusID, Port number."
2540 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^"
2541 print_lines_basic "1" "-p" "Full ${partition_string} information (-P plus all other detected ${partition_string}s)."
2542 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."
2543 print_lines_basic "1" "-r" "Distro repository data. Supported repo types: APT; PACMAN; PISI; YUM; URPMQ; Ports."
2544 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."
2545 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."
2546 print_lines_basic "1" "-S" "System information: host name, kernel, desktop environment (if in X), distro"
2547 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"
2548 print_lines_basic "1" "" "Make sure to have no space between letters and numbers (-t^cm10 - right, -t^cm^10 - wrong)."
2549 print_lines_basic "1" "-u" "${partition_string_u} UUIDs. Default: short ${partition_string} -P. For full -p output, use: -pu (or -plu)."
2550 print_lines_basic "1" "-v" "Script verbosity levels. Verbosity level number is required. Should not be used with -b or -F"
2551 print_lines_basic "1" "" "Supported levels: 0-${VERBOSITY_LEVELS} Example: $SCRIPT_NAME^-v^4"
2552 print_lines_basic "2" "0" "Short output, same as: $SCRIPT_NAME"
2553 print_lines_basic "2" "1" "Basic verbose, -S + basic CPU + -G + basic Disk + -I."
2554 print_lines_basic "2" "2" "Networking card (-N), Machine (-M) data, shows basic hard disk data (names only), and, if present, basic raid (devices only, and if inactive, notes that). similar to: $SCRIPT_NAME^-b"
2555 print_lines_basic "2" "3" "Advanced CPU (-C), network (-n) data, and switches on -x advanced data option."
2556 print_lines_basic "2" "4" "${partition_string_u} size/filled data (-P) for (if present):/, /home, /var/, /boot. Shows full disk data (-D)."
2557 print_lines_basic "2" "5" "Audio card (-A); sensors (-s), ${partition_string} label (-l) and UUID (-u), short form of optical drives, standard raid data (-R)."
2558 print_lines_basic "2" "6" "Full ${partition_string} (-p), unmounted ${partition_string} (-o), optical drive (-d), full raid; triggers -xx."
2559 print_lines_basic "2" "7" "Network IP data (-i); triggers -xxx."
2561 # if distro maintainers don't want the weather feature disable it
2562 if [[ $B_ALLOW_WEATHER == 'true' ]];then
2563 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."
2564 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"
2566 print_lines_basic "1" "-x" "Adds the following extra data (only works with verbose or line output, not short form):"
2567 print_lines_basic "2" "-C" "CPU Flags, Bogomips on Cpu;"
2568 print_lines_basic "2" "-d" "Extra optical drive data; adds rev version to optical drive."
2569 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"
2570 print_lines_basic "2" "-G" "Direct rendering status for Graphics (in X)."
2571 print_lines_basic "2" "-G" "(for single gpu, nvidia driver) screen number gpu is running on."
2572 print_lines_basic "2" "-i" "IPv6 as well for LAN interface (IF) devices."
2573 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)."
2574 print_lines_basic "2" "-N -A" "Version/port(s)/driver version (if available) for Network/Audio;"
2575 print_lines_basic "2" "-N -A -G" "Network, audio, graphics, shows PCI Bus ID/Usb ID number of card."
2576 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"
2577 print_lines_basic "2" "-S" "Desktop toolkit if avaliable (GNOME/XFCE/KDE only); Kernel gcc version"
2578 print_lines_basic "2" "-t" "Memory use output to cpu (-xt c), and cpu use to memory (-xt m)."
2579 if [[ $B_ALLOW_WEATHER == 'true' ]];then
2580 print_lines_basic "2" "-w -W" "Wind speed and time zone (-w only)."
2582 print_lines_basic "1" "-xx" "Show extra, extra data (only works with verbose or line output, not short form):"
2583 print_lines_basic "2" "-A" "Chip vendor:product ID for each audio device."
2584 print_lines_basic "2" "-D" "Disk serial number."
2585 print_lines_basic "2" "-G" "Chip vendor:product ID for each video card."
2586 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."
2587 print_lines_basic "2" "-M" "Chassis information, bios rom size (dmidecode only), if data for either is available."
2588 print_lines_basic "2" "-N" "Chip vendor:product ID for each nic."
2589 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."
2590 print_lines_basic "2" "-S" "Display manager (dm) in desktop output, if in X (like kdm, gdm3, lightdm)."
2591 if [[ $B_ALLOW_WEATHER == 'true' ]];then
2592 print_lines_basic "2" "-w -W" "Humidity, barometric pressure."
2594 print_lines_basic "2" "-@ 11-14" "Automatically uploads debugger data tar.gz file to ftp.techpatterns.com. EG: $SCRIPT_NAME^-xx@14"
2595 print_lines_basic "1" "-xxx" "Show extra, extra, extra data (only works with verbose or line output, not short form):"
2596 print_lines_basic "2" "-S" "Panel/shell information in desktop output, if in X (like gnome-shell, cinnamon, mate-panel)."
2597 if [[ $B_ALLOW_WEATHER == 'true' ]];then
2598 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)."
2600 print_lines_basic "1" "-z" "Security filters for IP/Mac addresses, location, user home directory name. Default on for irc clients."
2601 print_lines_basic "1" "-Z" "Absolute override for output filters. Useful for debugging networking issues in irc for example."
2602 print_screen_output " "
2603 print_screen_output "Additional Options:"
2604 print_lines_basic "4" "-h --help" "This help menu."
2605 print_lines_basic "4" "-H" "This help menu, plus developer options. Do not use dev options in normal operation!"
2606 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. "
2607 if [[ $B_ALLOW_UPDATE == 'true' ]];then
2608 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."
2610 print_lines_basic "4" "-V --version" "$SCRIPT_NAME version information. Prints information then exits."
2611 print_screen_output " "
2612 print_screen_output "Debugging Options:"
2613 print_lines_basic "1" "-%" "Overrides defective or corrupted data."
2614 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."
2615 print_lines_basic "2" "1-7" "On screen debugger output"
2616 print_lines_basic "2" "8" "Basic logging"
2617 print_lines_basic "2" "9" "Full file/sys info logging"
2618 print_lines_basic "2" "10" "Color logging."
2619 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>"
2620 print_lines_basic "1" "" "For alternate ftp upload locations: Example: inxi^-!^ftp.yourserver.com/incoming^-xx@^14"
2621 print_lines_basic "2" "11" "With data file of xiin read of /sys."
2622 print_lines_basic "2" "12" "With xorg conf and log data, xrandr, xprop, xdpyinfo, glxinfo etc."
2623 print_lines_basic "2" "13" "With data from dev, disks, ${partition_string}s, etc., plus xiin data file."
2624 print_lines_basic "2" "14" "Everything, full data collection."
2625 print_screen_output " "
2626 print_screen_output "Advanced Options:"
2627 print_lines_basic "1" "-! 31" "Turns off hostname in output. Useful if showing output from servers etc."
2628 print_lines_basic "1" "-! 32" "Turns on hostname in output. Overrides global B_SHOW_HOST='false'"
2630 if [[ $1 == 'full' ]];then
2631 print_screen_output " "
2632 print_screen_output "Developer and Testing Options (Advanced):"
2633 print_lines_basic "1" "-! 1" "Sets testing flag B_TESTING_1='true' to trigger testing condition 1."
2634 print_lines_basic "1" "-! 2" "Sets testing flag B_TESTING_2='true' to trigger testing condition 2."
2635 print_lines_basic "1" "-! 3" "Sets flags B_TESTING_1='true' and B_TESTING_2='true'."
2636 if [[ $B_ALLOW_UPDATE == 'true' ]];then
2637 print_lines_basic "1" "-! 10" "Triggers an update from the primary dev download server instead of svn."
2638 print_lines_basic "1" "-! 11" "Triggers an update from svn branch one - if present, of course."
2639 print_lines_basic "1" "-! 12" "Triggers an update from svn branch two - if present, of course."
2640 print_lines_basic "1" "-! 13" "Triggers an update from svn branch three - if present, of course."
2641 print_lines_basic "1" "-! 14" "Triggers an update from svn branch four - if present, of course."
2642 print_lines_basic "1" "-! 15" "Triggers an update from svn branch BSD - if present, of course."
2643 print_lines_basic "1" "-! 16" "Triggers an update from svn branch GNUBSD - if present, of course."
2644 print_lines_basic "1" "-! <http://......>" "Triggers an update from whatever server you list."
2646 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. "
2647 print_lines_basic "1" "" "Example: inxi^-!^ftp.yourserver.com/incoming^-xx@^14"
2649 print_screen_output " "
2652 # uses $TERM_COLUMNS to set width using $COLS_MAX as max width
2653 # IMPORTANT: minimize use of subshells here or the output is too slow
2654 # args: $1 - 0 1 2 3 4 for indentation level; $2 -line starter, like -m; $3 - content of block.
2657 local line_width=$COLS_MAX
2658 local print_string='' indent_inner='' indent_full='' indent_x=''
2659 local indent_working='' indent_working_full=''
2660 local line_starter='' line_1_starter='' line_x_starter=''
2661 # note: to create a padded string below
2662 local fake_string=' ' temp_count='' line_count='' spacer=''
2663 local indent_main=6 indent_x='' b_indent_x='true'
2666 # for no options, start at left edge
2672 1) indent_full=$indent_main
2674 if [[ $temp_count -le $indent_full ]];then
2675 indent_working=$indent_full
2677 indent_working=$temp_count #$(( $temp_count + 1 ))
2679 line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_working\}$/& /;ta" <<< $2 )"
2681 # first left pad 2 and 3, then right pad them
2682 2) indent_full=$(( $indent_main + 6 ))
2685 if [[ $temp_count -le $indent_inner ]];then
2686 indent_working=$indent_inner
2687 #indent_working_full=$indent_full
2689 indent_working=$(( $temp_count + 1 ))
2690 #indent_working_full=$(( $indent_full - $indent_inner - 1 ))
2692 line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_working\}$/& /;ta" <<< $2 )"
2693 line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_full\}$/ &/;ta" <<< "$line_1_starter" )"
2695 3) indent_full=$(( $indent_main + 8 ))
2698 if [[ $temp_count -le $indent_inner ]];then
2699 indent_working=$indent_inner
2701 indent_working=$(( $temp_count + 1 ))
2703 line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_working\}$/& /;ta" <<< $2 )"
2704 line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_full\}$/ &/;ta" <<< "$line_1_starter" )"
2707 4) indent_full=$(( $indent_main + 8 ))
2709 if [[ $temp_count -lt $indent_full ]];then
2710 indent_working=$indent_full
2712 indent_working=$temp_count #$(( $temp_count + 1 ))
2714 line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_working\}$/& /;ta" <<< $2 )"
2718 if [[ $b_indent_x == 'true' ]];then
2719 indent_x=$(( $indent_full + 1 ))
2720 line_x_starter="$(printf "%${indent_x}s" '')"
2723 line_count=$(( $line_width - $indent_full ))
2725 # bash loop is slow, only run this if required
2726 if [[ ${#3} -gt $line_count ]];then
2729 temp_string="$print_string$spacer$word"
2731 if [[ ${#temp_string} -lt $line_count ]];then
2732 print_string=$temp_string # lose any white space start/end
2733 # echo -n $(( $line_width - $indent_full ))
2735 if [[ -n $line_1_starter ]];then
2736 line_starter="$line_1_starter"
2739 line_starter="$line_x_starter"
2741 # clean up forced connections, ie, stuff we don't want wrapping
2742 print_string=${print_string//\^/ }
2743 print_screen_output "$line_starter$print_string"
2744 print_string="$word$spacer" # needed to handle second word on new line
2753 # print anything left over
2754 if [[ -n $print_string ]];then
2755 if [[ -n $line_1_starter ]];then
2756 line_starter="$line_1_starter"
2759 line_starter="$line_x_starter"
2761 print_string=${print_string//\^/ }
2762 print_screen_output "$line_starter$print_string"
2765 # 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'
2766 # 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'
2767 # print_lines_basic '2' '12' 'and its sss substring'
2768 # 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'
2771 ## print out version information for -V/--version
2772 print_version_info()
2774 # if not in PATH could be either . or directory name, no slash starting
2775 local script_path=$SCRIPT_PATH script_symbolic_start=''
2776 if [[ $script_path == '.' ]];then
2777 script_path=$( pwd )
2778 elif [[ -z $( grep '^/' <<< "$script_path" ) ]];then
2779 script_path="$( pwd )/$script_path"
2781 # handle if it's a symbolic link, rare, but can happen with script directories in irc clients
2782 # which would only matter if user starts inxi with -! 30 override in irc client
2783 if [[ -L $script_path/$SCRIPT_NAME ]];then
2784 script_symbolic_start=$script_path/$SCRIPT_NAME
2785 script_path=$( readlink $script_path/$SCRIPT_NAME )
2786 script_path=$( dirname $script_path )
2788 local last_modified=$( parse_version_data 'date' )
2789 local year_modified=$( gawk '{print $NF}' <<< "$last_modified" )
2791 print_screen_output "$SCRIPT_NAME $SCRIPT_VERSION_NUMBER-$SCRIPT_PATCH_NUMBER ($last_modified)"
2792 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
2793 print_screen_output "Program Location: $script_path"
2794 if [[ -n $script_symbolic_start ]];then
2795 print_screen_output "Started via symbolic link: $script_symbolic_start"
2797 print_lines_basic "0" "" "Website:^http://inxi.goooglecode.com"
2798 print_lines_basic "0" "" "IRC:^irc.oftc.net channel:^#smxi"
2799 print_lines_basic "0" "" "Forums:^http://techpatterns.com/forums/forum-33.html"
2800 print_screen_output " "
2801 print_lines_basic "0" "" "$SCRIPT_NAME - the universal, portable, system information tool for console and irc."
2802 print_screen_output " "
2803 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."
2804 print_lines_basic "0" "" "Subsequent changes and modifications (after Infobash 3.02): Copyright (C) 2008-$year_modified Scott Rogers, Harald Hope, aka trash80 & h2"
2805 print_screen_output " "
2806 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)"
2810 ########################################################################
2812 ########################################################################
2814 #### -------------------------------------------------------------------
2815 #### initial startup stuff
2816 #### -------------------------------------------------------------------
2818 # Determine where inxi was run from, set IRC_CLIENT and IRC_CLIENT_VERSION
2822 local Irc_Client_Path='' irc_client_path_lower='' non_native_konvi='' i=''
2823 local B_Non_Native_App='false' pppid='' App_Working_Name=''
2824 local b_qt4_konvi='false' ps_parent=''
2826 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
2828 unset IRC_CLIENT_VERSION
2829 # elif [[ -n $PPID ]];then
2830 elif [[ -n $PPID && -f /proc/$PPID/exe ]];then
2831 if [[ $B_OVERRIDE_FILTER != 'true' ]];then
2832 B_OUTPUT_FILTER='true'
2834 Irc_Client_Path=$( readlink /proc/$PPID/exe )
2835 # Irc_Client_Path=$( ps -p $PPID | gawk '!/[[:space:]]*PID/ {print $5}' )
2836 # echo $( ps -p $PPID )
2837 irc_client_path_lower=$( tr '[:upper:]' '[:lower:]' <<< $Irc_Client_Path )
2838 App_Working_Name=$( basename $irc_client_path_lower )
2839 # handles the xchat/sh/bash/dash cases, and the konversation/perl cases, where clients
2840 # report themselves as perl or unknown shell. IE: when konversation starts inxi
2841 # from inside itself, as a script, the parent is konversation/xchat, not perl/bash etc
2842 # note: perl can report as: perl5.10.0, so it needs wildcard handling
2843 case $App_Working_Name in
2844 # bsd will never use this section
2845 bash|dash|sh|python*|perl*) # We want to know who wrapped it into the shell or perl.
2846 pppid="$( ps -p $PPID -o ppid --no-headers | sed 's/[[:space:]]//g' )"
2847 if [[ -n $pppid && -f /proc/$pppid/exe ]];then
2848 Irc_Client_Path="$( readlink /proc/$pppid/exe )"
2849 irc_client_path_lower="$( tr '[:upper:]' '[:lower:]' <<< $Irc_Client_Path )"
2850 App_Working_Name=$( basename $irc_client_path_lower )
2851 B_Non_Native_App='true'
2855 # sets version number if it can find it
2856 get_irc_client_version
2858 ## lets look to see if qt4_konvi is the parent. There is no direct way to tell, so lets infer it.
2859 ## because $PPID does not work with qt4_konvi, the above case does not work
2860 if [[ $B_OVERRIDE_FILTER != 'true' ]];then
2861 B_OUTPUT_FILTER='true'
2863 b_qt4_konvi=$( is_this_qt4_konvi )
2864 if [[ $b_qt4_konvi == 'true' ]];then
2866 IRC_CLIENT='Konversation'
2867 IRC_CLIENT_VERSION=" $( konversation -v | gawk '
2869 for ( i=2; i<=NF; i++ ) {
2880 # this should handle certain cases where it's ssh or some other startup tool
2881 # that falls through all the other tests
2882 if [[ $BSD_TYPE != 'bsd' ]];then
2883 App_Working_Name=$(ps -p $PPID --no-headers 2>/dev/null | gawk '{print $NF}' )
2885 # without --no-headers we need the second line
2886 App_Working_Name=$(ps -p $PPID 2>/dev/null | gawk '/^[0-9]+/ {print $5}' )
2889 if [[ -n $App_Working_Name ]];then
2890 Irc_Client_Path=$App_Working_Name
2891 B_Non_Native_App='false'
2892 get_irc_client_version
2893 if [[ -z $IRC_CLIENT ]];then
2894 IRC_CLIENT=$App_Working_Name
2897 IRC_CLIENT="PPID=\"$PPID\" - empty?"
2898 unset IRC_CLIENT_VERSION
2903 log_function_data "IRC_CLIENT: $IRC_CLIENT :: IRC_CLIENT_VERSION: $IRC_CLIENT_VERSION :: PPID: $PPID"
2906 # note: all variables set in caller so no need to pass
2907 get_irc_client_version()
2910 # replacing loose detection with tight detection, bugs will be handled with app names
2912 case $App_Working_Name in
2913 # check for shell first
2915 unset IRC_CLIENT_VERSION
2916 IRC_CLIENT="Shell wrapper"
2918 # now start on irc clients, alphabetically
2920 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk '
2923 gsub(/[()]|bitchx-/,"",a)
2933 B_CONSOLE_IRC='true'
2937 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
2940 B_CONSOLE_IRC='true'
2944 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
2950 # the hexchat author decided to make --version/-v return a gtk dialogue box, lol...
2951 # so we need to read the actual config file for hexchat. Note that older hexchats
2952 # used xchat config file, so test first for default, then legacy. Because it's possible
2953 # for this file to be use edited, doing some extra checks here.
2954 if [[ -f ~/.config/hexchat/hexchat.conf ]];then
2955 file_data="$( cat ~/.config/hexchat/hexchat.conf )"
2956 elif [[ -f ~/.config/hexchat/xchat.conf ]];then
2957 file_data="$( cat ~/.config/hexchat/xchat.conf )"
2959 if [[ -n $file_data ]];then
2960 IRC_CLIENT_VERSION=$( gawk '
2965 /^[[:space:]]*version/ {
2966 # get rid of the space if present
2967 gsub(/[[:space:]]*/, "", $2 )
2969 exit # usually this is the first line, no point in continuing
2970 }' <<< "$file_data" )
2972 IRC_CLIENT_VERSION=" $IRC_CLIENT_VERSION"
2974 IRC_CLIENT_VERSION=' N/A'
2976 IRC_CLIENT="HexChat"
2979 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
2982 B_CONSOLE_IRC='true'
2986 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
2989 B_CONSOLE_IRC='true'
2992 konversation) ## konvi < 1.2 (qt4)
2993 # this is necessary to avoid the dcop errors from starting inxi as a /cmd started script
2994 if [[ $B_Non_Native_App == 'true' ]];then ## true negative is confusing
2996 else # if native app
2999 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk '
3001 for ( i=2; i<=NF; i++ ) {
3012 T=($IRC_CLIENT_VERSION)
3013 if [[ ${T[0]} == *+* ]];then
3014 # < Sho_> locsmif: The version numbers of SVN versions look like this:
3015 # "<version number of last release>+ #<build number", i.e. "1.0+ #3177" ...
3016 # for releases we remove the + and build number, i.e. "1.0" or soon "1.0.1"
3017 IRC_CLIENT_VERSION=" CVS $IRC_CLIENT_VERSION"
3020 IRC_CLIENT_VERSION=" ${T[0]}"
3023 # Remove any dots except the first, and make sure there are no trailing zeroes,
3024 T2=$( echo "$T2" | gawk '{
3030 # Since Konversation 1.0, the DCOP interface has changed a bit: dcop "$DCPORT" Konversation ..etc
3031 # becomes : dcop "$DCPORT" default ... or dcop "$DCPORT" irc ..etc. So we check for versions smaller
3032 # than 1 and change the DCOP parameter/object accordingly.
3033 if [[ ${T2} -lt 1 ]];then
3034 DCOPOBJ="Konversation"
3036 IRC_CLIENT="Konversation"
3039 IRC_CLIENT_VERSION=" $( kopete -v | gawk '
3047 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v 2>&1 | gawk '{
3048 for ( i=2; i<=NF; i++) {
3061 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
3067 # sample: quassel -v
3069 # KDE: 4.2.65 (KDE 4.2.65 (KDE 4.3 >= 20090226))
3070 # Quassel IRC: v0.4.0 [+60] (git-22effe5)
3071 # note: early < 0.4.1 quassels do not have -v
3072 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v 2>/dev/null | gawk -F ': ' '
3081 # this handles pre 0.4.1 cases with no -v
3082 if ( clientVersion == "" ) {
3083 clientVersion = "(pre v0.4.1)"
3087 # now handle primary, client, and core. quasselcore doesn't actually
3088 # handle scripts with exec, but it's here just to be complete
3089 case $App_Working_Name in
3091 IRC_CLIENT="Quassel [M]"
3094 IRC_CLIENT="Quassel"
3097 IRC_CLIENT="Quassel (core)"
3102 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v ) "
3103 B_CONSOLE_IRC='true'
3104 IRC_CLIENT="Weechat"
3107 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
3110 IRC_CLIENT="X-Chat-Gnome"
3113 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
3118 # then do some perl type searches, do this last since it's a wildcard search
3120 unset IRC_CLIENT_VERSION
3121 # KSirc is one of the possibilities now. KSirc is a wrapper around dsirc, a perl client
3123 for (( i=0; i <= $CMDL_MAX; i++ ))
3125 case ${A_CMDL[i]} in
3128 # Dynamic runpath detection is too complex with KSirc, because KSirc is started from
3129 # kdeinit. /proc/<pid of the grandparent of this process>/exe is a link to /usr/bin/kdeinit
3130 # with one parameter which contains parameters separated by spaces(??), first param being KSirc.
3131 # Then, KSirc runs dsirc as the perl irc script and wraps around it. When /exec is executed,
3132 # dsirc is the program that runs inxi, therefore that is the parent process that we see.
3133 # You can imagine how hosed I am if I try to make inxi find out dynamically with which path
3134 # KSirc was run by browsing up the process tree in /proc. That alone is straightjacket material.
3135 # (KSirc sucks anyway ;)
3136 IRC_CLIENT_VERSION=" $( ksirc -v | gawk '
3145 B_CONSOLE_IRC='true'
3146 set_perl_python_konvi "$App_Working_Name"
3149 # B_CONSOLE_IRC='true' # are there even any python type console irc clients? check.
3150 set_perl_python_konvi "$App_Working_Name"
3152 # then unset, set unknown data
3154 IRC_CLIENT="Unknown : ${Irc_Client_Path##*/}"
3155 unset IRC_CLIENT_VERSION
3158 if [[ $SHOW_IRC -lt 2 ]];then
3159 unset IRC_CLIENT_VERSION
3163 # args: $1 - App_Working_Name
3164 set_perl_python_konvi()
3166 if [[ -z $IRC_CLIENT_VERSION ]];then
3167 # this is a hack to try to show konversation if inxi is running but started via /cmd
3168 if [[ -n $( grep -i 'konversation' <<< "$Ps_aux_Data" | grep -v 'grep' ) && $B_RUNNING_IN_DISPLAY == 'true' ]];then
3169 IRC_CLIENT='Konversation'
3170 IRC_CLIENT_VERSION=" $( konversation --version 2>/dev/null | gawk '/^Konversation/ {print $2}' )"
3171 B_CONSOLE_IRC='false'
3173 IRC_CLIENT="Unknown $1 client"
3178 ## try to infer the use of Konversation >= 1.2, which shows $PPID improperly
3179 ## no known method of finding Kovni >= 1.2 as parent process, so we look to see if it is running,
3180 ## and all other irc clients are not running.
3183 local konvi_qt4_client='' konvi_dbus_exist='' konvi_pid='' konvi_home_dir=''
3184 local konvi='' konvi_qt4_ver='' b_is_qt4=''
3186 # fringe cases can throw error, always if untested app, use 2>/dev/null after testing if present
3187 if [[ $B_QDBUS == 'true' ]];then
3188 konvi_dbus_exist=$( qdbus 2>/dev/null | grep "org.kde.konversation" )
3190 # sabayon uses /usr/share/apps/konversation as path
3191 if [[ -n $konvi_dbus_exist ]] && [[ -e /usr/share/kde4/apps/konversation || -e /usr/share/apps/konversation ]]; then
3192 konvi_pid=$( ps -A | gawk 'BEGIN{IGNORECASE=1} /konversation/ { print $1 }' )
3193 konvi_home_dir=$( readlink /proc/$konvi_pid/exe )
3194 konvi=$( echo $konvi_home_dir | sed "s/\// /g" )
3197 if [[ ${konvi[2]} == 'konversation' ]];then
3198 konvi_qt4_ver=$( konversation -v | grep -i 'konversation' )
3199 # note: we need to change this back to a single dot number, like 1.3, not 1.3.2
3200 konvi_qt4_client=$( echo "$konvi_qt4_ver" | gawk '{ print $2 }' | cut -d '.' -f 1,2 )
3202 if [[ $konvi_qt4_client > 1.1 ]]; then
3210 log_function_data "b_is_qt4: $b_is_qt4"
3212 ## for testing this module
3213 #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]}"
3216 # This needs some cleanup and comments, not quite understanding what is happening, although generally output is known
3217 # Parse the null separated commandline under /proc/<pid passed in $1>/cmdline
3224 if [[ ! -e /proc/$ppid/cmdline ]];then
3228 ##print_screen_output "Marker"
3229 ##print_screen_output "\$ppid='$ppid' -=- $(< /proc/$ppid/cmdline)"
3231 ## note: need to figure this one out, and ideally clean it up and make it readable
3232 while read -d $'\0' L && [[ $i -lt 32 ]]
3234 A_CMDL[i++]="$L" ## note: make sure this is valid - What does L mean? ##
3235 done < /proc/$ppid/cmdline
3236 ##print_screen_output "\$i='$i'"
3237 if [[ $i -eq 0 ]];then
3238 A_CMDL[0]=$(< /proc/$ppid/cmdline)
3239 if [[ -n ${A_CMDL[0]} ]];then
3244 log_function_data "CMDL_MAX: $CMDL_MAX"
3248 #### -------------------------------------------------------------------
3250 #### -------------------------------------------------------------------
3251 ## create array of sound cards installed on system, and if found, use asound data as well
3255 local i='' alsa_data='' audio_driver='' device_count='' temp_array=''
3258 # this first step handles the drivers for cases where the second step fails to find one
3259 device_count=$( echo "$Lspci_v_Data" | grep -iEc '(multimedia audio controller|audio device)' )
3260 if [[ $device_count -eq 1 ]] && [[ $B_ASOUND_DEVICE_FILE == 'true' ]];then
3261 audio_driver=$( gawk -F ']: ' '
3265 # filtering out modems and usb devices like webcams, this might get a
3266 # usb audio card as well, this will take some trial and error
3267 $0 !~ /modem|usb|webcam/ {
3268 driver=gensub( /^(.+)( - )(.+)$/, "\\1", 1, $2 )
3269 gsub(/^ +| +$/,"",driver)
3270 if ( driver != "" ){
3273 }' $FILE_ASOUND_DEVICE )
3274 log_function_data 'cat' "$FILE_ASOUND_DEVICE"
3277 # this is to safeguard against line breaks from results > 1, which if inserted into following
3278 # array will create a false array entry. This is a hack, not a permanent solution.
3279 audio_driver=$( echo $audio_driver )
3280 # now we'll build the main audio data, card name, driver, and port. If no driver is found,
3281 # and if the first method above is not null, and one card is found, it will use that instead.
3282 A_AUDIO_DATA=( $( echo "$Lspci_v_Data" | gawk -F ': ' -v audioDriver="$audio_driver" '
3286 /multimedia audio controller|audio device/ {
3287 audioCard=gensub(/^[0-9a-f:\.]+ [^:]+: (.+)$/,"\\1","g",$0)
3288 # The doublequotes are necessary because of the pipes in the variable.
3289 gsub(/'"$BAN_LIST_NORMAL"'/, "", audioCard)
3290 gsub(/,/, " ", audioCard)
3291 gsub(/^ +| +$/, "", audioCard)
3292 gsub(/ [ \t]+/, " ", audioCard)
3293 aPciBusId[audioCard] = gensub(/(^[0-9a-f:\.]+) [^:]+: .+$/,"\\1","g",$0)
3296 # loop until you get to the end of the data block
3297 while (getline && !/^$/) {
3299 if (/driver in use/) {
3300 drivers[audioCard] = drivers[audioCard] gensub( /(.*): (.*)/ ,"\\2", "g" ,$0 ) ""
3302 else if (/kernel modules:/) {
3303 modules[audioCard] = modules[audioCard] gensub( /(.*): (.*)/ ,"\\2" ,"g" ,$0 ) ""
3306 portsTemp = gensub(/\t*I\/O ports at (.*) \[.*\]/,"\\1","g",$0)
3307 ports[audioCard] = ports[audioCard] portsTemp " "
3322 if (drivers[i] != "") {
3323 useDrivers=drivers[i]
3328 # little trick here to try to catch the driver if there is
3329 # only one card and it was null, from the first test of asound/cards
3330 if (drivers[i] != "") {
3331 useDrivers=drivers[i]
3333 else if ( audioDriver != "" ) {
3334 useDrivers=audioDriver
3337 if (ports[i] != "") {
3340 if (modules[i] != "" ) {
3341 useModules = modules[i]
3343 if ( aPciBusId[i] != "" ) {
3344 usePciBusId = aPciBusId[i]
3346 # create array primary item for master array
3347 sub( / $/, "", usePorts ) # clean off trailing whitespace
3348 print a[j] "," useDrivers "," usePorts "," useModules "," usePciBusId
3353 # in case of failure of first check do this instead
3354 if [[ ${#A_AUDIO_DATA[@]} -eq 0 ]] && [[ $B_ASOUND_DEVICE_FILE == 'true' ]];then
3355 A_AUDIO_DATA=( $( gawk -F ']: ' '
3359 $1 !~ /modem/ && $2 !~ /modem/ {
3360 card=gensub( /^(.+)( - )(.+)$/, "\\3", 1, $2 )
3361 driver=gensub( /^(.+)( - )(.+)$/, "\\1", 1, $2 )
3365 }' $FILE_ASOUND_DEVICE ) )
3369 # handle cases where card detection fails, like in PS3, where lspci gives no output, or headless boxes..
3370 if [[ ${#A_AUDIO_DATA[@]} -eq 0 ]];then
3371 A_AUDIO_DATA[0]='Failed to Detect Sound Card!'
3373 temp_array=${A_AUDIO_DATA[@]}
3374 log_function_data "A_AUDIO_DATA: $temp_array"
3378 # alsa usb detection by damentz
3380 get_audio_usb_data()
3383 local usb_proc_file='' array_count='' usb_data='' usb_id='' lsusb_path='' lsusb_data=''
3387 lsusb_path=$( type -p lsusb )
3388 if [[ -n $lsusb_path ]];then
3389 lsusb_data=$( $lsusb_path 2>/dev/null )
3391 log_function_data 'raw' "usb_data:\n$lsusb_data"
3392 if [[ -n $lsusb_data ]];then
3393 # for every sound card symlink in /proc/asound - display information about it
3394 for usb_proc_file in /proc/asound/*
3396 # If the file is a symlink, and contains an important usb exclusive file: continue
3397 if [[ -L $usb_proc_file && -e $usb_proc_file/usbid ]]; then
3398 # find the contents of usbid in lsusb and print everything after the 7th word on the
3399 # corresponding line. Finally, strip out commas as they will change the driver :)
3400 usb_id=$( cat $usb_proc_file/usbid )
3401 usb_data=$( grep "$usb_id" <<< "$lsusb_data" )
3402 if [[ -n $usb_data && -n $usb_id ]];then
3410 gsub( /,/, " ", $0 )
3411 gsub(/'"$BAN_LIST_NORMAL"'/, "", $0)
3412 gsub(/ [ \t]+/, " ", $0)
3413 for ( i=7; i<= NF; i++ ) {
3414 string = string separator $i
3419 print string ",USB Audio,,," $2 "-" $4 "," $6
3421 }' <<< "$usb_data" )
3423 # this method is interesting, it shouldn't work but it does
3424 #A_AUDIO_DATA=( "${A_AUDIO_DATA[@]}" "$usb_data,USB Audio,," )
3425 # but until we learn why the above worked, I'm using this one, which is safer
3426 if [[ -n $usb_data ]];then
3427 array_count=${#A_AUDIO_DATA[@]}
3428 A_AUDIO_DATA[$array_count]="$usb_data"
3434 temp_array=${A_AUDIO_DATA[@]}
3435 log_function_data "A_AUDIO_DATA: $temp_array"
3440 get_audio_alsa_data()
3443 local alsa_data='' temp_array=''
3445 # now we'll get the alsa data if the file exists
3446 if [[ $B_ASOUND_VERSION_FILE == 'true' ]];then
3455 # some alsa strings have the build date in (...)
3456 # remove trailing . and remove possible second line if compiled by user
3458 gsub( /Driver | [(].*[)]|\.$/,"",$0 )
3460 gsub(/^ +| +$/, "", $0)
3461 gsub(/ [ \t]+/, " ", $0)
3462 sub(/Advanced Linux Sound Architecture/, "ALSA", $0)
3463 if ( $1 == "ALSA" ){
3467 print alsa "," version
3468 }' $FILE_ASOUND_VERSION ) )
3470 log_function_data 'cat' "$FILE_ASOUND_VERSION"
3472 temp_array=${A_ALSA_DATA[@]}
3473 log_function_data "A_ALSA_DATA: $temp_array"
3477 ## create A_CPU_CORE_DATA, currently with two values: integer core count; core string text
3478 ## return value cpu core count string, this helps resolve the multi redundant lines of old style output
3479 get_cpu_core_count()
3482 local cpu_physical_count='' cpu_core_count='' cpu_type='' cpu_alpha_count=''
3483 if [[ $B_CPUINFO_FILE == 'true' ]]; then
3484 # load the A_CPU_TYPE_PCNT_CCNT core data array
3485 get_cpu_ht_multicore_smp_data
3486 ## Because of the upcoming release of cpus with core counts over 6, a count of cores is given after Deca (10)
3487 # count the number of processors given
3488 cpu_physical_count=${A_CPU_TYPE_PCNT_CCNT[1]}
3489 cpu_core_count=${A_CPU_TYPE_PCNT_CCNT[2]}
3490 cpu_type=${A_CPU_TYPE_PCNT_CCNT[0]}
3492 # match the numberic value to an alpha value
3493 cpu_alpha_count=$( get_cpu_core_count_alpha "$cpu_core_count" )
3495 # create array, core count integer; core count string
3496 # A_CPU_CORE_DATA=( "$cpu_core_count" "$cpu_alpha_count Core$cpu_type" )
3497 A_CPU_CORE_DATA=( "$cpu_physical_count" "$cpu_alpha_count" "$cpu_type" "$cpu_core_count" )
3498 elif [[ -n $BSD_TYPE ]];then
3501 if [[ $BSD_VERSION == 'openbsd' ]];then
3504 cpu_core_count=$( gawk -F "$gawk_fs" '
3505 # note: on openbsd can also be hw.ncpufound so exit after first
3509 }' <<< "$Sysctl_a_Data" )
3510 if [[ -n $( grep -E '^[0-9]+$' <<< "$cpu_core_count" ) ]];then
3511 cpu_alpha_count=$( get_cpu_core_count_alpha "$cpu_core_count" )
3512 if [[ $cpu_core_count -gt 1 ]];then
3516 cpu_physical_count=1
3517 A_CPU_CORE_DATA=( "$cpu_physical_count" "$cpu_alpha_count" "$cpu_type" "$cpu_core_count" )
3519 temp_array=${A_CPU_CORE_DATA[@]}
3520 log_function_data "A_CPU_CORE_DATA: $temp_array"
3524 # args: $1 - integer core count
3525 get_cpu_core_count_alpha()
3528 local cpu_alpha_count=''
3531 1) cpu_alpha_count='Single';;
3532 2) cpu_alpha_count='Dual';;
3533 3) cpu_alpha_count='Triple';;
3534 4) cpu_alpha_count='Quad';;
3535 5) cpu_alpha_count='Penta';;
3536 6) cpu_alpha_count='Hexa';;
3537 7) cpu_alpha_count='Hepta';;
3538 8) cpu_alpha_count='Octa';;
3539 9) cpu_alpha_count='Ennea';;
3540 10) cpu_alpha_count='Deca';;
3541 *) cpu_alpha_count='Multi';;
3544 echo $cpu_alpha_count
3549 ## main cpu data collector
3553 local i='' j='' cpu_array_nu='' a_cpu_working='' multi_cpu='' bits='' temp_array=''
3554 local bsd_cpu_flags=''
3556 if [[ $B_CPUINFO_FILE == 'true' ]];then
3557 # stop script for a bit to let cpu slow down before parsing cpu /proc file
3564 # need to prime nr for arm cpus, which do not have processor number output in some cases
3569 # TAKE STRONGER NOTE: \t+ does NOT always work, MUST be [ \t]+
3570 # TAKE NOTE: \t+ will work for $FILE_CPUINFO, but SOME ARBITRARY FILE used for TESTING might contain SPACES!
3571 # Therefore PATCH to use [ \t]+ when TESTING!
3572 /^processor[ \t]+:/ {
3574 gsub(/^ +| +$/, "", $NF)
3575 if ( $NF ~ "^[0-9]+$" ) {
3579 if ( $NF ~ "^ARM" ) {
3584 cpu[nr, "model"] = $NF
3588 /^model name|^cpu\t+:/ {
3589 gsub(/'"$BAN_LIST_NORMAL"'/, "", $NF )
3590 gsub(/'"$BAN_LIST_CPU"'/, "", $NF )
3592 gsub(/^ +| +$/, "", $NF)
3593 gsub(/ [ \t]+/, " ", $NF)
3594 cpu[nr, "model"] = $NF
3595 if ( $NF ~ "^ARM" ) {
3600 /^cpu MHz|^clock\t+:/ {
3613 gsub(/MHZ/,"",$NF) ## clears out for cell cpu
3614 gsub(/.00[0]+$/,".00",$NF) ## clears out excessive zeros
3615 cpu[nr, "speed"] = $NF
3619 cpu[nr, "cache"] = $NF
3622 /^flags|^features/ {
3623 cpu[nr, "flags"] = $NF
3624 # not all ARM cpus show ARM in model name
3625 if ( $1 ~ /^features/ ) {
3631 cpu[nr, "bogomips"] = $NF
3635 gsub(/genuine|authentic/,"",$NF)
3636 cpu[nr, "vendor"] = tolower( $NF )
3640 #if (!nr) { print ",,,"; exit } # <- should this be necessary or should bash handle that
3641 for ( i = 0; i <= nr; i++ ) {
3642 # note: assuming bogomips for arm at 1 x clock
3643 # http://en.wikipedia.org/wiki/BogoMips ARM could change so watch this
3644 # maybe add: && bArm == "true" but I think most of the bogomips roughly equal cpu speed if not amd/intel
3645 if ( cpu[i, "bogomips"] != "" && cpu[i, "speed"] == "" ) {
3646 cpu[i, "speed"] = cpu[i, "bogomips"]
3648 print cpu[i, "model"] "," cpu[i, "speed"] "," cpu[i, "cache"] "," cpu[i, "flags"] "," cpu[i, "bogomips"] "," cpu[nr, "vendor"] "," bArm
3650 # this is / was used in inxi short output only, but when it is N/A, need to use the previous array
3651 # value, from above, the actual speed that is, for short output, key 0.
3658 printf("Min:%s%s Max:%s%s\n", min, "Mhz", max, "Mhz")
3661 printf("%s %s\n", max, "Mhz")
3667 log_function_data 'cat' "$FILE_CPUINFO"
3668 elif [[ -n $BSD_TYPE ]];then
3672 temp_array=${A_CPU_DATA[@]}
3673 log_function_data "A_CPU_DATA: $temp_array"
3674 # echo ta: ${temp_array[@]}
3676 # echo getMainCpu: ${[@]}
3683 local bsd_cpu_flags=$( get_cpu_flags_bsd )
3686 if [[ $BSD_VERSION == 'openbsd' ]];then
3692 gawk -F "$gawk_fs" -v cpuFlags="$bsd_cpu_flags" '
3702 gsub(/'"$BAN_LIST_NORMAL"'/, "", $NF )
3703 gsub(/'"$BAN_LIST_CPU"'/, "", $NF )
3705 sub(/[a-z]+-core/, "", $NF )
3706 gsub(/^ +| +$|\"/, "", $NF)
3707 gsub(/ [ \t]+/, " ", $NF)
3709 if ( cpuClock != "" ) {
3713 /^hw.(clock|cpuspeed)/ {
3715 if ( cpuModel != "" ) {
3720 print cpuModel "," cpuClock "," cpuCache "," cpuFlags "," cpuBogomips "," cpuVendor
3722 }' <<< "$Sysctl_a_Data" ) )
3732 local cpu_flags=$( gawk -F '=' '
3738 while ( getline && !/memory/ ) {
3739 if ( $1 ~ /Features/ ) {
3740 # clean up odd stuff like <b23>
3741 gsub(/<[a-z0-9]+>/,"", $2)
3742 # all the flags are contained within < ... > on freebsd at least
3743 gsub(/.*<|>.*/,"", $2)
3745 cpuFlags = cpuFlags " " $2
3748 cpuFlags=tolower(cpuFlags)
3751 }' <<< "$Dmesg_Boot_Data" )
3754 log_function_data "$cpu_flags"
3758 ## this is for counting processors and finding HT types
3759 get_cpu_ht_multicore_smp_data()
3765 # note: known bug with xeon intel, they show a_core_id/physical_id as 0 for ht 4 core
3766 if [[ $B_CPUINFO_FILE == 'true' ]]; then
3767 A_CPU_TYPE_PCNT_CCNT=( $(
3773 num_of_processors = 0
3774 num_of_physical_cpus = 0
3777 # these 3 arrays cannot be declared because that sets the first element
3778 # but leaving this here so that we avoid doing that in the future
3780 # a_processor_id = ""
3781 # a_physical_id = ""
3783 # note: we need separate iterators because some cpuinfo data has only
3784 # processor, no core id or phys id
3786 core_iter = "" # set from actual NF data
3787 phys_iter = "" # set from actual NF data
3788 # needed to handle arm cpu, no processor number cases
3794 # hack to handle xeons which can have buggy /proc/cpuinfo files
3795 /^model name/ && ( $0 ~ /Xeon/ ) {
3798 # only do this once since sibling count does not change.
3799 /^siblings/ && ( bXeon == "true" ) && ( siblings == 0 ) {
3800 gsub(/[^0-9]/,"",$NF)
3805 # array of logical processors, both HT and physical
3809 gsub(/^ +| +$/, "", $NF)
3810 if ( $NF ~ "^[0-9]+$" ) {
3811 a_processor_id[proc_iter] = $NF
3815 # note, for dual core, this can be off by one because the first
3816 # line says: Processor : Arm.. but subsequent say: processor : 0 and so on as usual
3817 if ( $NF ~ "^ARM" ) {
3822 # note: do not iterate because new ARM syntax puts cpu in processsor : 0 syntax
3823 a_processor_id[proc_iter] = nr
3827 # array of physical cpu ids, note, this will be unset for vm cpus in many cases
3828 # because they have no physical cpu, so we cannot assume this will be here.
3831 a_physical_id[phys_iter] = $NF
3833 # array of core ids, again, here we may have HT, so we need to create an array of the
3834 # actual core ids. As With physical, we cannot assume this will be here in a vm
3837 a_core_id[core_iter] = $NF
3839 # this will be used to fix an intel glitch if needed, cause, intel
3840 # sometimes reports core id as the same number for each core,
3841 # so if cpu cores shows greater value than number of cores, use this.
3843 cpu_core_count = $NF
3846 ## Look thru the array and filter same numbers.
3847 ## only unique numbers required
3848 ## this is to get an accurate count
3849 ## we are only concerned with array length
3851 ## count unique processors ##
3852 # note, this fails for intel cpus at times
3853 for ( i in a_processor_id ) {
3857 ## count unique physical cpus ##
3858 for ( i in a_physical_id ) {
3859 num_of_physical_cpus++
3863 ## count unique cores ##
3864 for ( i in a_core_id ) {
3867 # xeon may show wrong core / physical id count, if it does, fix it. A xeon
3868 # may show a repeated core id : 0 which gives a fake num_of_cores=1
3869 if ( bXeon == "true" && num_of_cores == 1 && siblings > 1 ) {
3870 num_of_cores = siblings/2
3872 # final check, override the num of cores value if it clearly is wrong
3873 # and use the raw core count and synthesize the total instead of real count
3874 if ( ( num_of_cores == 0 ) && ( cpu_core_count * num_of_physical_cpus > 1 ) ) {
3875 num_of_cores = cpu_core_count * num_of_physical_cpus
3877 # last check, seeing some intel cpus and vms with intel cpus that do not show any
3878 # core id data at all, or siblings.
3879 if ( num_of_cores == 0 && num_of_processors > 0 ) {
3880 num_of_cores = num_of_processors
3882 # ARM/vm cpu fix, if no physical or core found, use count of 1 instead
3883 if ( num_of_physical_cpus == 0 ) {
3884 num_of_physical_cpus = 1
3886 # print "NoCpu: " num_of_physical_cpus
3887 # print "NoCores: " num_of_cores
3888 # print "NoProc:" num_of_processors
3889 # print "CpuCoreCount:" cpu_core_count
3890 ####################################################################
3892 # if > 1 processor && processor id (physical id) == core id then Hyperthreaded (HT)
3893 # if > 1 processor && processor id (physical id) != core id then Multi-Core Processors (MCP)
3894 # if > 1 processor && processor ids (physical id) > 1 then Multiple Processors (SMP)
3895 # if = 1 processor then single core/processor Uni-Processor (UP)
3896 if ( num_of_processors > 1 || ( bXeon == "true" && siblings > 0 ) ) {
3898 if ( num_of_processors == (num_of_cores * 2) ) {
3899 cpu_type = cpu_type "HT-"
3901 else if ( bXeon == "true" && siblings > 1 ) {
3902 cpu_type = cpu_type "HT-"
3904 # non-HT multi-core or HT multi-core
3905 if (( num_of_processors == num_of_cores) || ( num_of_physical_cpus < num_of_cores)) {
3906 cpu_type = cpu_type "MCP-"
3908 # >1 cpu sockets active
3909 if ( num_of_physical_cpus > 1 ) {
3910 cpu_type = cpu_type "SMP-"
3914 cpu_type = cpu_type "UP-"
3917 print cpu_type " " num_of_physical_cpus " " num_of_cores
3921 temp_array=${A_CPU_TYPE_PCNT_CCNT[@]}
3922 log_function_data "A_CPU_TYPE_PCNT_CCNT: $temp_array"
3926 # Detect desktop environment in use, initial rough logic from: compiz-check
3927 # http://forlong.blogage.de/entries/pages/Compiz-Check
3928 # NOTE $XDG_CURRENT_DESKTOP envvar is not reliable, but it shows certain desktops better.
3929 # most desktops are not using it as of 2014-01-13 (KDE, UNITY, LXDE. Not Gnome)
3930 get_desktop_environment()
3934 # set the default, this function only runs in X, if null, don't print data out
3935 local desktop_environment='' xprop_root=''
3936 local version='' version_data='' toolkit=''
3938 # works on 4, assume 5 will id the same, why not, no need to update in future
3939 # KDE_SESSION_VERSION is the integer version of the desktop
3940 if [[ $XDG_CURRENT_DESKTOP == 'KDE' || -n $KDE_SESSION_VERSION ]]; then
3941 # note the command is actually like, kded4 --version, so we construct it
3942 version_data=$( kded$KDE_SESSION_VERSION --version 2>/dev/null )
3943 version=$( grep -si '^KDE Development Platform:' <<< "$version_data" | gawk '{print $4}' )
3944 if [[ -z $version ]];then
3945 version=$KDE_SESSION_VERSION
3947 if [[ $B_EXTRA_DATA == 'true' ]];then
3948 toolkit=$( grep -si '^Qt:' <<< "$version_data" | gawk '{print $2}' )
3949 if [[ -n $toolkit ]];then
3950 version="$version (Qt $toolkit)"
3953 desktop_environment="KDE"
3954 # KDE_FULL_SESSION property is only available since KDE 3.5.5.
3955 # src: http://humanreadable.nfshost.com/files/startkde
3956 elif [[ $KDE_FULL_SESSION == 'true' ]]; then
3957 version_data=$( kded --version 2>/dev/null )
3958 version=$( grep -si '^KDE:' <<< "$version_data" | gawk '{print $2}' )
3959 # version=$( get_de_app_version 'kded' '^KDE:' '2' )
3960 if [[ -z $version ]];then
3963 if [[ $B_EXTRA_DATA == 'true' ]];then
3964 toolkit=$( grep -si '^Qt:' <<< "$version_data" | gawk '{print $2}' )
3965 if [[ -n $toolkit ]];then
3966 version="$version (Qt $toolkit)"
3969 desktop_environment="KDE"
3970 elif [[ $XDG_CURRENT_DESKTOP == 'Unity' ]];then
3971 version=$( get_de_app_version 'unity' '^unity' '2' )
3972 # not certain cinn will always have version, so keep output right if not
3973 if [[ -n $version ]];then
3976 if [[ $B_EXTRA_DATA == 'true' ]];then
3977 toolkit=$( get_de_gtk_data )
3978 if [[ -n $toolkit ]];then
3979 version="${version}(Gtk ${toolkit})"
3982 desktop_environment="Unity"
3984 # did we find it? If not, start the xprop tests
3985 if [[ -z $desktop_environment ]];then
3986 if [[ -n $( type -p xprop ) ]];then
3987 xprop_root="$( xprop -root 2>/dev/null )"
3989 # note that cinnamon split from gnome, and and can now be id'ed via xprop,
3990 # but it will still trigger the next gnome true case, so this needs to go before gnome test
3991 # eventually this needs to be better organized so all the xprop tests are in the same
3992 # section, but this is good enough for now.
3993 if [[ -n $xprop_root && -n $( grep -is '^_MUFFIN' <<< "$xprop_root" ) ]];then
3994 version=$( get_de_app_version 'cinnamon' '^cinnamon' '2' )
3995 # not certain cinn will always have version, so keep output right if not
3996 if [[ -n $version ]];then
3999 if [[ $B_EXTRA_DATA == 'true' ]];then
4000 toolkit=$( get_de_gtk_data )
4001 if [[ -n $toolkit ]];then
4002 version="${version}(Gtk ${toolkit})"
4005 desktop_environment="Cinnamon"
4006 elif [[ -n $xprop_root && -n $( grep -is '^_MARCO' <<< "$xprop_root" ) ]];then
4007 version=$( get_de_app_version 'mate-about' '^MATE[[:space:]]DESKTOP' 'NF' )
4008 # not certain cinn/mate will always have version, so keep output right if not
4009 if [[ -n $version ]];then
4012 if [[ $B_EXTRA_DATA == 'true' ]];then
4013 toolkit=$( get_de_gtk_data )
4014 if [[ -n $toolkit ]];then
4015 version="${version}(Gtk ${toolkit})"
4018 desktop_environment="MATE"
4019 # note, GNOME_DESKTOP_SESSION_ID is deprecated so we'll see how that works out
4020 # https://bugzilla.gnome.org/show_bug.cgi?id=542880
4021 elif [[ -n $GNOME_DESKTOP_SESSION_ID ]]; then
4022 if [[ -n $( type -p gnome-shell ) ]];then
4023 version=$( get_de_app_version 'gnome-shell' 'gnome' '3' )
4024 elif [[ -n $( type -p gnome-about ) ]];then
4025 version=$( get_de_app_version 'gnome-about' 'gnome' '3' )
4027 if [[ $B_EXTRA_DATA == 'true' ]];then
4028 toolkit=$( get_de_gtk_data )
4029 if [[ -n $toolkit ]];then
4030 version="$version (Gtk $toolkit)"
4033 desktop_environment="Gnome"
4035 if [[ -z $desktop_environment ]];then
4036 # now that the primary ones have been handled, next is to find the ones with unique
4037 # xprop detections possible
4038 if [[ -n $xprop_root ]];then
4039 # String: "This is xfdesktop version 4.2.12"
4040 # alternate: xfce4-about --version > xfce4-about 4.10.0 (Xfce 4.10)
4041 if [[ -n $( grep -Eis '\"xfce4\"' <<< "$xprop_root" ) ]];then
4042 version=$( get_de_app_version 'xfdesktop' 'xfdesktop[[:space:]]version' '5' )
4043 # arch linux reports null, so use alternate if null
4044 if [[ -z $version ]];then
4045 version=$( get_de_app_version 'xfce4-panel' '^xfce4-panel' '2' )
4046 if [[ -z $version ]];then
4050 if [[ $B_EXTRA_DATA == 'true' ]];then
4051 toolkit=$( get_de_app_version 'xfdesktop' 'Built[[:space:]]with[[:space:]]GTK' '4' )
4052 if [[ -n $toolkit ]];then
4053 version="$version (Gtk $toolkit)"
4056 desktop_environment="Xfce"
4057 # when 5 is released, the string may need updating
4058 elif [[ -n $( grep -is '\"xfce5\"' <<< "$xprop_root" ) ]];then
4059 version=$( get_de_app_version 'xfdesktop' 'xfdesktop[[:space:]]version' '5' )
4060 # arch linux reports null, so use alternate if null
4061 if [[ -z $version ]];then
4062 version=$( get_de_app_version 'xfce5-panel' '^xfce5-panel' '2' )
4063 if [[ -z $version ]];then
4067 if [[ $B_EXTRA_DATA == 'true' ]];then
4068 toolkit=$( get_de_app_version 'xfdesktop' 'Built[[:space:]]with[[:space:]]GTK' '4' )
4069 if [[ -n $toolkit ]];then
4070 version="$version (Gtk $toolkit)"
4073 desktop_environment="Xfce"
4074 elif [[ -n $( grep -is 'BLACKBOX_PID' <<< "$xprop_root" ) ]];then
4075 if [[ -n $( grep -is 'fluxbox' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4076 version=$( get_de_app_version 'fluxbox' '^fluxbox' '2' )
4077 desktop_environment='Fluxbox'
4079 desktop_environment='Blackbox'
4081 elif [[ -n $( grep -is 'OPENBOX_PID' <<< "$xprop_root" ) ]];then
4082 # note: openbox-lxde --version may be present, but returns openbox data
4083 version=$( get_de_app_version 'openbox' '^openbox' '2' )
4084 if [[ $XDG_CURRENT_DESKTOP == 'LXDE' || \
4085 -n $( grep -is 'lxde' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4086 if [[ -n $version ]];then
4087 version="(Openbox $version)"
4089 desktop_environment='LXDE'
4090 elif [[ -n $( grep -is 'razor-desktop' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4091 if [[ -n $version ]];then
4092 version="(Openbox $version)"
4094 desktop_environment='Razor-QT'
4096 desktop_environment='Openbox'
4098 elif [[ -n $( grep -is 'ICEWM' <<< "$xprop_root" ) ]];then
4099 version=$( get_de_app_version 'icewm' '^icewm' '2' )
4100 desktop_environment='IceWM'
4101 elif [[ -n $( grep -is 'ENLIGHTENMENT' <<< "$xprop_root" ) ]];then
4102 # no -v or --version but version is in xprop -root
4103 # ENLIGHTENMENT_VERSION(STRING) = "Enlightenment 0.16.999.49898"
4104 version=$( grep -is 'ENLIGHTENMENT_VERSION' <<< "$xprop_root" | cut -d '"' -f 2 | gawk '{print $2}' )
4105 desktop_environment='Enlightenment'
4106 elif [[ -n $( grep -is '^I3_' <<< "$xprop_root" ) ]];then
4107 version=$( get_de_app_version 'i3' '^i3' '3' )
4108 desktop_environment='i3'
4109 elif [[ -n $( grep -is 'WINDOWMAKER' <<< "$xprop_root" ) ]];then
4110 version=$( get_de_app_version 'wmaker' '^Window[[:space:]]*Maker' 'NF' )
4111 if [[ -n $version ]];then
4114 desktop_environment="WindowMaker"
4115 elif [[ -n $( grep -is '^_WM2' <<< "$xprop_root" ) ]];then
4116 # note; there isn't actually a wm2 version available but error handling should cover it and return null
4117 # maybe one day they will add it?
4118 version=$( get_de_app_version 'wm2' '^wm2' 'NF' )
4119 # not certain will always have version, so keep output right if not
4120 if [[ -n $version ]];then
4123 desktop_environment="WM2"
4124 elif [[ -n $( grep -is 'herbstluftwm' <<< "$xprop_root" ) ]];then
4125 version=$( get_de_app_version 'herbstluftwm' '^herbstluftwm' 'NF' )
4126 if [[ -n $version ]];then
4129 desktop_environment="herbstluftwm"
4132 # a few manual hacks for things that don't id with xprop, these are just good guesses
4133 # note that gawk is going to exit after first occurance of search string, so no need for extra
4134 if [[ -z $desktop_environment ]];then
4135 if [[ -n $( grep -is 'fvwm-crystal' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4136 version=$( get_de_app_version 'fvwm' '^fvwm' '2' )
4137 desktop_environment='FVWM-Crystal'
4138 elif [[ -n $( grep -is 'fvwm' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4139 version=$( get_de_app_version 'fvwm' '^fvwm' '2' )
4140 desktop_environment='FVWM'
4141 elif [[ -n $( grep -is 'pekwm' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4142 version=$( get_de_app_version 'pekwm' '^pekwm' '3' )
4143 desktop_environment='pekwm'
4144 elif [[ -n $( grep -is 'awesome' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4145 version=$( get_de_app_version 'awesome' '^awesome' '2' )
4146 desktop_environment='Awesome'
4147 elif [[ -n $( grep -is 'scrotwm' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4148 version=$( get_de_app_version 'scrotwm' '^welcome.*scrotwm' '4' )
4149 desktop_environment='Scrotwm' # no --version for this one
4150 elif [[ -n $( grep -is 'spectrwm' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4151 version=$( get_de_app_version 'spectrwm' '^spectrwm.*welcome.*spectrwm' '5' )
4152 desktop_environment='Spectrwm' # no --version for this one
4153 elif [[ -n $( grep -Eis '([[:space:]]|/)twm' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4154 desktop_environment='Twm' # no --version for this one
4155 elif [[ -n $( grep -Eis '([[:space:]]|/)dwm' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4156 version=$( get_de_app_version 'dwm' '^dwm' '1' )
4157 desktop_environment='dwm'
4158 elif [[ -n $( grep -is 'wmii2' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4159 version=$( get_de_app_version 'wmii2' '^wmii2' '1' )
4160 desktop_environment='wmii2'
4161 # note: in debian at least, wmii is actuall wmii3
4162 elif [[ -n $( grep -is 'wmii' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4163 version=$( get_de_app_version 'wmii' '^wmii' '1' )
4164 desktop_environment='wmii'
4165 elif [[ -n $( grep -Eis '([[:space:]]|/)jwm' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4166 version=$( get_de_app_version 'jwm' '^jwm' '2' )
4167 desktop_environment='JWM'
4172 if [[ -n $version ]];then
4175 echo "$desktop_environment${version}"
4179 # note: gawk doesn't support white spaces in search string, gave errors, so use [[:space:]] instead
4180 # args: $1 - desktop/app command for --version; $2 - search string; $3 - gawk print number
4181 get_de_app_version()
4183 local version_data='' version='' get_version='--version'
4185 # mate-about -v = MATE Desktop Environment 1.4.0
4187 dwm|jwm|mate-about|wmii|wmii2)
4191 get_version='version'
4196 # note, some wm/apps send version info to stderr instead of stdout
4197 dwm|ksh|scrotwm|spectrwm)
4198 version_data="$( $1 $get_version 2>&1 )"
4201 version_data="$( tcsh $get_version 2>/dev/null )"
4203 # quick debian/buntu hack until I find a universal way to get version for these
4205 if [[ -n $( type -p dpkg ) ]];then
4206 version_data="$( dpkg -l $1 2>/dev/null )"
4210 version_data="$( $1 $get_version 2>/dev/null )"
4214 if [[ -n $version_data ]];then
4220 # sample: dwm-5.8.2, ©.. etc, why no space? who knows. Also get rid of v in number string
4221 # xfce, and other, output has , in it, so dump all commas and parentheses
4222 gsub(/(,|dwm-|wmii2-|wmii-|v|V|\(|\))/, "",$'$3')
4224 exit # quit after first match prints
4225 }' <<< "$version_data" )
4230 get_desktop_extra_data()
4233 local de_data=$( ps -A | gawk '
4239 /(gnome-shell|gnome-panel|kicker|lxpanel|mate-panel|plasma-desktop|xfce4-panel)$/ {
4240 # only one entry per type, can be multiple
4241 if ( desktops !~ $NF ) {
4242 desktops = desktops separator $NF
4261 # this is a hack, and has to be changed with every toolkit version change, and only dev systems
4262 # have this installed, but it's a cross distro command so let's test it first
4263 if [[ -n $( type -p pkg-config ) ]];then
4264 toolkit=$( pkg-config --modversion gtk+-4.0 2>/dev/null )
4265 # note: opensuse gets null output here, we need the command to get version and output sample
4266 if [[ -z $toolkit ]];then
4267 toolkit=$( pkg-config --modversion gtk+-3.0 2>/dev/null )
4269 if [[ -z $toolkit ]];then
4270 toolkit=$( pkg-config --modversion gtk+-2.0 2>/dev/null )
4273 # now let's go to more specific version tests, this will never cover everything and that's fine.
4274 if [[ -z $toolkit ]];then
4275 # we'll try some known package managers next. dpkg will handle a lot of distros
4276 # this is the most likely order as of: 2014-01-13. Not going to try to support all package managers
4277 # too much work, just the very biggest ones.
4278 if [[ -n $( type -p dpkg ) ]];then
4279 toolkit=$( dpkg -s libgtk-3-0 2>/dev/null | gawk -F ':' '/^Version/ {print $2}' )
4280 if [[ -z $toolkit ]];then
4281 toolkit=$( dpkg -s libgtk2.0-0 2>/dev/null | gawk -F ':' '/^Version/ {print $2}' )
4283 # just guessing on gkt 4 package name
4284 if [[ -z $toolkit ]];then
4285 toolkit=$( dpkg -s libgtk-4-0 2>/dev/null | gawk -F ':' '/^Version/ {print $2}' )
4287 elif [[ -n $( type -p pacman ) ]];then
4288 toolkit=$( pacman -Qi gtk3 2>/dev/null | gawk -F ':' '/^Version/ {print $2}' )
4289 if [[ -z $toolkit ]];then
4290 toolkit=$( pacman -Qi gtk2 2>/dev/null | gawk -F ':' '/^Version/ {print $2}' )
4299 # see which dm has started if any
4300 get_display_manager()
4303 # ldm - LTSP display manager
4304 local dm_id_list='entranced.pid entrance/entranced.pid gdm.pid gdm3.pid kdm.pid ldm.pid lightdm.pid lxdm.pid mdm.pid nodm.pid slim.lock tint2.pid wdm.pid xdm.pid'
4305 local dm_id='' dm='' separator=''
4306 # note we don't need to filter grep if we do it this way
4307 local x_is_running=$( grep '/usr.*/X' <<< "$Ps_aux_Data" | grep -iv '/Xprt' )
4309 for dm_id in $dm_id_list
4311 if [[ -e /var/run/$dm_id || -e /run/$dm_id ]];then
4312 # just on the off chance that two dms are running, good info to have in that case, if possible
4313 dm=$dm$separator$( basename $dm_id | cut -d '.' -f 1 )
4317 # might add this in, but the rate of new dm's makes it more likely it's an unknown dm, so
4318 # we'll keep output to N/A
4319 if [[ -n $x_is_running && -z $dm ]];then
4320 if [[ -n $( grep 'startx$' <<< "$Ps_aux_Data" ) ]];then
4326 log_function_data "display manager: $dm"
4331 # for more on distro id, please reference this python thread: http://bugs.python.org/issue1322
4332 ## return distro name/id if found
4336 local i='' j='' distro='' distro_file='' a_distro_glob='' temp_array=''
4338 # may need modification if archbsd / debian can be id'ed with /etc files
4339 if [[ -n $BSD_TYPE ]];then
4340 distro=$( uname -sr )
4342 log_function_data "distro: $distro"
4347 # get the wild carded array of release/version /etc files if present
4350 # note: always exceptions, so wild card after release/version: /etc/lsb-release-crunchbang
4351 # wait to handle since crunchbang file is one of the few in the world that uses this method
4352 a_distro_glob=(*[-_]{release,version})
4356 temp_array=${a_distro_glob[@]}
4357 log_function_data "A_GLX_DATA: $temp_array"
4359 if [[ ${#a_distro_glob[@]} -eq 1 ]];then
4360 distro_file="${a_distro_glob}"
4361 # use the file if it's in the known good lists
4362 elif [[ ${#a_distro_glob[@]} -gt 1 ]];then
4363 for i in $DISTROS_DERIVED $DISTROS_PRIMARY
4365 # Only echo works with ${var[@]}, not print_screen_output() or script_debugger()
4366 # This is a known bug, search for the word "strange" inside comments
4367 # echo "i='$i' a_distro_glob[@]='${a_distro_glob[@]}'"
4368 if [[ " ${a_distro_glob[@]} " == *" $i "* ]];then
4369 # Now lets see if the distro file is in the known-good working-lsb-list
4370 # if so, use lsb-release, if not, then just use the found file
4371 # this is for only those distro's with self named release/version files
4372 # because Mint does not use such, it must be done as below
4373 ## this if statement requires the spaces and * as it is, else it won't work
4375 if [[ " $DISTROS_LSB_GOOD " == *" ${i} "* ]] && [[ $B_LSB_FILE == 'true' ]];then
4376 distro_file='lsb-release'
4377 elif [[ " $DISTROS_OS_RELEASE_GOOD " == *" ${i} "* ]] && [[ $B_OS_RELEASE_FILE == 'true' ]];then
4378 distro_file='os-release'
4386 log_function_data "distro_file: $distro_file"
4387 # first test for the legacy antiX distro id file
4388 if [[ -e /etc/antiX ]];then
4389 distro="$( grep -Eoi 'antix.*\.iso' <<< $( remove_erroneous_chars '/etc/antiX' ) | sed 's/\.iso//' )"
4390 # this handles case where only one release/version file was found, and it's lsb-release. This would
4391 # never apply for ubuntu or debian, which will filter down to the following conditions. In general
4392 # if there's a specific distro release file available, that's to be preferred, but this is a good backup.
4393 elif [[ -n $distro_file && $B_LSB_FILE == 'true' && " $DISTROS_LSB_GOOD" == *" $distro_file "* ]];then
4394 distro=$( get_distro_lsb_os_release_data 'lsb-file' )
4395 elif [[ $distro_file == 'lsb-release' ]];then
4396 distro=$( get_distro_lsb_os_release_data 'lsb-file' )
4397 elif [[ $distro_file == 'os-release' ]];then
4398 distro=$( get_distro_lsb_os_release_data 'os-release-file' )
4399 # then if the distro id file was found and it's not in the exluded primary distro file list, read it
4400 elif [[ -n $distro_file && -s /etc/$distro_file && " $DISTROS_EXCLUDE_LIST " != *" $distro_file "* ]];then
4401 # new opensuse uses os-release, but older ones may have a similar syntax, so just use the first line
4402 if [[ $distro_file == 'SuSE-release' ]];then
4403 # leaving off extra data since all new suse have it, in os-release, this file has line breaks, like os-release
4404 # but in case we want it, it's: CODENAME = Mantis | VERSION = 12.2
4405 # for now, just take first occurance, which should be the first line, which does not use a variable type format
4406 distro=$( grep -i -m 1 'suse' /etc/$distro_file )
4408 distro=$( remove_erroneous_chars "/etc/$distro_file" )
4410 # otherwise try the default debian/ubuntu /etc/issue file
4411 elif [[ -f /etc/issue ]];then
4412 # lsb gives more manageable and accurate output than issue, but mint should use issue for now
4413 # some bashism, boolean must be in parenthesis to work correctly, ie [[ $(boolean) ]] not [[ $boolean ]]
4414 if [[ $B_LSB_FILE == 'true' ]] && [[ -z $( grep -i 'mint' /etc/issue ) ]];then
4415 distro=$( get_distro_lsb_os_release_data 'lsb-file' )
4425 gsub(/ [ \t]+/, " ")
4429 # this handles an arch bug where /etc/arch-release is empty and /etc/issue is corrupted
4430 # only older arch installs that have not been updated should have this fallback required, new ones use
4432 if [[ -n $( grep -i 'arch linux' <<< $distro ) ]];then
4438 if [[ ${#distro} -gt 80 ]] && [[ $B_HANDLE_CORRUPT_DATA != 'true' ]];then
4439 distro="${RED}/etc/${distro_file} corrupted, use -% to override${NORMAL}"
4441 ## note: would like to actually understand the method even if it's not used
4442 # : ${distro:=Unknown distro o_O}
4443 ## test for /etc/lsb-release as a backup in case of failure, in cases where > one version/release file
4444 ## were found but the above resulted in null distro value
4445 if [[ -z $distro ]] && [[ $B_LSB_FILE == 'true' ]];then
4446 distro=$( get_distro_lsb_os_release_data 'lsb-file' )
4448 if [[ -z $distro ]] && [[ $B_OS_RELEASE_FILE == 'true' ]];then
4449 distro=$( get_distro_lsb_os_release_data 'os-release-file' )
4451 # now some final null tries
4452 if [[ -z $distro ]];then
4453 # if the file was null but present, which can happen in some cases, then use the file name itself to
4454 # set the distro value. Why say unknown if we have a pretty good idea, after all?
4455 if [[ -n $distro_file ]] && [[ " $DISTROS_DERIVED $DISTROS_PRIMARY " == *" $distro_file "* ]];then
4456 distro=$( sed $SED_RX -e 's/[-_]//' -e 's/(release|version)//' <<< $distro_file | sed $SED_RX 's/^([a-z])/\u\1/' )
4458 ## finally, if all else has failed, give up
4459 if [[ -z $distro ]];then
4463 # final step cleanup of unwanted information
4464 # opensuse has the x86 etc type string in names, not needed as redundant since -S already shows that
4470 sub(/ *\(*(x86_64|i486|i586|i686|686|586|486)\)*/, "", $0)
4474 log_function_data "distro: $distro"
4478 # args: $1 - lsb-file/lsb-app/os-release-file
4479 get_distro_lsb_os_release_data()
4486 if [[ $B_LSB_FILE == 'true' ]];then
4487 distro=$( gawk -F '=' '
4491 # clean out unwanted characters
4493 gsub(/\\|\"|[:\47]/,"", $0 )
4494 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2 )
4495 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $1 )
4497 # note: adding the spacing directly to variable to make sure distro output is null if not found
4499 # this is needed because grep for "arch" is too loose to be safe
4500 if ( $2 == "arch" ) {
4501 distroId = "Arch Linux"
4503 else if ( $2 != "n/a" ) {
4507 /^DISTRIB_RELEASE/ {
4508 if ( $2 != "n/a" ) {
4509 distroRelease = $2 " "
4512 /^DISTRIB_CODENAME/ {
4513 if ( $2 != "n/a" ) {
4514 distroCodename = $2 " "
4517 # sometimes some distros cannot do their lsb-release files correctly, so here is
4518 # one last chance to get it right.
4519 /^DISTRIB_DESCRIPTION/ {
4520 if ( $2 != "n/a" ) {
4521 distroDescription = $2
4526 if ( distroId == "" && distroRelease == "" && distroCodename == "" && distroDescription != "" ){
4527 fullString = distroDescription
4530 fullString = distroId distroRelease distroCodename
4534 ' $FILE_LSB_RELEASE )
4535 log_function_data 'cat' "$FILE_LSB_RELEASE"
4539 # this is HORRIBLY slow, not using
4540 if [[ -n $( type -p lsb_release ) ]];then
4541 distro=$( echo "$( lsb_release -irc )" | gawk -F ':' '
4545 # clean out unwanted characters
4547 gsub(/\\|\"|[:\47]/,"", $0 )
4548 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2 )
4549 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $1 )
4561 print distroId " " distroRelease " (" distroCodename ")"
4566 if [[ $B_OS_RELEASE_FILE == 'true' ]];then
4567 distro=$( gawk -F '=' '
4576 # clean out unwanted characters
4578 gsub(/\\|\"|[:\47]/,"", $0 )
4579 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2 )
4580 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $1 )
4582 # note: adding the spacing directly to variable to make sure distro output is null if not found
4584 if ( $2 != "n/a" ) {
4589 if ( $2 != "n/a" ) {
4594 if ( $2 != "n/a" && $1 == "VERSION" ) {
4597 else if ( $2 != "n/a" && $1 == "VERSION_ID" ) {
4602 if ( prettyName != "" ) {
4603 distroName = prettyName
4605 else if ( regularName != "" ) {
4606 distroName = regularName
4607 if ( versionName != "" ) {
4608 distroName = distroName " " versionName
4610 else if ( versionId != "" ) {
4611 distroName = distroName " " versionId
4617 ' $FILE_OS_RELEASE )
4618 log_function_data 'cat' "$FILE_OS_RELEASE"
4623 log_function_data "distro: $distro"
4627 get_dmidecode_data()
4631 local dmidecodePath=''
4633 if [[ $B_DMIDECODE_SET != 'true' ]];then
4634 dmidecodePath=$( type -p dmidecode 2>/dev/null )
4635 if [[ -n $dmidecodePath ]];then
4636 # note stripping out these lines: Handle 0x0016, DMI type 17, 27 bytes
4637 # but NOT deleting them, in case the dmidecode data is missing empty lines which will be
4638 # used to separate results. Then we remove the doubled empty lines to keep it clean and
4639 # strip out all the stuff we don't want to see in the results.
4640 DMIDECODE_DATA="$( $dmidecodePath 2>/dev/null \
4649 # no idea why, but freebsd gawk does not do this right
4652 if ( twoData != "" ) {
4658 if ( $0 ~ /^\tDMI type/ ) {
4659 sub(/^\tDMI type.*/, "", $0)
4662 gsub(/'"$BAN_LIST_NORMAL"'/, "", twoData)
4664 # clean out Handle line
4665 sub(/^Handle.*/,"", $0)
4666 sub(/^[[:space:]]*Inactive.*/,"",$0)
4667 # yes, there is a typo in a user data set, unknow
4668 # Base Board Version|Base Board Serial Number
4669 # Chassis Manufacturer|Chassis Version|Chassis Serial Number
4670 # System manufacturer|System Product Name|System Version
4671 # To Be Filled By O.E.M.
4672 # strip out starting white space so that the following stuff will clear properly
4673 sub(/^[[:space:]]+/, "", twoData)
4674 sub(/^Base Board .*|^Chassis .*|.*O\.E\.M\..*|.*OEM.*|^Not .*|^System .*|.*unknow.*|.*N\/A.*|none|^To be filled.*/, "", twoData)
4675 gsub(/bios|acpi/, "", twoData)
4676 sub(/http:\/\/www.abit.com.tw\//, "Abit", twoData)
4678 # for double indented values replace with ~ so later can test for it, we are trusting that
4679 # indentation will be tabbed in this case
4680 # special case, dmidecode 2.2 has an extra tab and a DMI type line
4681 if ( cutExtraTab == "true" ) {
4682 sub(/^\t\t\t+/, "~", oneData)
4685 sub(/^\t\t+/, "~", oneData)
4688 gsub(/^[[:space:]]+|[[:space:]]+$/, "", twoData)
4689 gsub(/^[[:space:]]+|[[:space:]]+$/, "", oneData)
4690 gsub(/ [ \t]+/, " ", twoData)
4691 # reconstructing the line for processing so gawk can use -F : again
4692 if ( oneData != "" && twoHolder == "true" ) {
4693 print oneData ":" twoData
4705 B_DMIDECODE_SET='true'
4706 log_function_data "DMIDECODE_DATA: $DMIDECODE_DATA"
4711 # get_dmidecode_data;echo "$DMIDECODE_DATA";exit
4714 get_dmesg_boot_data()
4718 local dmsg_boot_data=''
4720 if [[ $B_DMESG_BOOT_FILE == 'true' ]];then
4721 # replace all indented items with ~ so we can id them easily while processing
4722 dmsg_boot_data="$( cat $FILE_DMESG_BOOT | sed $SED_RX 's/"//g' )"
4724 echo "$dmsg_boot_data"
4725 # log_function_data "$dmsg_boot_data"
4729 get_gcc_kernel_version()
4731 # note that we use gawk to get the last part because beta, alpha, git versions can be non-numeric
4734 if [[ -e /proc/version ]];then
4735 gccVersion=$( grep -Eio 'gcc[[:space:]]*version[[:space:]]*([^ \t]*)' /proc/version 2>/dev/null | gawk '{print $3}' )
4740 get_gcc_system_version()
4743 local separator='' gcc_installed='' gcc_list='' gcc_others='' temp_array=''
4744 local gcc_version=$(
4745 gcc --version 2>/dev/null | sed $SED_RX 's/\([^\)]*\)//g' | gawk '
4754 # can't use xargs -L basename because not all systems support thats
4755 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
4756 gcc_others=$( ls /usr/bin/gcc-* 2>/dev/null )
4757 if [[ -n $gcc_others ]];then
4758 for item in $gcc_others
4760 gcc_installed=$( basename $item | gawk -F '-' '
4764 if [[ -n $gcc_installed && -z $( grep "^$gcc_installed" <<< $gcc_version ) ]];then
4765 gcc_list=$gcc_list$separator$gcc_installed
4771 if [[ -n $gcc_version ]];then
4772 A_GCC_VERSIONS=( "$gcc_version" $gcc_list )
4774 temp_array=${A_GCC_VERSIONS[@]}
4775 log_function_data "A_GCC_VERSIONS: $temp_array"
4780 local gpu_temp='' gpu_fan='' screens='' screen_nu='' gpu_temp_looper=''
4782 # we'll try for nvidia/ati, then add if more are shown
4783 if [[ -n $( type -p nvidia-settings ) ]];then
4784 # first get the number of screens
4785 screens=$( nvidia-settings -q screens | gawk '
4787 screens=screens gensub(/(.*)(:[0-9]\.[0-9])(.*)/, "\\2", "1", $0) " "
4793 # now we'll get the gpu temp for each screen discovered. The print out function
4794 # will handle removing screen data for single gpu systems
4795 for screen_nu in $screens
4797 gpu_temp_looper=$( nvidia-settings -c $screen_nu -q GPUCoreTemp | gawk -F ': ' '
4803 /Attribute (.*)[0-9]+\.$/ {
4805 if ( $2 ~ /^[0-9]+$/ ) {
4806 gpuTemp=gpuTemp $2 "C "
4812 screen_nu=$( cut -d ':' -f 2 <<< $screen_nu )
4813 gpu_temp="$gpu_temp$screen_nu:$gpu_temp_looper "
4815 elif [[ -n $( type -p aticonfig ) ]];then
4816 # gpu_temp=$( aticonfig --adapter=0 --od-gettemperature | gawk -F ': ' '
4817 gpu_temp=$( aticonfig --adapter=all --od-gettemperature | gawk -F ': ' '
4823 /Sensor (.*)[0-9\.]+ / {
4824 gpuTempWorking=gensub(/(.*) ([0-9\.]+) (.*)/, "\\2", "1", $2)
4825 if ( gpuTempWorking ~ /^[0-9\.]+$/ ) {
4826 gpuTemp=gpuTemp gpuTempWorking "C "
4832 # this handles some newer cases of free driver temp readouts, will require modifications as
4833 # more user data appears.
4834 elif [[ -n $Sensors_Data ]];then
4842 /^('"$SENSORS_GPU_SEARCH"')-pci/ {
4843 while ( getline && !/^$/ ) {
4845 sub(/^[[:alnum:]]*.*:/, "", $0 ) # clear out everything to the :
4846 gsub(/[\+ \t°]/, "", $1) # ° is a special case, like a space for gawk
4847 gpuTemp=gpuTemp separator $1
4854 }' <<< "$Sensors_Data" )
4857 if [[ -n $gpu_temp ]];then
4862 ## for possible future data, not currently used
4863 get_graphics_agp_data()
4868 if [[ $B_MODULES_FILE == 'true' ]];then
4869 ## not used currently
4870 agp_module=$( gawk '
4871 /agp/ && !/agpgart/ && $3 > 0 {
4872 print(gensub(/(.*)_agp.*/,"\\1","g",$1))
4874 log_function_data 'cat' "$FILE_MODULES"
4876 log_function_data "agp_module: $agp_module"
4880 ## create array of gfx cards installed on system
4881 get_graphics_card_data()
4884 local i='' temp_array=''
4887 A_GRAPHICS_CARD_DATA=( $( gawk -F': ' '
4892 /vga compatible controller/ {
4893 gsub(/'"$BAN_LIST_NORMAL"'/, "", $NF)
4895 gsub(/^ +| +$/, "", $NF)
4896 gsub(/ [ \t]+/, " ", $NF)
4897 busId=gensub(/^([0-9a-f:\.]+) (.+)$/,"\\1","",$1)
4899 }' <<< "$Lspci_v_Data" ) )
4901 # for (( i=0; i < ${#A_GRAPHICS_CARD_DATA[@]}; i++ ))
4903 # A_GRAPHICS_CARD_DATA[i]=$( sanitize_characters BAN_LIST_NORMAL "${A_GRAPHICS_CARD_DATA[i]}" )
4906 # GFXMEM is UNUSED at the moment, because it shows AGP aperture size, which is not necessarily equal to GFX memory..
4907 # 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]"
4908 temp_array=${A_GRAPHICS_CARD_DATA[@]}
4909 log_function_data "A_GRAPHICS_CARD_DATA: $temp_array"
4913 get_graphics_driver()
4917 # list is from sgfxi plus non-free drivers
4918 local driver_list='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'
4919 local driver='' driver_string='' xorg_log_data='' status='' temp_array=''
4921 if [[ $B_XORG_LOG == 'true' ]];then
4922 A_GRAPHIC_DRIVERS=( $(
4929 # note that in file names, driver is always lower case
4930 /[[:space:]]Loading.*('"$driver_list"')_drv.so$/ {
4931 driver=gensub(/.*[[:space:]]Loading.*('"$driver_list"')_drv.so/, "\\1", 1, $0 )
4932 # we get all the actually loaded drivers first, we will use this to compare the
4933 # failed/unloaded, which have not always actually been truly loaded
4934 aDrivers[driver]="loaded"
4936 /Unloading[[:space:]].*('"$driver_list"')(|_drv.so)$/ {
4937 driver=gensub(/(.*)Unloading[[:space:]].*('"$driver_list"')(|_drv.so)$/, "\\2", 1, $0 )
4938 # we need to make sure that the driver has already been truly loaded, not just discussed
4939 if ( driver in aDrivers ) {
4940 aDrivers[driver]="unloaded"
4943 /Failed.*('"$driver_list"')_drv.so|Failed.*\"('"$driver_list"')\"/ {
4944 driver=gensub(/(.*)Failed.*('"$driver_list"')_drv.so/, "\\2", 1, $0 )
4945 if ( driver == $0 ) {
4946 driver=gensub(/(.*)Failed.*\"('"$driver_list"')\".*|fred/, "\\2", 1, $0 )
4948 # we need to make sure that the driver has already been truly loaded, not just discussed
4949 if ( driver != $0 && driver in aDrivers ) {
4950 aDrivers[driver]="failed"
4953 # verify that the driver actually started the desktop, even with false failed messages which can occur
4954 # this is the driver that is actually driving the display
4955 /.*\([0-9]+\):[[:space:]]Depth.*framebuffer/ {
4956 driver=gensub(/.*('"$driver_list"')\([0-9]+\):[[:space:]]Depth.*framebuffer.*/, "\\1", 1, $0 )
4957 # we need to make sure that the driver has already been truly loaded, not just discussed, also
4958 # set driver to lower case because sometimes it will show as RADEON or NVIDIA in the actual x start
4959 driver=tolower(driver)
4960 if ( driver != $0 && driver in aDrivers ) {
4961 aDrivers[driver]="loaded"
4965 for ( driver in aDrivers ) {
4966 print driver "," aDrivers[driver]
4968 }' < $FILE_XORG_LOG ) )
4970 temp_array=${A_GRAPHIC_DRIVERS[@]}
4971 log_function_data "A_GRAPHIC_DRIVERS: $temp_array"
4976 ## create array of glx data
4977 get_graphics_glx_data()
4981 if [[ $B_SHOW_DISPLAY_DATA == 'true' && $B_ROOT != 'true' ]];then
4983 A_GLX_DATA=( $( glxinfo | gawk -F ': ' '
4984 # note: function declarations go before BEGIN? It appears so, confirm.
4985 # the real question here though is why this function is even here, seems
4986 # just to be a complicated way to pack/print a variable, but maybe the
4987 # original idea was to handle > 1 cases of detections I guess
4988 function join( arr, sep ) {
5004 gsub(/'"$BAN_LIST_NORMAL"'/, "", $2)
5005 gsub(/ [ \t]+/, " ", $2) # get rid of the created white spaces
5006 gsub(/^ +| +$/, "", $2)
5007 if ( $2 ~ /mesa/ ) {
5009 # if ( $2 ~ / r[3-9][0-9][0-9] / ) {
5011 # this counter failed in one case, a bug, and is not needed now
5019 # dropping all conditions from this test to just show full mesa information
5020 # there is a user case where not f and mesa apply, atom mobo
5021 # /opengl version/ && ( f || $2 !~ /mesa/ ) {
5023 # fglrx started appearing with this extra string, does not appear to communicate anything of value
5024 sub(/Compatibility Profile Context/, "- CPC", $2 )
5025 gsub(/ [ \t]+/, " ", $2) # get rid of the created white spaces
5026 gsub(/^ +| +$/, "", $2)
5029 /direct rendering/ {
5033 printf( "%s\n%s\n%s\n", join( a, ", " ), join( b, ", " ), join( c, ", " ) )
5037 # GLXR=$(glxinfo | gawk -F ': ' 'BEGIN {IGNORECASE=1} /opengl renderer/ && $2 !~ /mesa/ {seen[$2]++} END {for (i in seen) {printf("%s ",i)}}')
5038 # GLXV=$(glxinfo | gawk -F ': ' 'BEGIN {IGNORECASE=1} /opengl version/ && $2 !~ /mesa/ {seen[$2]++} END {for (i in seen) {printf("%s ",i)}}')
5040 temp_array=${A_GLX_DATA[@]}
5041 log_function_data "A_GLX_DATA: $temp_array"
5045 ## return screen resolution / tty resolution
5046 get_graphics_res_data()
5049 local screen_resolution='' xdpy_data='' screens_count=0 tty_session=''
5051 if [[ $B_SHOW_DISPLAY_DATA == 'true' && $B_ROOT != 'true' ]];then
5052 # Added the two ?'s , because the resolution is now reported without spaces around the 'x', as in
5053 # 1400x1050 instead of 1400 x 1050. Change as of X.org version 1.3.0
5054 xdpy_data="$( xdpyinfo )"
5055 xdpy_count=$( grep -c 'dimensions' <<< "$xdpy_data" )
5056 # we get a bit more info from xrandr than xdpyinfo, but xrandr fails to handle
5057 # multiple screens from different video cards
5058 if [[ $xdpy_count -eq 1 ]];then
5059 screen_resolution=$( xrandr | gawk '
5061 res[++m] = gensub(/^.* ([0-9]+) ?x ?([0-9]+)[_ ].* ([0-9\.]+)\*.*$/,"\\1x\\2@\\3hz","g",$0)
5065 if (res[n] ~ /^[[:digit:]]+x[[:digit:]]+/) {
5066 line = line ? line ", " res[n] : res[n]
5074 if [[ -z $screen_resolution || $xdpy_count -gt 1 ]];then
5075 screen_resolution=$( gawk '
5082 screens = screens separator # first time, this is null, next, has comma last
5083 screens = screens $2 # then tack on the new value for nice comma list
5088 }' <<< "$xdpy_data" )
5091 if [[ $B_PROC_DIR == 'true' && -z $BSD_TYPE ]];then
5092 screen_resolution=$( stty -F $( readlink /proc/$PPID/fd/0 ) size | gawk '{
5095 # note: this works fine for all systems but keeping the above for now since
5096 # the above is probably more accurate for linux systems.
5098 if [[ $B_CONSOLE_IRC != 'true' ]];then
5099 screen_resolution=$( stty -a | gawk -F ';' '
5101 gsub(/[[:space:]]*(rows|columns)[[:space:]]*/,"",$0)
5102 gsub(/[[:space:]]*/,"",$2)
5103 gsub(/[[:space:]]*/,"",$3)
5107 if [[ -n $BSD_TYPE ]];then
5108 tty_session=$( get_tty_console_irc )
5109 # getting information for tty that owns the irc client
5110 screen_resolution="$( stty -f /dev/pts/$tty_session size | gawk '{print $2"x"$1}' )"
5115 echo "$screen_resolution"
5116 log_function_data "screen_resolution: $screen_resolution"
5120 ## create array of display server vendor/version data
5121 get_graphics_display_server_data()
5124 local vendor='' version='' temp_array='' xdpy_info='' a_display_vendor_working=''
5126 if [[ $B_SHOW_DISPLAY_DATA == 'true' && $B_ROOT != 'true' ]];then
5127 # X vendor and version detection.
5128 # new method added since radeon and X.org and the disappearance of <X server name> version : ...etc
5129 # Later on, the normal textual version string returned, e.g. like: X.Org version: 6.8.2
5130 # A failover mechanism is in place. (if $version is empty, the release number is parsed instead)
5131 # xdpy_info="$( xdpyinfo )"
5133 a_display_vendor_working=( $( xdpyinfo | gawk -F': +' '
5141 gsub(/the|inc|foundation|project|corporation/, "", $2)
5143 gsub(/^ +| +$/, "", $2)
5144 gsub(/ [ \t]+/, " ", $2)
5150 /vendor release number/ {
5156 print vendorString "," version "," vendorRelease
5158 vendor=${a_display_vendor_working[0]}
5159 version=${a_display_vendor_working[1]}
5161 # this gives better output than the failure last case, which would only show:
5162 # for example: X.org: 1.9 instead of: X.org: 1.9.0
5163 if [[ -z $version ]];then
5164 version=$( get_graphics_display_server_version )
5166 if [[ -z $version ]];then
5167 version=${a_display_vendor_working[2]}
5170 # some distros, like fedora, report themselves as the xorg vendor, so quick check
5171 # here to make sure the vendor string includes Xorg in string
5172 if [[ -z $( grep -E '(X|xorg|x\.org)' <<< $vendor ) ]];then
5173 vendor="$vendor X.org"
5176 A_DISPLAY_SERVER_DATA[0]="$vendor"
5177 A_DISPLAY_SERVER_DATA[1]="$version"
5179 version=$( get_graphics_display_server_version )
5180 if [[ -n $version ]];then
5182 A_DISPLAY_SERVER_DATA[0]="$vendor"
5183 A_DISPLAY_SERVER_DATA[1]="$version"
5186 temp_array=${A_DISPLAY_SERVER_DATA[@]}
5187 log_function_data "A_DISPLAY_SERVER_DATA: $temp_array"
5191 # if other tests fail, try this one, this works for root, out of X also
5192 get_graphics_display_server_version()
5195 local version='' x_data=''
5196 # note that some users can have /usr/bin/Xorg but not /usr/bin/X
5197 if [[ -n $( type -p X ) ]];then
5198 # note: MUST be this syntax: X -version 2>&1
5199 # otherwise X -version overrides everything and this comes out null.
5200 # two knowns id strings: X.Org X Server 1.7.5 AND X Window System Version 1.7.5
5201 #X -version 2>&1 | gawk '/^X Window System Version/ { print $5 }'
5202 x_data="$( X -version 2>&1 )"
5203 elif [[ -n $( type -p Xorg ) ]];then
5204 x_data="$( Xorg -version 2>&1)"
5206 if [[ -n $x_data ]];then
5216 /^X Window System Version/ {
5222 log_function_data " version: $version"
5226 # this gets just the raw data, total space/percent used and disk/name/per disk capacity
5227 get_hdd_data_basic()
5230 local hdd_used='' temp_array='' df_string=''
5231 local hdd_data='' df_test=''
5233 if [[ -z $BSD_TYPE ]];then
5234 df_string='df -P -T --exclude-type=aufs --exclude-type=devfs --exclude-type=devtmpfs
5235 --exclude-type=fdescfs --exclude-type=iso9660 --exclude-type=linprocfs --exclude-type=procfs
5236 --exclude-type=squashfs --exclude-type=sysfs --exclude-type=tmpfs --exclude-type=unionfs'
5238 # default size is 512, so use -k for 1024
5239 df_string='df -T -k'
5240 # default size is 512, -H only for size in human readable format
5241 # older bsds don't support -T, pain, so we'll use partial output there
5242 df_test=$( df -H -T 2>/dev/null )
5243 if [[ -n $df_test ]];then
5244 df_string='df -k -T'
5249 hdd_data="$( eval $df_string )"
5250 log_function_data 'raw' "hdd_data:\n$hdd_data"
5251 hdd_used=$( echo "$hdd_data" | gawk -v bsdType=$BSD_TYPE '
5253 # this is used for specific cases where bind, or incorrect multiple mounts to same partitions,
5254 # is present. The value is searched for an earlier appearance of that partition and if it is
5255 # present, the data is not added into the partition used size.
5257 # this handles a case where the same dev item is mounted twice to different points
5262 # using $1, not $2, because older bsd df do not have -T, filesystem type
5263 ( bsdType != "" ) && $1 ~ /^(aufs|devfs|devtmpfs|fdescfs|filesystem|iso9660|linprocfs|procfs|squashfs|sysfs|tmpfs|type|unionfs)$/ {
5264 # note use next, not getline or it does not work right
5267 # also handles odd dm-1 type, from lvm, and mdraid, and some other bsd partition syntax
5268 # note that linux 3.2.45-grsec-9th types kernels have this type of partition name: /dev/xvdc (no number, letter)
5269 /^\/dev\/(mapper\/|[hsv]d[a-z][0-9]+|dm[-]?[0-9]+|ada[0-9]+p[0-9]+.*|md[0-9]+|[aw]d[0-9]+s.*|xvd[a-z])/ {
5270 # this handles the case where the first item is too long
5271 # and makes df wrap output to next line, so here we advance
5272 # it to the next line for that single case. Using df -P should
5273 # make this unneeded but leave it in just in case
5274 if ( NF < 6 && $0 !~ /.*%/ ) {
5275 devSet = devSet "~" $1 "~"
5278 # if the first item caused a wrap, use one less than standard
5279 # testing for the field with % in it, ie: 34%, then go down from there
5280 # this also protects against cases where the mount point has a space in the
5281 # file name, thus breaking going down from $NF directly.
5282 # some bsds will also have only 6 items
5284 devWorking="~" $1 "~"
5285 mountWorking="~" $6 "~"
5286 if ( partitionsSet !~ mountWorking && devSet !~ devWorking ) {
5289 partitionsSet = partitionsSet mountWorking
5290 # make sure to only include bsd real lines here, ie, short df output
5291 if ( $1 ~ /^\/dev\// ) {
5292 devSet = devSet devWorking
5295 # otherwise use standard
5296 else if ( $6 ~ /.*%/ ) {
5297 devWorking="~" $1 "~"
5298 mountWorking="~" $7 "~"
5299 if ( partitionsSet !~ mountWorking && devSet !~ devWorking ) {
5302 partitionsSet = partitionsSet mountWorking
5303 devSet = devSet devWorking
5305 # and if this is not detected, give up, we need user data to debug
5314 if [[ -z $hdd_used ]];then
5317 log_function_data "hdd_used: $hdd_used"
5318 # create the initial array strings:
5319 # disk-dev, capacity, name, usb or not
5320 # final item is the total of the disk
5323 if [[ $B_PARTITIONS_FILE == 'true' ]];then
5325 gawk -v hddused="$hdd_used" '
5327 driveSize = $(NF - 1)*1024/1000**3
5328 gsub(/,/, " ", driveSize)
5329 gsub(/^ +| +$/, "", driveSize)
5330 printf( $NF",%.1fGB,,\n", driveSize )
5332 # See http://lanana.org/docs/device-list/devices-2.6+.txt for major numbers used below
5333 # $1 ~ /^(3|22|33|8)$/ && $2 % 16 == 0 {
5336 # special case from this data: 8 0 156290904 sda
5337 # note: vm has 252/253/254 known starter, grsec has 202
5338 $1 ~ /^(3|8|22|33|202|252|253|254)$/ && $NF ~ /[hsv]d[a-z]$/ && ( $2 % 16 == 0 || $2 % 16 == 8 ) {
5343 size = size*1024/1000**3 # calculate size in GB size
5344 workingUsed = hddused*1024/1000**3 # calculate workingUsed in GB used
5345 # this handles a special case with livecds where no hdd_used is detected
5346 if ( size > 0 && hddused == "na" ) {
5347 size = sprintf( "%.1f", size )
5350 else if ( size > 0 && workingUsed > 0 ) {
5351 diskUsed = workingUsed*100/size # calculate used percentage
5352 diskUsed = sprintf( "%.1f", diskUsed )
5353 size = sprintf( "%.1f", size )
5354 print size "GB," diskUsed "% used"
5357 print "NA,-" # print an empty array, this will be further handled in the print out function
5359 }' $FILE_PARTITIONS ) )
5360 log_function_data 'cat' "$FILE_PARTITIONS"
5363 temp_array=${A_HDD_DATA[@]}
5364 log_function_data "A_HDD_DATA: $temp_array"
5368 ## fills out the A_HDD_DATA array with disk names
5369 get_hard_drive_data_advanced()
5372 local a_temp_working='' a_temp_scsi='' temp_holder='' temp_name='' i='' j=''
5373 local sd_ls_by_id='' ls_disk_by_id='' usb_exists='' temp_array=''
5375 ## check for all ide type drives, non libata, only do it if hdx is in array
5376 ## this is now being updated for new /sys type paths, this may handle that ok too
5377 if [[ -n $( grep -E 'hd[a-z]' <<< ${A_HDD_DATA[@]} ) ]];then
5378 # remember, we're using the last array item to store the total size of disks
5379 for (( i=0; i < ${#A_HDD_DATA[@]} - 1; i++ ))
5382 a_temp_working=( ${A_HDD_DATA[i]} )
5384 if [[ -n $( grep -E '^hd[a-z]' <<< ${a_temp_working[0]} ) ]];then
5385 if [[ -e /proc/ide/${a_temp_working[0]}/model ]];then
5386 a_temp_working[2]="$( remove_erroneous_chars /proc/ide/${a_temp_working[0]}/model )"
5388 a_temp_working[2]="Name n/a"
5390 # these loops are to easily extend the cpu array created in the gawk script above with more fields per cpu.
5391 for (( j=0; j < ${#a_temp_working[@]}; j++ ))
5393 if [[ $j -gt 0 ]];then
5394 A_HDD_DATA[i]="${A_HDD_DATA[i]},${a_temp_working[$j]}"
5396 A_HDD_DATA[i]="${a_temp_working[$j]}"
5403 ## then handle libata names
5404 # first get the ata device names, put them into an array
5406 if [[ $B_SCSI_FILE == 'true' ]]; then
5407 a_temp_scsi=( $( gawk '
5417 if (b[i] ~ / *type: *direct-access.*/) {
5418 #c=gensub(/^ *vendor: (.+) +model: (.+) +rev: (.+)$/,"\\1 \\2 \\3","g",a[i])
5419 #c=gensub( /^ *vendor: (.+) +model: (.+) +rev:.*$/,"\\1 \\2","g",a[i] )
5420 # the vendor: string is useless, and is a bug, ATA is not a vendor for example
5421 c=gensub( /^ *vendor: (.+) +model: (.+) +rev:.*$/, "\\2", "g", a[i] )
5423 gsub(/^ +| +$/, "", c)
5424 gsub(/ [ \t]+/, " ", c)
5426 # we actually want this data, so leaving this off for now
5427 # if (c ~ /\<flash\>|\<pendrive\>|memory stick|memory card/) {
5434 log_function_data 'cat' "$FILE_SCSI"
5438 ## then we'll loop through that array looking for matches.
5439 if [[ -n $( grep -E 'sd[a-z]' <<< ${A_HDD_DATA[@]} ) ]];then
5440 # first pack the main ls variable so we don't have to keep using ls /dev...
5441 # not all systems have /dev/disk/by-id
5442 ls_disk_by_id="$( ls -l /dev/disk/by-id 2>/dev/null )"
5443 for (( i=0; i < ${#A_HDD_DATA[@]} - 1; i++ ))
5445 if [[ -n $( grep -E '^sd[a-z]' <<< ${A_HDD_DATA[$i]} ) ]];then
5447 a_temp_working=( ${A_HDD_DATA[$i]} )
5449 # /sys/block/[sda,hda]/device/model
5450 # this is handles the new /sys data types first
5451 if [[ -e /sys/block/${a_temp_working[0]}/device/model ]];then
5452 temp_name="$( remove_erroneous_chars /sys/block/${a_temp_working[0]}/device/model )"
5453 temp_name=$( tr ' ' '_' <<< $temp_name | cut -d '-' -f 1 )
5454 elif [[ ${#a_temp_scsi[@]} -gt 0 ]];then
5455 for (( j=0; j < ${#a_temp_scsi[@]}; j++ ))
5457 ## ok, ok, it's incomprehensible, search /dev/disk/by-id for a line that contains the
5458 # discovered disk name AND ends with the correct identifier, sdx
5459 # get rid of whitespace for some drive names and ids, and extra data after - in name
5460 temp_name=$( tr ' ' '_' <<< ${a_temp_scsi[$j]} | cut -d '-' -f 1 )
5461 sd_ls_by_id=$( grep -Em1 ".*$temp_name.*${a_temp_working[0]}$" <<< "$ls_disk_by_id" )
5463 if [[ -n $sd_ls_by_id ]];then
5464 temp_name=${a_temp_scsi[$j]}
5467 # test to see if we can get a better name output when null
5468 if [[ -n $temp_name ]];then
5469 temp_name=$temp_name
5475 if [[ -z $temp_name ]];then
5476 temp_name="Name n/a"
5478 usb_exists=$( grep -Em1 "usb-.*$temp_name.*${a_temp_working[0]}$" <<< "$ls_disk_by_id" )
5479 if [[ -n $usb_exists ]];then
5480 a_temp_working[3]='USB'
5483 a_temp_working[2]=$temp_name
5484 # these loops are to easily extend the cpu array created in the gawk script above with more fields per cpu.
5485 for (( j=0; j < ${#a_temp_working[@]}; j++ ))
5487 if [[ $j -gt 0 ]];then
5488 A_HDD_DATA[i]="${A_HDD_DATA[i]},${a_temp_working[$j]}"
5490 A_HDD_DATA[i]="${a_temp_working[$j]}"
5495 unset ls_disk_by_id # and then let's dump the data we don't need
5497 temp_array=${A_HDD_DATA[@]}
5498 log_function_data "A_HDD_DATA: $temp_array"
5502 # args: $1 - which drive to get serial number of
5503 get_hdd_serial_number()
5509 get_partition_dev_data 'id'
5511 # lrwxrwxrwx 1 root root 9 Apr 26 09:32 scsi-SATA_ST3160827AS_5MT2HMH6 -> ../../sdc
5512 # exit on the first instance
5513 hdd_serial=$( gawk '
5515 serial=gensub( /^(.+)_([^_]+)$/, "\\2", 1, $9 )
5518 }' <<< "$DEV_DISK_ID" )
5521 log_function_data "hdd serial: $hdd_serial"
5525 # a few notes, normally hddtemp requires root, but you can set user rights in /etc/sudoers.
5526 # args: $1 - /dev/<disk> to be tested for
5530 local hdd_temp='' sudo_command=''
5532 if [[ $B_HDDTEMP_TESTED != 'true' ]];then
5533 B_HDDTEMP_TESTED='true'
5534 HDDTEMP_PATH=$( type -p hddtemp )
5536 if [[ $B_SUDO_TESTED != 'true' ]];then
5537 B_SUDO_TESTED='true'
5538 SUDO_PATH=$( type -p sudo )
5541 if [[ -n $HDDTEMP_PATH && -n $1 ]];then
5542 # only use sudo if not root, -n option requires sudo -V 1.7 or greater. sudo will just error out
5543 # which is the safest course here for now, otherwise that interactive sudo password thing is too annoying
5544 # important: -n makes it non interactive, no prompt for password
5545 if [[ $B_ROOT != 'true' && -n $SUDO_PATH ]];then
5546 sudo_command='sudo -n '
5548 # this will fail if regular user and no sudo present, but that's fine, it will just return null
5549 hdd_temp=$( eval $sudo_command $HDDTEMP_PATH -nq -u C $1 )
5550 if [[ -n $hdd_temp && -n $( grep -E '^([0-9\.]+)$' <<< $hdd_temp ) ]];then
5561 local init_type='' init_version='' rc_type='' rc_version='' temp_array=''
5562 local ls_run='' strings_init_version=''
5563 local runlevel=$( get_runlevel_data )
5564 local default_runlevel=$( get_runlevel_default )
5566 # this test is pretty solid, if pid 1 is owned by systemd, it is systemd
5567 # otherwise that is 'init', which covers the rest of the init systems, I think anyway.
5568 # more data may be needed for other init systems.
5569 if [[ -e /proc/1/comm && -n $( grep -s 'systemd' /proc/1/comm ) ]];then
5571 if [[ -n $( type -p systemd ) ]];then
5572 init_version=$( get_de_app_version 'systemd' '^systemd' '2' )
5574 if [[ -z $init_version && -n $( type -p systemctl ) ]];then
5575 init_version=$( get_de_app_version 'systemctl' '^systemd' '2' )
5579 # note: upstart-file-bridge.pid upstart-socket-bridge.pid upstart-udev-bridge.pid
5580 if [[ -n $( /sbin/init --version 2>/dev/null | grep 'upstart' ) ]];then
5582 # /sbin/init --version == init (upstart 1.12.1)
5583 init_version=$( get_de_app_version 'init' 'upstart' '3' )
5584 elif [[ -n $( type -p epoch ) ]];then
5586 # epoch version == Epoch Init System 1.0.1 "Sage"
5587 init_version=$( get_de_app_version 'epoch' '^Epoch' '4' )
5589 # http://smarden.org/runit/sv.8.html
5590 elif [[ -e /sbin/runit-init || -e /etc/runit || -n $( type -p sv ) ]];then
5591 init_type='runit' # lower case
5592 # no data on version yet
5593 elif [[ -f /etc/inittab ]];then
5594 init_type='SysVinit'
5595 if [[ -n $( type -p strings ) ]];then
5596 strings_init_version="$( strings /sbin/init | grep -E 'version[[:space:]]+[0-9]' )"
5598 if [[ -n $strings_init_version ]];then
5599 init_version=$( gawk '{print $2}' <<< "$strings_init_version" )
5602 elif [[ -f /etc/ttys ]];then
5603 init_type='init (bsd)'
5606 if [[ -n $( grep 'openrc' <<< "$ls_run" ) ]];then
5608 # /sbin/openrc --version == openrc (OpenRC) 0.13
5609 if [[ -n $( type -p openrc ) ]];then
5610 rc_version=$( get_de_app_version 'openrc' '^openrc' '3' )
5611 # /sbin/rc --version == rc (OpenRC) 0.11.8 (Gentoo Linux)
5612 elif [[ -n $( type -p rc ) ]];then
5613 rc_version=$( get_de_app_version 'rc' '^rc' '3' )
5615 ## assume sysvrc, but this data is too buggy and weird and inconsistent to have meaning
5616 # leaving this off for now
5617 # elif [[ -f /etc/inittab ]];then
5619 # # this is a guess that rc and init are same versions, may need updates / fixes
5620 # rc_version=$init_version
5632 "$default_runlevel" )
5636 temp_array=${A_INIT_DATA[@]}
5637 log_function_data "A_INIT_DATA: $temp_array"
5642 get_kernel_version()
5646 local kernel_version='' ksplice_kernel_version=''
5648 kernel_version=$( uname -rm )
5650 if [[ -n $( type -p uptrack-uname ) && -n $kernel_version ]];then
5651 ksplice_kernel_version=$( uptrack-uname -rm )
5652 if [[ $kernel_version != $ksplice_kernel_version ]];then
5653 kernel_version="$ksplice_kernel_version (ksplice)"
5656 log_function_data "kernel_version: $kernel_version - ksplice_kernel_version: $ksplice_kernel_version"
5658 echo $kernel_version
5669 if [[ $B_LSPCI == 'true' ]];then
5670 lspci_data="$( lspci -$1 | gawk '{
5671 gsub(/\(prog-if[^)]*\)/,"")
5672 sub(/^0000:/, "", $0) # seen case where the 0000: is prepended, rare, but happens
5678 log_function_data 'raw' "lspci_data $1:\n$lspci_data"
5694 }' <<< "$Lspci_n_Data" )
5704 local temp_array='' separator='' id_file='' file_data='' array_string=''
5705 local id_dir='/sys/class/dmi/id/' dmi_data=''
5706 local machine_files="
5707 sys_vendor product_name product_version product_serial product_uuid
5708 board_vendor board_name board_version board_serial
5709 bios_vendor bios_version bios_date
5712 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
5713 machine_files="$machine_files
5714 chassis_vendor chassis_type chassis_version chassis_serial
5717 if [[ -d $id_dir ]];then
5718 for id_file in $machine_files
5721 if [[ -r $id_dir$id_file ]];then
5727 gsub(/'"$BAN_LIST_NORMAL"'/, "", $0)
5729 # yes, there is a typo in a user data set, unknow
5730 # Base Board Version|Base Board Serial Number
5731 # Chassis Manufacturer|Chassis Version|Chassis Serial Number
5732 # System manufacturer|System Product Name|System Version
5733 # To Be Filled By O.E.M.
5734 sub(/^Base Board .*|^Chassis .*|.*O\.E\.M\..*|.*OEM.*|^Not .*|^System .*|.*unknow.*|.*N\/A.*|none|^To be filled.*/, "", $0)
5735 gsub(/bios|acpi/, "", $0)
5736 sub(/http:\/\/www.abit.com.tw\//, "Abit", $0)
5737 gsub(/^ +| +$/, "", $0)
5738 gsub(/ [ \t]+/, " ", $0)
5740 }' < $id_dir$id_file )
5742 array_string="$array_string$separator$file_data"
5747 if [[ -n $DMIDECODE_DATA ]];then
5748 if [[ $B_ROOT == 'true' ]];then
5749 # this handles very old systems, like Lenny 2.6.26, with dmidecode, but no data
5750 if [[ -n $( grep -i 'no smbios ' <<< "$DMIDECODE_DATA" ) ]];then
5751 array_string='dmidecode-no-smbios-dmi-data'
5752 # please note: only dmidecode version 2.11 or newer supports consistently the -s flag
5754 array_string=$( gawk -F ':' '
5757 baseboardManufacturer=""
5758 baseboardProductName=""
5759 baseboardSerialNumber=""
5762 biosRevision="" # only available from dmidecode
5763 biosRomSize="" # only available from dmidecode
5766 chassisManufacturer=""
5767 chassisSerialNumber=""
5770 systemManufacturer=""
5771 systemProductName=""
5773 systemSerialNumber=""
5775 bItemFound="" # we will only output if at least one item was found
5783 /^Bios Information/ {
5784 while ( getline && !/^$/ ) {
5785 if ( $1 ~ /^Release Date/ ) { biosReleaseDate=$2 }
5786 if ( $1 ~ /^BIOS Revision/ ) { biosRevision=$2 }
5787 if ( $1 ~ /^ROM Size/ ) { biosRomSize=$2 }
5788 if ( $1 ~ /^Vendor/ ) { biosVendor=$2 }
5789 if ( $1 ~ /^Version/ ) { biosVersion=$2 }
5791 testString=biosReleaseDate biosRevision biosRomSize biosVendor biosVersion
5792 if ( testString != "" ) {
5797 /^Base Board Information/ {
5798 while ( getline && !/^$/ ) {
5799 if ( $1 ~ /^Manufacturer/ ) { baseboardManufacturer=$2 }
5800 if ( $1 ~ /^Product Name/ ) { baseboardProductName=$2 }
5801 if ( $1 ~ /^Serial Number/ ) { baseboardSerialNumber=$2 }
5803 testString=baseboardManufacturer baseboardProductName baseboardSerialNumber
5804 if ( testString != "" ) {
5809 /^Chassis Information/ {
5810 while ( getline && !/^$/ ) {
5811 if ( $1 ~ /^Manufacturer/ ) { chassisManufacturer=$2 }
5812 if ( $1 ~ /^Serial Number/ ) { chassisSerialNumber=$2 }
5813 if ( $1 ~ /^Type/ ) { chassisType=$2 }
5814 if ( $1 ~ /^Version/ ) { chassisVersion=$2 }
5816 testString=chassisManufacturer chassisSerialNumber chassisType chassisVersion
5817 if ( testString != "" ) {
5822 /^System Information/ {
5823 while ( getline && !/^$/ ) {
5824 if ( $1 ~ /^Manufacturer/ ) { systemManufacturer=$2 }
5825 if ( $1 ~ /^Product Name/ ) { systemProductName=$2 }
5826 if ( $1 ~ /^Version/ ) { systemVersion=$2 }
5827 if ( $1 ~ /^Serial Number/ ) { systemSerialNumber=$2 }
5828 if ( $1 ~ /^UUID/ ) { systemUuid=$2 }
5830 testString=systemManufacturer systemProductName systemVersion systemSerialNumber systemUuid
5831 if ( testString != "" ) {
5836 ( bSys == "true" && bCha="true" && bBio == "true" && bBas == "true" ) {
5837 exit # stop the loop
5840 if ( bItemFound == "true" ) {
5841 fullString = systemManufacturer "," systemProductName "," systemVersion "," systemSerialNumber
5842 fullString = fullString "," systemUuid "," baseboardManufacturer "," baseboardProductName
5843 fullString = fullString "," baseboardVersion "," baseboardSerialNumber "," biosVendor
5844 fullString = fullString "," biosVersion "," biosReleaseDate "," chassisManufacturer
5845 fullString = fullString "," chassisType "," chassisVersion "," chassisSerialNumber
5846 fullString = fullString "," biosRevision "," biosRomSize
5850 }' <<< "$DMIDECODE_DATA" )
5853 array_string='dmidecode-non-root-user'
5858 A_MACHINE_DATA=( $array_string )
5860 temp_array=${A_MACHINE_DATA[@]}
5861 # echo ${temp_array[@]}
5862 log_function_data "A_MACHINE_DATA: $temp_array"
5865 # B_ROOT='true';get_machine_data;exit
5866 ## return memory used/installed
5870 local memory='' memory_full=''
5871 if [[ $B_MEMINFO_FILE == 'true' ]];then
5876 /^(MemFree|Buffers|Cached):/ {
5880 used = tot - notused
5881 printf("%.1f/%.1fMB\n", used/1024, tot/1024)
5883 log_function_data 'cat' "$FILE_MEMINFO"
5884 elif [[ $B_SYSCTL == 'true' && -n $Sysctl_a_Data ]];then
5887 if [[ $BSD_VERSION == 'openbsd' ]];then
5890 memory=$( grep -i 'mem' <<< "$Sysctl_a_Data" | gawk -F "$gawk_fs" '
5895 # freebsd seems to use bytes here
5897 gsub(/^[^0-9]+|[^0-9]+$/,"",$2)
5898 realMemory = $2/1024
5899 if ( freeMemory != "" ) {
5903 # But, it uses K here. Openbsd does not seem to have this item
5904 # this can be either: Free Memory OR Free Memory Pages
5905 $1 ~ /^Free Memory/ {
5906 gsub(/[^0-9]/,"",$NF)
5908 if ( realMemory != "" ) {
5913 # hack: temp fix for openbsd: in case no free mem was detected but we have physmem
5914 if ( freeMemory == "" && realMemory != "" ) {
5915 printf("NA/%.1fMB\n", realMemory/1024)
5917 else if ( freeMemory != "" && realMemory != "" ) {
5918 used = realMemory - freeMemory
5919 printf("%.1f/%.1fMB\n", used/1024, realMemory/1024)
5924 log_function_data "memory: $memory"
5928 # process and return module version data
5929 get_module_version_number()
5932 local module_version=''
5934 if [[ $B_MODINFO_TESTED != 'true' ]];then
5935 B_MODINFO_TESTED='true'
5936 MODINFO_PATH=$( type -p modinfo )
5939 if [[ -n $MODINFO_PATH ]];then
5940 module_version=$( $MODINFO_PATH $1 2>/dev/null | gawk '
5946 gsub(/^ +| +$/, "", $2)
5947 gsub(/ [ \t]+/, " ", $2)
5953 echo "$module_version"
5954 log_function_data "module_version: $module_version"
5958 ## create array of network cards
5959 get_networking_data()
5963 local B_USB_NETWORKING='false' temp_array=''
5967 echo "$Lspci_v_Data" | gawk '
5970 counter=0 # required to handle cases of > 1 instance of the same chipset
5972 /^[0-9a-f:\.]+ (ethernet|network) (controller|bridge)/ || /^[0-9a-f:\.]+ [^:]+: .*(ethernet|network).*$/ {
5973 nic=gensub(/^[0-9a-f:\.]+ [^:]+: (.+)$/,"\\1","g",$0)
5974 #gsub(/realtek semiconductor/, "Realtek", nic)
5975 #gsub(/davicom semiconductor/, "Davicom", nic)
5976 # The doublequotes are necessary because of the pipes in the variable.
5977 gsub(/'"$BAN_LIST_NORMAL"'/, "", nic)
5979 gsub(/^ +| +$/, "", nic)
5980 gsub(/ [ \t]+/, " ", nic)
5981 # construct a unique string ending for each chipset detected, this allows for
5982 # multiple instances of the same exact chipsets, ie, dual gigabit
5983 nic = nic "~~" counter++
5984 aPciBusId[nic] = gensub(/(^[0-9a-f:\.]+) [^:]+: .+$/,"\\1","g",$0)
5985 # I do not understand why incrementing a string index makes sense?
5987 while ( getline && !/^$/ ) {
5990 ports[nic] = ports[nic] $4 " "
5992 if ( /driver in use/ ) {
5993 drivers[nic] = drivers[nic] gensub( /(.*): (.*)/ ,"\\2" ,"g" ,$0 ) ""
5995 else if ( /kernel modules/ ) {
5996 modules[nic] = modules[nic] gensub( /(.*): (.*)/ ,"\\2" ,"g" ,$0 ) ""
6010 a[j] = eth[i] "x " i
6015 ## note: this loses the plural ports case, is it needed anyway?
6016 if ( ports[i] != "" ) {
6019 if ( drivers[i] != "" ) {
6020 useDrivers = drivers[i]
6022 if ( modules[i] != "" ) {
6023 useModules = modules[i]
6025 if ( aPciBusId[i] != "" ) {
6026 usePciBusId = aPciBusId[i]
6028 # create array primary item for master array
6029 # and strip out the counter again, this handled dual cards with same chipset
6030 sub( /~~[0-9]+$/, "", a[j] )
6031 sub( / $/, "", usePorts ) # clean off trailing whitespace
6032 print a[j] "," useDrivers "," usePorts "," useModules, "," usePciBusId
6037 get_networking_usb_data
6038 if [[ $B_SHOW_ADVANCED_NETWORK == 'true' || $B_USB_NETWORKING == 'true' ]];then
6039 get_network_advanced_data
6041 temp_array=${A_NETWORK_DATA[@]}
6042 log_function_data "A_NETWORK_DATA: $temp_array"
6047 get_network_advanced_data()
6050 local a_network_adv_working='' if_path='' working_path='' working_uevent_path='' dir_path=''
6051 local if_id='' speed='' duplex='' mac_id='' oper_state='' chip_id=''
6052 local usb_data='' usb_vendor='' usb_product='' product_path='' driver_test=''
6054 for (( i=0; i < ${#A_NETWORK_DATA[@]}; i++ ))
6057 a_network_adv_working=( ${A_NETWORK_DATA[i]} )
6058 # reset these every go round
6067 if [[ -z $( grep '^usb-' <<< ${a_network_adv_working[4]} ) ]];then
6068 # note although this may exist technically don't use it, it's a virtual path
6069 # and causes weird cat errors when there's a missing file as well as a virtual path
6070 # /sys/bus/pci/devices/0000:02:02.0/net/eth1
6071 # real paths are: /sys/devices/pci0000:00/0000:00:1e/0/0000:02:02.0/net/eth1/uevent
6072 # and on older debian kernels: /sys/devices/pci0000:00/0000:02:02.0/net:eth1/uevent
6073 # but broadcom shows this sometimes:
6074 # /sys/devices/pci0000:00/0000:00:03.0/0000:03:00.0/ssb0:0/uevent:['DRIVER=b43', 'MODALIAS=ssb:v4243id0812rev0D']:
6075 working_path="/sys/bus/pci/devices/0000:${a_network_adv_working[4]}"
6076 # now we want the real one, that xiin also displays, without symbolic links.
6077 if [[ -e $working_path ]];then
6078 working_path=$( readlink -f $working_path 2>/dev/null )
6079 # sometimes there is another directory between the path and /net
6080 if [[ ! -e $working_path/net ]];then
6081 # using find here, probably will need to also use it in usb part since the grep
6082 # method seems to not be working now. Slice off the rest, which leaves the basic path
6083 working_path=$( find $working_path/*/net/*/uevent 2>/dev/null | \
6087 # working_path=$( ls /sys/devices/pci*/*/0000:${a_network_adv_working[4]}/net/*/uevent )
6089 # now we'll use the actual vendor:product string instead
6090 usb_data=${a_network_adv_working[10]}
6091 usb_vendor=$( cut -d ':' -f 1 <<< $usb_data )
6092 usb_product=$( cut -d ':' -f 2 <<< $usb_data )
6093 # this grep returns the path plus the contents of the file, with a colon separator, so slice that off
6094 # /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/idVendor
6095 working_path=$( grep -s "$usb_vendor" /sys/devices/pci*/*/usb*/*/*/idVendor | \
6096 sed -e "s/idVendor:$usb_vendor//" -e '/driver/d' )
6097 # try an alternate path if first one doesn't work
6098 # /sys/devices/pci0000:00/0000:00:0b.1/usb1/1-1/idVendor
6099 if [[ -z $working_path ]];then
6100 working_path=$( grep -s "$usb_vendor" /sys/devices/pci*/*/usb*/*/idVendor | \
6101 sed -e "s/idVendor:$usb_vendor//" -e '/driver/d' )
6102 product_path=$( grep -s "$usb_product" /sys/devices/pci*/*/usb*/*/idProduct | \
6103 sed -e "s/idProduct:$usb_product//" -e '/driver/d' )
6105 product_path=$( grep -s "$usb_product" /sys/devices/pci*/*/usb*/*/*/idProduct | \
6106 sed -e "s/idProduct:$usb_product//" -e '/driver/d' )
6109 # make sure it's the right product/vendor match here, it will almost always be but let's be sure
6110 if [[ -n $working_path && -n $product_path ]] && [[ $working_path == $product_path ]];then
6111 #if [[ -n $working_path ]];then
6112 # now ls that directory and get the numeric starting sub directory and that should be the full path
6113 # to the /net directory part
6114 dir_path=$( ls ${working_path} 2>/dev/null | grep -sE '^[0-9]' )
6115 working_uevent_path="${working_path}${dir_path}"
6118 # /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/uevent grep for DRIVER=
6119 # /sys/devices/pci0000:00/0000:00:0b.1/usb1/1-1/1-1:1.0/uevent
6120 if [[ -n $usb_data ]];then
6121 driver_test=$( grep -si 'DRIVER=' $working_uevent_path/uevent | cut -d '=' -f 2 )
6122 if [[ -n $driver_test ]];then
6123 a_network_adv_working[1]=$driver_test
6126 log_function_data "PRE: working_path: $working_path\nworking_uevent_path: $working_uevent_path"
6128 # this applies in two different cases, one, default, standard, two, for usb, this is actually
6129 # the short path, minus the last longer numeric directory name, ie:
6130 # from debian squeeze 2.6.32-5-686:
6131 # /sys/devices/pci0000:00/0000:00:0b.1/usb1/1-1/net/wlan0/address
6132 if [[ -e $working_path/net ]];then
6133 if_path=$( ls $working_path/net 2>/dev/null )
6135 working_path=$working_path/net/$if_path
6136 # this is the normal usb detection if the first one didn't work
6137 elif [[ -n $usb_data && -e $working_uevent_path/net ]];then
6138 if_path=$( ls $working_uevent_path/net 2>/dev/null )
6140 working_path=$working_uevent_path/net/$if_path
6141 # 2.6.32 debian lenny kernel shows not: /net/eth0 but /net:eth0
6143 if_path=$( ls $working_path 2>/dev/null | grep 'net:' )
6144 if_id=$( cut -d ':' -f 2 <<< "$if_path" )
6145 working_path=$working_path/$if_path
6147 log_function_data "POST: working_path: $working_path\nif_path: $if_path - if_id: $if_id"
6149 if [[ -n $if_path ]];then
6150 if [[ -r $working_path/speed ]];then
6151 speed=$( cat $working_path/speed 2>/dev/null )
6153 if [[ -r $working_path/duplex ]];then
6154 duplex=$( cat $working_path/duplex 2>/dev/null )
6156 if [[ -r $working_path/address ]];then
6157 mac_id=$( cat $working_path/address 2>/dev/null )
6159 if [[ -r $working_path/operstate ]];then
6160 oper_state=$( cat $working_path/operstate 2>/dev/null )
6164 if [[ -n ${a_network_adv_working[10]} ]];then
6165 chip_id=${a_network_adv_working[10]}
6167 A_NETWORK_DATA[i]=${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
6174 get_networking_usb_data()
6177 local lsusb_path='' lsusb_data='' a_usb='' array_count=''
6179 # now we'll check for usb wifi, a work in progress
6180 # USB_NETWORK_SEARCH
6181 # alsa usb detection by damentz
6182 # for every sound card symlink in /proc/asound - display information about it
6183 lsusb_path=$( type -p lsusb )
6184 # if lsusb exists, the file is a symlink, and contains an important usb exclusive file: continue
6185 if [[ -n $lsusb_path ]]; then
6186 # send error messages of lsusb to /dev/null as it will display a bunch if not a super user
6187 lsusb_data="$( $lsusb_path 2>/dev/null )"
6188 # also, find the contents of usbid in lsusb and print everything after the 7th word on the
6189 # corresponding line. Finally, strip out commas as they will change the driver :)
6190 if [[ -n $lsusb_data ]];then
6199 /'"$USB_NETWORK_SEARCH"'/ && !/bluetooth| hub|keyboard|mouse|printer| ps2|reader|scan|storage/ {
6201 gsub( /,/, " ", $0 )
6202 gsub(/'"$BAN_LIST_NORMAL"'/, "", $0)
6203 gsub(/ [ \t]+/, " ", $0)
6204 #sub(/realtek semiconductor/, "Realtek", $0)
6205 #sub(/davicom semiconductor/, "Davicom", $0)
6206 #sub(/Belkin Components/, "Belkin", $0)
6208 for ( i=7; i<= NF; i++ ) {
6209 string = string separator $i
6214 print string ",,,,usb-" $2 "-" $4 ",,,,,," $6
6216 }' <<< "$lsusb_data" ) )
6218 if [[ ${#a_usb[@]} -gt 0 ]];then
6219 array_count=${#A_NETWORK_DATA[@]}
6220 for (( i=0; i < ${#a_usb[@]}; i++ ))
6222 A_NETWORK_DATA[$array_count]=${a_usb[i]}
6225 # need this to get the driver data for -N regular output, but no need
6226 # to run the advanced stuff unless required
6227 B_USB_NETWORKING='true'
6231 # echo $B_USB_NETWORKING
6235 get_networking_wan_ip_data()
6240 # get ip using wget redirect to stdout. This is a clean, text only IP output url,
6241 # single line only, ending in the ip address. May have to modify this in the future
6242 # to handle ipv4 and ipv6 addresses but should not be necessary.
6243 # awk has bad regex handling so checking it with grep -E instead
6244 # ip=$( echo 2001:0db8:85a3:0000:0000:8a2e:0370:7334 | gawk --re-interval '
6245 # ip=$( wget -q -O - $WAN_IP_URL | gawk --re-interval '
6246 ip=$( wget -t 1 -T $WGET_TIMEOUT -q -O - $WAN_IP_URL | gawk --re-interval '
6252 if [[ -z $ip ]];then
6254 elif [[ -z $( grep -Es \
6255 '^([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
6256 ip='IP Source Corrupt!'
6259 log_function_data "ip: $ip"
6263 get_networking_local_ip_data()
6267 local ip_tool_command=$( type -p ip )
6268 local temp_array='' ip_tool='ip' ip_tool_data=''
6269 # the chances for all new systems to have ip by default are far higher than
6270 # the deprecated ifconfig. Only try for ifconfig if ip is not present in system
6271 if [[ -z $ip_tool_command ]];then
6272 ip_tool_command=$( type -p ifconfig )
6275 ip_tool_command="$ip_tool_command addr"
6277 if [[ -n "$ip_tool_command" ]];then
6278 if [[ $ip_tool == 'ifconfig' ]];then
6279 ip_tool_data="$( $ip_tool_command | gawk '
6281 line=gensub(/^([a-z]+[0-9][:]?[[:space:]].*)/, "\n\\1", $0)
6284 # note, ip addr does not have proper record separation, so creating new lines explicitly here at start
6285 # of each IF record item. Also getting rid of the unneeded numeric line starters, now it can be parsed
6286 # like ifconfig more or less
6287 elif [[ $ip_tool == 'ip' ]];then
6288 ip_tool_data="$( eval ${ip_tool_command} | sed 's/^[0-9]\+:[[:space:]]\+/\n/' )"
6291 if [[ -z $ip_tool_command ]];then
6292 A_INTERFACES_DATA=( "Interfaces program 'ip' missing. Please check: $SCRIPT_NAME --recommends" )
6293 elif [[ -n "$ip_tool_data" ]];then
6294 IFS=$'\n' # $ip_tool_command
6295 A_INTERFACES_DATA=( $(
6296 gawk -v ipTool=$ip_tool -v bsdType=$BSD_TYPE '
6304 # skip past the lo item
6306 while (getline && !/^$/ ) {
6307 # do nothing, just get past this entry item
6311 # not clear on why inet is coming through, but this gets rid of it
6312 # as first line item.
6314 gsub(/^ +| +$/, "", $0)
6315 gsub(/ [ \t]+/, " ", $0)
6317 # prep this this for ip addr: eth0:
6318 sub(/:/, "", interface)
6322 aInterfaces[interface]++
6324 while (getline && !/^$/ ) {
6325 if ( ipTool == "ifconfig" ) {
6327 ifIp = gensub( /addr:([0-9\.]+)/, "\\1", "g", $2 )
6329 ifMask = gensub( /mask:([0-9\.]+)/, "\\1", "g", $NF )
6332 if (/inet6 addr:/) {
6335 if ( bsdType == "bsd" ) {
6336 if ( $1 == "inet" ) {
6338 if ( $3 == "netmask" ) {
6342 if ( $0 ~ /inet6.*%/ ) {
6348 else if ( ipTool == "ip" ) {
6349 if ( $1 == "inet" ) {
6352 if ( $1 == "inet6" ) {
6357 # slice off the digits that are sometimes tacked to the end of the address,
6359 sub(/\/[0-9]+/, "", ifIp)
6360 sub(/\/[0-9]+/, "", ifIpV6)
6361 ipAddresses[interface] = ifIp "," ifMask "," ifIpV6
6365 for (i in aInterfaces) {
6368 if (ipAddresses[i] != "") {
6369 ifData = ipAddresses[i]
6371 # create array primary item for master array
6372 # tested needed to avoid bad data from above, if null it is garbage
6373 # this is the easiest way to handle junk I found, improve if you want
6374 if ( ifData != "" ) {
6375 print a[j] "," ifData
6379 }' <<< "$ip_tool_data" ) )
6382 A_INTERFACES_DATA=( "Interfaces program $ip_tool present but created no data. " )
6384 temp_array=${A_INTERFACES_DATA[@]}
6385 log_function_data "A_INTERFACES_DATA: $temp_array"
6388 # get_networking_local_ip_data;exit
6390 # get_networking_local_ip_data;exit
6391 get_optical_drive_data()
6395 local temp_array='' sys_uevent_path='' proc_cdrom='' link_list=''
6396 local separator='' linked='' disk='' item_string='' proc_info_string=''
6397 local dev_disks_links="$( ls /dev/dvd* /dev/cd* /dev/scd* 2>/dev/null )"
6398 # get the actual disk dev location, first try default which is easier to run, need to preserve line breaks
6399 local dev_disks_real="$( echo "$dev_disks_links" | xargs -L 1 readlink 2>/dev/null | sort -u )"
6400 # Some systems don't support xargs -L so we need to do it manually
6401 if [[ -z $dev_disks_real ]];then
6402 for linked in $dev_disks_links
6404 disk=$( readlink $linked 2>/dev/null )
6405 if [[ -n $disk ]];then
6406 disk=$( basename $disk ) # puppy shows this as /dev/sr0, not sr0
6407 if [[ -z $dev_disks_real || -z $( grep $disk <<< $dev_disks_real ) ]];then
6408 # need line break IFS for below, no white space
6409 dev_disks_real="$dev_disks_real$separator$disk"
6414 dev_disks_real="$( sort -u <<< "$dev_disks_real" )"
6420 # A_OPTICAL_DRIVE_DATA indexes: not going to use all these, but it's just as easy to build the full
6421 # data array and use what we need from it as to update it later to add features or items
6422 # 0 - true dev path, ie, sr0, hdc
6423 # 1 - dev links to true path
6424 # 2 - device vendor - for hdx drives, vendor model are one string from proc
6426 # 4 - device rev version
6428 # 6 - multisession support
6438 if [[ -n $dev_disks_real ]];then
6439 if [[ $B_SHOW_FULL_OPTICAL == 'true' ]];then
6440 proc_cdrom="$( cat /proc/sys/dev/cdrom/info 2>/dev/null )"
6443 A_OPTICAL_DRIVE_DATA=( $(
6444 for disk in $dev_disks_real
6446 for linked in $dev_disks_links
6448 if [[ -n $( readlink $linked | grep $disk ) ]];then
6449 linked=$( basename $linked )
6450 link_list="$link_list$separator$linked"
6454 item_string="$disk,$link_list"
6464 # this is only for new sd type paths in /sys, otherwise we'll use /proc/ide
6465 if [[ -z $( grep '^hd' <<< $disk ) ]];then
6466 sys_path=$( ls /sys/devices/pci*/*/host*/target*/*/block/$disk/uevent 2>/dev/null | sed "s|/block/$disk/uevent||" )
6467 # no need to test for errors yet, probably other user systems will require some alternate paths though
6468 if [[ -n $sys_path ]];then
6469 vendor=$( cat $sys_path/vendor 2>/dev/null )
6470 model=$( cat $sys_path/model 2>/dev/null | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/,//g' )
6471 state=$( cat $sys_path/state 2>/dev/null | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/,//g' )
6472 rev_number=$( cat $sys_path/rev 2>/dev/null | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/,//g' )
6474 elif [[ -e /proc/ide/$disk/model ]];then
6475 vendor=$( cat /proc/ide/$disk/model 2>/dev/null )
6477 if [[ -n $vendor ]];then
6483 gsub(/'"$BAN_LIST_NORMAL"'/, "", $0)
6484 sub(/TSSTcorp/, "TSST ", $0) # seen more than one of these weird ones
6486 gsub(/^[[:space:]]*|[[:space:]]*$/, "", $0)
6487 gsub(/ [[:space:]]+/, " ", $0)
6491 # this needs to run no matter if there's proc data or not to create the array comma list
6492 if [[ $B_SHOW_FULL_OPTICAL == 'true' ]];then
6493 proc_info_string=$( gawk -v diskId=$disk '
6507 # first get the position of the device name from top field
6508 # we will use this to get all the other data for that column
6510 for ( position=3; position <= NF; position++ ) {
6511 if ( $position == diskId ) {
6519 /Can read multisession:/ {
6520 multisession=$( position + 1 )
6523 mcn=$( position + 1 )
6526 audio=$( position + 1 )
6529 cdr=$( position + 1 )
6531 /Can write CD-RW:/ {
6532 cdrw=$( position + 1 )
6535 dvd=$( position + 1 )
6537 /Can write DVD-R:/ {
6538 dvdr=$( position + 1 )
6540 /Can write DVD-RAM:/ {
6541 dvdram=$( position + 1 )
6544 print speed "," multisession "," mcn "," audio "," cdr "," cdrw "," dvd "," dvdr "," dvdram
6546 ' <<< "$proc_cdrom" )
6548 item_string="$item_string,$vendor,$model,$rev_number,$proc_info_string,$state"
6554 temp_array=${A_OPTICAL_DRIVE_DATA[@]}
6555 log_function_data "A_OPTICAL_DRIVE_DATA: $temp_array"
6559 get_partition_data()
6563 local a_partition_working='' dev_item='' temp_array='' dev_working_item=''
6564 local swap_data='' df_string='' main_partition_data='' df_test='' fs_type=''
6565 local mount_data='' dev_bsd_item=''
6566 #local excluded_file_types='--exclude-type=aufs --exclude-type=tmpfs --exclude-type=iso9660'
6567 # df doesn't seem to work in script with variables like at the command line
6568 # added devfs linprocfs sysfs fdescfs which show on debian kfreebsd kernel output
6569 if [[ -z $BSD_TYPE ]];then
6570 swap_data="$( swapon -s 2>/dev/null )"
6571 df_string='df -h -T -P --exclude-type=aufs --exclude-type=devfs --exclude-type=devtmpfs
6572 --exclude-type=fdescfs --exclude-type=iso9660 --exclude-type=linprocfs --exclude-type=procfs
6573 --exclude-type=squashfs --exclude-type=sysfs --exclude-type=tmpfs --exclude-type=unionfs'
6575 swap_data="$( swapctl -l 2>/dev/null )"
6576 # default size is 512, -H only for size in human readable format
6577 # older bsds don't support -T, pain, so we'll use partial output there
6578 df_test=$( df -H -T 2>/dev/null )
6579 if [[ -n $df_test ]];then
6580 df_string='df -H -T'
6585 main_partition_data="$( eval $df_string )"
6586 # set dev disk label/mapper/uuid data globals
6587 get_partition_dev_data 'label'
6588 get_partition_dev_data 'mapper'
6589 get_partition_dev_data 'uuid'
6591 log_function_data 'raw' "main_partition_data:\n$main_partition_data\n\nswap_data:\n$swap_data"
6593 # new kernels/df have rootfs and / repeated, creating two entries for the same partition
6594 # so check for two string endings of / then slice out the rootfs one, I could check for it
6595 # before slicing it out, but doing that would require the same action twice re code execution
6596 if [[ $( grep -cs '[[:space:]]/$' <<< "$main_partition_data" ) -gt 1 ]];then
6597 main_partition_data="$( grep -vs '^rootfs' <<< "$main_partition_data" )"
6599 log_function_data 'raw' "main_partition_data_post_rootfs:\n$main_partition_data\n\nswap_data:\n$swap_data"
6601 # sample line: /dev/sda2 ext3 15G 8.9G 4.9G 65% /home
6602 # $NF = partition name; $(NF - 4) = partition size; $(NF - 3) = used, in gB; $(NF - 1) = percent used
6603 ## note: by subtracting from the last field number NF, we avoid a subtle issue with LVM df output, where if
6604 ## the first field is too long, it will occupy its own line, this way we are getting only the needed data
6605 A_PARTITION_DATA=( $( echo "$main_partition_data" | gawk -v bsdType=$BSD_TYPE '
6610 # this has to be nulled for every iteration so it does not retain value from last iteration
6612 # skipping these file systems because bsds do not support df --exclude-type=<fstype>
6613 # note that using $1 to handle older bsd df, which do not support -T. This will not be reliable but we will see
6615 # skip if non disk/partition, or if raid primary id, which will not have a / in it
6616 if ( $1 ~ /^(aufs|devfs|devtmpfs|fdescfs|iso9660|linprocfs|procfs|squashfs|sysfs|tmpfs|type|unionfs)$/ ||
6617 $1 ~ /^([^\/]+)$/ ) {
6618 # note use next, not getline or it does not work right
6622 # this is required because below we are subtracting from NF, so it has to be > 5
6623 # the real issue is long file system names that force the wrap of df output: //fileserver/main
6624 # but we still need to handle more dynamically long space containing file names, but later.
6625 # Using df -P should fix this, ie, no wrapping of line lines, but leaving this for now
6626 ( NF < 6 ) && ( $0 !~ /[0-9]+%/ ) {
6627 # set the dev location here for cases of wrapped output
6629 devBase=gensub( /^(\/dev\/)(.+)$/, "\\2", 1, $1 )
6634 # next set devBase if it didn not get set above here
6635 ( devBase == "" ) && ( $1 ~ /^\/dev\/|:\/|\/\// ) {
6636 devBase=gensub( /^(\/dev\/)(.+)$/, "\\2", 1, $1 )
6638 # this handles zfs type devices/partitions, which do not start with / but contain /
6639 ( bsdType != "" && devBase == "" && $1 ~ /^[^\/]+\/.+/ ) {
6640 devBase=gensub( /^([^\/]+\/)([^\/]+)$/, "non-dev-\\1\\2", 1, $1 )
6642 # this handles yet another fredforfaen special case where a mounted drive
6643 # has the search string in its name
6644 $NF ~ /^\/$|^\/boot$|^\/var$|^\/home$|^\/tmp$|^\/usr$/ {
6645 # note, older df in bsd do not have file system column
6646 if ( NF == "7" && $(NF - 1) ~ /[0-9]+%/ ) {
6647 fileSystem=$(NF - 5)
6652 print $NF "," $(NF - 4) "," $(NF - 3) "," $(NF - 1) ",main," fileSystem "," devBase
6654 # skip all these, including the first, header line. Use the --exclude-type
6655 # to handle new filesystems types we do not want listed here
6656 $NF !~ /^\/$|^\/boot$|^\/var$|^\/home$|^\/tmp$|^\/usr$|^filesystem/ {
6657 # this is to avoid file systems with spaces in their names, that will make
6658 # the test show the wrong data in each of the fields, if no x%, then do not use
6659 # using 3 cases, first default, standard, 2nd, 3rd, handles one and two spaces in name
6660 if ( $(NF - 1) ~ /[0-9]+%/ ) {
6661 # note, older df in bsd do not have file system column
6663 fileSystem=$(NF - 5)
6668 print $NF "," $(NF - 4) "," $(NF - 3) "," $(NF - 1) ",secondary," fileSystem "," devBase
6670 # these two cases construct the space containing name
6671 else if ( $(NF - 2) ~ /[0-9]+%/ ) {
6672 # note, older df in bsd do not have file system column
6673 if ( NF == "8" && $(NF - 6) !~ /^[0-9]+/ ) {
6674 fileSystem=$(NF - 6)
6679 print $(NF - 1) " " $NF "," $(NF - 5) "," $(NF - 4) "," $(NF - 2) ",secondary," fileSystem "," devBase
6681 else if ( $(NF - 3) ~ /[0-9]+%/ ) {
6682 # note, older df in bsd do not have file system column
6683 if ( NF == "9" && $(NF - 7) !~ /^[0-9]+/ ) {
6684 fileSystem=$(NF - 7)
6689 print $(NF - 2) " " $(NF - 1) " " $NF "," $(NF - 6) "," $(NF - 5) "," $(NF - 3) ",secondary," fileSystem "," devBase
6693 # now add the swap partition data, don't want to show swap files, just partitions,
6694 # though this can include /dev/ramzswap0. Note: you can also use /proc/swaps for this
6695 # data, it's the same exact output as swapon -s
6696 $( echo "$swap_data" | gawk -v bsdType=$BSD_TYPE '
6703 if ( bsdType == "" ) {
6711 size = sprintf( "%.2f", sizeHolder*1024/1000**3 )
6712 devBase = gensub( /^(\/dev\/)(.+)$/, "\\2", 1, $1 )
6713 used = sprintf( "%.2f", usedHolder*1024/1000**3 )
6714 percentUsed = sprintf( "%.0f", ( usedHolder/sizeHolder )*100 )
6715 print "swap-" swapCounter "," size "GB," used "GB," percentUsed "%,main," "swap," devBase
6716 swapCounter = ++swapCounter
6720 temp_array=${A_PARTITION_DATA[@]}
6722 log_function_data "1: A_PARTITION_DATA:\n$temp_array"
6724 # we'll use this for older systems where no filesystem type is shown in df
6725 if [[ $BSD_TYPE == 'bsd' ]];then
6726 mount_data="$( mount )"
6728 # now we'll handle some fringe cases where irregular df -hT output shows /dev/disk/.. instead of
6729 # /dev/h|sdxy type data for column 1, . A_PARTITION_DATA[6]
6730 # Here we just search for the uuid/label and then grab the end of the line to get the right dev item.
6731 for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
6734 a_partition_working=( ${A_PARTITION_DATA[i]} )
6737 dev_item=${a_partition_working[6]} # reset each loop
6738 fs_type=${a_partition_working[5]}
6739 # older bsds have df minus -T so can't get fs type easily, try using mount instead
6740 if [[ $BSD_TYPE == 'bsd' && -z $fs_type && -n $dev_item ]];then
6741 dev_bsd_item=$( sed -e 's/non-dev-//' -e 's|/|\\/|g' <<< "$dev_item" )
6742 fs_type=$( gawk -F '(' '
6744 # slice out everything after / plus the first comma
6745 sub( /,.*/, "", $2 )
6748 }' <<< "$mount_data" )
6750 # note: for swap this will already be set
6751 if [[ -n $( grep -E '(by-uuid|by-label)' <<< $dev_item ) ]];then
6752 dev_working_item=$( basename $dev_item )
6753 if [[ -n $DEV_DISK_UUID ]];then
6754 dev_item=$( echo "$DEV_DISK_UUID" | gawk '
6755 $0 ~ /[ /t]'$dev_working_item'[ /t]/ {
6756 item=gensub( /..\/..\/(.+)/, "\\1", 1, $NF )
6761 # if we didn't find anything for uuid try label
6762 if [[ -z $dev_item && -n $DEV_DISK_LABEL ]];then
6763 dev_item=$( echo "$DEV_DISK_LABEL" | gawk '
6764 $0 ~ /[ /t]'$dev_working_item'[ /t]/ {
6765 item=gensub( /..\/..\/(.+)/, "\\1", 1, $NF )
6770 elif [[ -n $( grep 'mapper/' <<< $dev_item ) ]];then
6771 # get the mapper actual dev item
6772 dev_item=$( get_dev_processed_item "$dev_item" )
6775 if [[ -n $dev_item ]];then
6776 # assemble everything we could get for dev/h/dx, label, and uuid
6778 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
6782 temp_array=${A_PARTITION_DATA[@]}
6784 log_function_data "2: A_PARTITION_DATA:\n$temp_array"
6785 if [[ $B_SHOW_LABELS == 'true' || $B_SHOW_UUIDS == 'true' ]];then
6786 get_partition_data_advanced
6791 # first get the locations of the mount points for label/uuid detection
6792 get_partition_data_advanced()
6795 local a_partition_working='' dev_partition_data=''
6796 local dev_item='' dev_label='' dev_uuid='' temp_array=''
6797 local mount_point=''
6798 # set dev disk label/mapper/uuid data globals
6799 get_partition_dev_data 'label'
6800 get_partition_dev_data 'mapper'
6801 get_partition_dev_data 'uuid'
6803 if [[ $B_MOUNTS_FILE == 'true' ]];then
6804 for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
6807 a_partition_working=( ${A_PARTITION_DATA[i]} )
6810 # note: for swap this will already be set
6811 if [[ -z ${a_partition_working[6]} ]];then
6813 mount_point=$( sed 's|/|\\/|g' <<< ${a_partition_working[0]} )
6814 #echo mount_point $mount_point
6815 dev_partition_data=$( gawk '
6821 # trying to handle space in name
6822 # gsub( /\\040/, " ", $0 )
6823 /[ \t]'$mount_point'[ \t]/ && $1 != "rootfs" {
6824 # initialize the variables
6828 # slice out the /dev
6829 partition=gensub( /^(\/dev\/)(.+)$/, "\\2", 1, $1 )
6830 # label and uuid can occur for root, set partition to null now
6831 if ( partition ~ /by-label/ ) {
6832 label=gensub( /^(\/dev\/disk\/by-label\/)(.+)$/, "\\2", 1, $1 )
6835 if ( partition ~ /by-uuid/ ) {
6836 uuid=gensub( /^(\/dev\/disk\/by-uuid\/)(.+)$/, "\\2", 1, $1 )
6840 # handle /dev/root for / id
6841 if ( partition == "root" ) {
6842 # if this works, great, otherwise, just set this to null values
6843 partTemp="'$( readlink /dev/root 2>/dev/null )'"
6844 if ( partTemp != "" ) {
6845 if ( partTemp ~ /[hsv]d[a-z][0-9]{1,2}/ ) {
6846 partition=gensub( /^(\/dev\/)(.+)$/, "\\2", 1, partTemp )
6848 else if ( partTemp ~ /by-uuid/ ) {
6849 uuid=gensub( /^(\/dev\/disk\/by-uuid\/)(.+)$/, "\\2", 1, partTemp )
6850 partition="" # set null to let real location get discovered
6852 else if ( partTemp ~ /by-label/ ) {
6853 label=gensub( /^(\/dev\/disk\/by-label\/)(.+)$/, "\\2", 1, partTemp )
6854 partition="" # set null to let real location get discovered
6863 print partition "," label "," uuid
6867 # assemble everything we could get for dev/h/dx, label, and uuid
6869 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
6872 ## now we're ready to proceed filling in the data
6874 a_partition_working=( ${A_PARTITION_DATA[i]} )
6876 # get the mapper actual dev item first, in case it's mapped
6877 dev_item=$( get_dev_processed_item "${a_partition_working[6]}" )
6878 # make sure not to slice off rest if it's a network mounted file system
6879 if [[ -n $dev_item && -z $( grep -E '(^//|:/)' <<< $dev_item ) ]];then
6880 dev_item=$( basename $dev_item ) ## needed to avoid error in case name still has / in it
6882 dev_label=${a_partition_working[7]}
6883 dev_uuid=${a_partition_working[8]}
6884 # then if dev data/uuid is incomplete, try to get missing piece
6885 # it's more likely we'll get a uuid than a label. But this should get the
6886 # dev item set no matter what, so then we can get the rest of any missing data
6887 # first we'll get the dev_item if it's missing
6888 if [[ -z $dev_item ]];then
6889 if [[ -n $DEV_DISK_UUID && -n $dev_uuid ]];then
6890 dev_item=$( echo "$DEV_DISK_UUID" | gawk '
6891 $0 ~ /[ \t]'$dev_uuid'[ \t]/ {
6892 item=gensub( /..\/..\/(.+)/, "\\1", 1, $NF )
6896 elif [[ -n $DEV_DISK_LABEL && -n $dev_label ]];then
6897 dev_item=$( echo "$DEV_DISK_LABEL" | gawk '
6898 # first we need to change space x20 in by-label back to a real space
6899 #gsub( /x20/, " ", $0 )
6900 # then we can see if the string is there
6901 $0 ~ /[ \t]'$dev_label'[ \t]/ {
6902 item=gensub( /..\/..\/(.+)/, "\\1", 1, $NF )
6909 # this can trigger all kinds of weird errors if it is a non /dev path, like: remote:/machine/name
6910 if [[ -n $dev_item && -z $( grep -E '(^//|:/)' <<< $dev_item ) ]];then
6911 if [[ -n $DEV_DISK_UUID && -z $dev_uuid ]];then
6912 dev_uuid=$( echo "$DEV_DISK_UUID" | gawk '
6918 if [[ -n $DEV_DISK_LABEL && -z $dev_label ]];then
6919 dev_label=$( echo "$DEV_DISK_LABEL" | gawk '
6927 # assemble everything we could get for dev/h/dx, label, and uuid
6929 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
6932 log_function_data 'cat' "$FILE_MOUNTS"
6934 if [[ $BSD_TYPE == 'bsd' ]];then
6935 get_partition_data_advanced_bsd
6938 temp_array=${A_PARTITION_DATA[@]}
6940 log_function_data "3-advanced: A_PARTITION_DATA:\n$temp_array"
6944 get_partition_data_advanced_bsd()
6947 local gpart_data="$( gpart list 2>/dev/null )"
6948 local a_partition_working='' label_uuid='' dev_item=''
6950 if [[ -n $gpart_data ]];then
6951 for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
6954 a_partition_working=( ${A_PARTITION_DATA[i]} )
6956 # no need to use the rest of the name if it's not a straight /dev/item
6957 dev_item=$( basename ${a_partition_working[6]} )
6959 label_uuid=$( gawk -F ':' '
6965 /^[0-9]+\.[[:space:]]*Name.*'$dev_item'/ {
6966 while ( getline && $1 !~ /^[0-9]+\.[[:space:]]*Name/ ) {
6967 if ( $1 ~ /rawuuid/ ) {
6968 gsub(/^[[:space:]]+|[[:space:]]+$/,"",$2)
6971 if ( $1 ~ /label/ ) {
6972 gsub(/^[[:space:]]+|[[:space:]]+$|none|\(null\)/,"",$2)
6978 }' <<< "$gpart_data" )
6980 # assemble everything we could get for dev/h/dx, label, and uuid
6982 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
6989 # args: $1 - uuid/label/id/mapper
6990 get_partition_dev_data()
6994 # only run these tests once per directory to avoid excessive queries to fs
6997 if [[ $B_ID_SET != 'true' ]];then
6998 if [[ -d /dev/disk/by-id ]];then
6999 DEV_DISK_ID="$( ls -l /dev/disk/by-id )"
7005 if [[ $B_LABEL_SET != 'true' ]];then
7006 if [[ -d /dev/disk/by-label ]];then
7007 DEV_DISK_LABEL="$( ls -l /dev/disk/by-label )"
7013 if [[ $B_MAPPER_SET != 'true' ]];then
7014 if [[ -d /dev/mapper ]];then
7015 DEV_DISK_MAPPER="$( ls -l /dev/mapper )"
7021 if [[ $B_UUID_SET != 'true' ]];then
7022 if [[ -d /dev/disk/by-uuid ]];then
7023 DEV_DISK_UUID="$( ls -l /dev/disk/by-uuid )"
7030 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"
7031 # debugging section, uncomment to insert user data
7044 # args: $1 - dev item, check for mapper, then get actual dev item if mapped
7045 # eg: lrwxrwxrwx 1 root root 7 Sep 26 15:10 truecrypt1 -> ../dm-2
7046 get_dev_processed_item()
7050 local dev_item=$1 dev_return=''
7052 if [[ -n $DEV_DISK_MAPPER && -n $( grep -is 'mapper/' <<< $dev_item ) ]];then
7053 dev_return=$( echo "$DEV_DISK_MAPPER" | gawk '
7054 $( NF - 2 ) ~ /^'$( basename $dev_item )'$/ {
7055 item=gensub( /..\/(.+)/, "\\1", 1, $NF )
7059 if [[ -z $dev_return ]];then
7060 dev_return=$dev_item
7068 get_patch_version_string()
7070 local patch_version_number=$( sed 's/^[0]*//' <<< $SCRIPT_PATCH_NUMBER )
7072 if [[ -n $patch_version_number ]];then
7073 patch_version_number="-$patch_version_number"
7074 # for cases where it was for example: 00-bsd cleaned to --bsd trim out one -
7075 if [[ -n $( grep '\--' <<< $patch_version_number ) ]];then
7076 patch_version_number=$( sed 's/--/-/' <<< $patch_version_number )
7079 echo $patch_version_number
7086 local pciconf_data='' temp_array=''
7088 if [[ $B_PCICONF == 'true' ]];then
7089 pciconf_data="$( pciconf -lv 2>/dev/null )"
7090 if [[ -n $pciconf_data ]];then
7091 pciconf_data=$( gawk '
7096 gsub(/'"$BAN_LIST_NORMAL"'/, "", $0)
7097 gsub(/[[:space:]]+=[[:space:]]+/, "=",$0)
7098 gsub(/^[[:space:]]+|'"'"'|\"|,/, "", $0)
7100 # line=gensub(/.*[[:space:]]+(class=[^[:space:]]*|card=[^[:space:]]*)|chip=[^[:space:]]*|rev=[^[:space:]]*|hdr=[^[:space:]]*).*/,"\n\\1","g",$0)
7101 line=gensub(/(.*@.*)/,"\n\\1",$0)
7103 }' <<< "$pciconf_data" )
7104 # create empty last line with this spacing trick
7105 pciconf_data="$pciconf_data
7108 # echo "$pciconf_data"
7109 # now insert into arrays
7111 A_PCICONF_DATA=( $( gawk '
7132 driver=gensub(/^([^@]+)@.*/, "\\1", itemData )
7133 pciId=gensub(/^.*@pci([0-9\.:]+).*/, "\\1", itemData )
7134 sub(/:$/, "", pciId)
7136 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 )
7137 if ( $2 == "class=020000" ) {
7140 else if ( $2 == "class=030000" ) {
7143 else if ( $2 == "class=040300" ) {
7147 while ( getline && $1 !~ /^$/ ) {
7148 if ( $1 ~ /^vendor/ ) {
7149 sub(/^vendor=/, "", $1 )
7152 else if ( $1 ~ /^device/ ) {
7153 sub(/^device=/, "", $1 )
7156 else if ( $1 ~ /^class=/ && class == "" ) {
7157 sub(/^class=/, "", $1)
7161 if ( device == "" ) {
7165 fullLine=class "," device "," vendor "," driver "," pciId "," chipId
7168 }' <<< "$pciconf_data" ))
7172 A_PCICONF_DATA='pciconf-not-installed'
7174 B_PCICONF_SET='true'
7175 temp_array=${A_PCICONF_DATA[@]}
7176 log_function_data "$temp_array"
7177 log_function_data "$pciconf_data"
7181 # packs standard card arrays using the pciconf stuff
7182 # args: $1 - audio/network/display - matches first item in A_PCICONF_DATA arrays
7183 get_pciconf_card_data()
7186 local a_temp='' array_string='' j=0 device_string=''
7187 local ip_tool_command=$( type -p ifconfig )
7188 local mac='' state='' speed='' duplex='' network_string=''
7190 for (( i=0;i<${#A_PCICONF_DATA[@]};i++ ))
7193 a_temp=( ${A_PCICONF_DATA[i]} )
7196 if [[ ${a_temp[0]} == $1 ]];then
7197 # don't print the vendor if it's already in the device name
7198 if [[ -z $( grep -i "${a_temp[2]}" <<< "${a_temp[1]}" ) ]];then
7199 device_string="${a_temp[2]} ${a_temp[1]}"
7201 device_string=${a_temp[1]}
7205 array_string="$device_string,${a_temp[3]},,,${a_temp[4]},,${a_temp[5]}"
7206 A_AUDIO_DATA[j]=$array_string
7209 array_string="$device_string,${a_temp[4]},${a_temp[5]}"
7210 A_GRAPHICS_CARD_DATA[j]=$array_string
7213 if [[ -n $ip_tool_command && -n ${a_temp[3]} ]];then
7214 network_string=$( $ip_tool_command ${a_temp[3]} | gawk '
7222 /^[[:space:]]*ether/ {
7225 /^[[:space:]]*media/ {
7226 if ( $0 ~ /<.*>/ ) {
7227 duplex=gensub(/.*<([^>]+)>.*/,"\\1",$0)
7229 if ( $0 ~ /\(.*\)/ ) {
7230 speed=gensub(/.*\(([^<[:space:]]+).*\).*/,"\\1",$0)
7233 /^[[:space:]]*status/ {
7234 sub(/.*status[:]?[[:space:]]*/,"", $0)
7238 print state "~" speed "~" mac "~" duplex
7241 if [[ -n $network_string ]];then
7242 mac=$( cut -d '~' -f 3 <<< $network_string )
7243 state=$( cut -d '~' -f 1 <<< $network_string )
7244 speed=$( cut -d '~' -f 2 <<< $network_string )
7245 duplex=$( cut -d '~' -f 4 <<< $network_string )
7247 array_string="$device_string,${a_temp[3]},,,${a_temp[4]},${a_temp[3]},$state,$speed,$duplex,$mac,${a_temp[5]}"
7248 A_NETWORK_DATA[j]=$array_string
7258 # args: $1 - type cpu/mem
7262 local array_length='' reorder_temp='' i=0 head_tail='' sort_type='' ps_data=''
7264 # bummer, have to make it more complex here because of reverse sort
7265 # orders in output, pesky lack of support of +rss in old systems
7268 if [[ $BSD_TYPE != 'bsd' ]];then
7269 sort_type='ps aux --sort -rss'
7272 sort_type='ps aux -m'
7277 if [[ $BSD_TYPE != 'bsd' ]];then
7278 sort_type='ps aux --sort %cpu'
7281 sort_type='ps aux -r'
7287 # throttle potential irc abuse
7288 if [[ $B_RUNNING_IN_SHELL != 'true' && $PS_COUNT -gt 5 ]];then
7289 PS_THROTTLED=$PS_COUNT
7292 # use eval here to avoid glitches with -
7293 ps_data="$( eval $sort_type )"
7296 # note that inxi can use a lot of cpu, and can actually show up here as the script runs
7297 A_PS_DATA=( $( echo "$ps_data" | grep -Ev "($SCRIPT_NAME|%CPU|[[:space:]]ps[[:space:]])" | $head_tail -n $PS_COUNT | gawk '
7315 rss=sprintf( "%.2f", $6/1024 )
7316 # have to get rid of [,],(,) eg: [lockd] which break the printout function compare in bash
7317 gsub(/\[|\]|\(|\)/,"~", $0 )
7326 appStarterName=gensub( /(\/.*\/)(.*)/, "\\2", "1", appStarterPath )
7327 appName=gensub( /(\/.*\/)(.*)/, "\\2", "1", appPath )
7328 print appName "," appPath "," appStarterName "," appStarterPath "," cpu "," mem "," pid "," rss "," user
7331 # make the array ordered highest to lowest so output looks the way we expect it to
7332 # this isn't necessary for -rss, and we can't make %cpu ordered the other way, so
7333 # need to reverse it here. -rss is used because on older systems +rss is not supported
7334 if [[ $1 == 'cpu' && $BSD_TYPE != 'bsd' ]];then
7335 array_length=${#A_PS_DATA[@]};
7336 while (( $i < $array_length/2 ))
7338 reorder_temp=${A_PS_DATA[i]}f
7339 A_PS_DATA[i]=${A_PS_DATA[$array_length-$i-1]}
7340 A_PS_DATA[$array_length-$i-1]=$reorder_temp
7347 # echo ${A_PS_DATA[@]}
7351 # mdstat syntax information: http://www-01.ibm.com/support/docview.wss?uid=isg3T1011259
7352 # note that this does NOT use either Disk or Partition information for now, ie, there
7353 # is no connection between the data types, but the output should still be consistent
7360 if [[ $B_MDSTAT_FILE == 'true' ]];then
7361 mdstat="$( cat $FILE_MDSTAT 2>/dev/null )"
7364 if [[ -n $mdstat ]];then
7365 # need to make sure there's always a newline in front of each record type, and
7366 # also correct possible weird formats for the output from older kernels etc.
7367 mdstat="$( sed -e 's/^md/\nmd/' -e 's/^unused[[:space:]]/\nunused /' \
7368 -e 's/read_ahead/\nread_ahead/' -e 's/^resync=/\nresync=/' -e 's/^Event/\nEvent/' \
7369 -e 's/^[[:space:]]*$//' -e 's/[[:space:]]read_ahead/\nread_ahead/' <<< "$mdstat" )"
7370 # some fringe cases do not end as expected, so need to add newlines plus EOF to make sure while loop doesn't spin
7371 mdstat=$( echo -e "$mdstat\n\nEOF" )
7382 KernelRaidSupport = gensub(/personalities[[:space:]]*:[[:space:]]*(.*)/, "\\1", 1, $0)
7383 # clean off the brackets
7384 gsub(/[\[\]]/,"",KernelRaidSupport)
7385 print "KernelRaidSupport," KernelRaidSupport
7388 ReadAhead=gensub(/read_ahead (.*)/, "\\1", 1 )
7389 print "ReadAhead," ReadAhead
7392 print "raidEvent," $NF
7394 # print logic will search for this value and use it to print out the unused devices data
7396 unusedDevices = gensub(/^unused devices:[[:space:]][<]?([^>]*)[>]?.*/, "\\1", 1, $0)
7397 print "UnusedDevices," unusedDevices
7401 # reset for each record loop through
7411 recoveryProgressBar = ""
7412 recoveryPercent = ""
7414 sectorsRecovered = ""
7419 while ( !/^[[:space:]]*$/ ) {
7421 gsub(/[[:space:]]+/, " ", $0 )
7423 device = gensub(/(md.*)[[:space:]]?:/, "\\1", "1", $1 )
7425 if ( $0 ~ /mirror|raid[0-9]+/ ) {
7426 raidLevel = gensub(/(.*)raid([0-9]+)(.*)/, "\\2", "g", $0 )
7428 if ( $0 ~ /(active \(auto-read-only\)|active|inactive)/ ) {
7429 deviceState = gensub(/(.*) (active \(auto-read-only\)|active|inactive) (.*)/, "\\2", "1", $0 )
7431 # gawk will not return all the components using gensub, only last one
7433 for ( i=3; i<=NF; i++ ) {
7434 if ( $i ~ /[hs]d[a-z][0-9]*(\[[0-9]+\])?(\([SF]\))?/ ) {
7435 components = components separator $i
7439 if ( $0 ~ /blocks/ ) {
7440 blocks = gensub(/(.*[[:space:]]+)?([0-9]+)[[:space:]]blocks.*/, "\\2", "1", $0)
7442 if ( $0 ~ /super[[:space:]][0-9\.]+/ ) {
7443 superBlock = gensub(/.*[[:space:]]super[[:space:]]([0-9\.]+)[[:space:]].*/, "\\1", "1", $0)
7445 if ( $0 ~ /algorithm[[:space:]][0-9\.]+/ ) {
7446 algorithm = gensub(/.*[[:space:]]algorithm[[:space:]]([0-9\.]+)[[:space:]].*/, "\\1", "1", $0)
7448 if ( $0 ~ /\[[0-9]+\/[0-9]+\]/ ) {
7449 deviceReport = gensub(/.*[[:space:]]\[([0-9]+\/[0-9]+)\][[:space:]].*/, "\\1", "1", $0)
7450 uData = gensub(/.*[[:space:]]\[([U_]+)\]/, "\\1", "1", $0)
7452 # need to avoid this: bitmap: 0/10 pages [0KB], 16384KB chunk
7453 # while currently all the normal chunks are marked with k, not kb, this can change in the future
7454 if ( $0 ~ /[0-9]+[k] chunk/ && $0 !~ /bitmap/ ) {
7455 chunkSize = gensub(/(.*) ([0-9]+[k]) chunk.*/, "\\2", "1", $0)
7457 if ( $0 ~ /^resync=/ ) {
7459 print "resyncStatus," $0
7461 if ( $0 ~ /\[[=]*>[\.]*\].*(resync|recovery)/ ) {
7462 recoveryProgressBar = gensub(/.*(\[[=]*>[\.]*\]).*/, "\\1",1,$0)
7464 if ( $0 ~ / (resync|recovery)[[:space:]]*=/ ) {
7465 recoveryPercent = gensub(/.* (resync|recovery)[[:space:]]*=[[:space:]]*([0-9\.]+%).*/, "\\1~\\2", 1 )
7466 if ( $0 ~ /[[:space:]]\([0-9]+\/[0-9]+\)/ ) {
7467 sectorsRecovered = gensub(/.* \(([0-9]+\/[0-9]+)\).*/, "\\1", 1, $0 )
7469 if ( $0 ~ /finish[[:space:]]*=/ ) {
7470 finishTime = gensub(/.* finish[[:space:]]*=[[:space:]]*([[0-9\.]+)([a-z]+) .*/, "\\1 \\2", 1, $0 )
7472 if ( $0 ~ /speed[[:space:]]*=/ ) {
7473 recoverSpeed = gensub(/.* speed[[:space:]]*=[[:space:]]*([[0-9\.]+)([a-z]+\/[a-z]+)/, "\\1 \\2", 1, $0 )
7476 if ( $0 ~ /bitmap/ ) {
7477 bitmapValues = gensub(/(.*[[:space:]])?bitmap:(.*)/, "\\2", 1, $0 )
7482 raidString = device "," deviceState "," raidLevel "," components "," deviceReport "," uData
7483 raidString = raidString "," blocks "," superBlock "," algorithm "," chunkSize "," bitmapValues
7484 raidString = raidString "," recoveryProgressBar "," recoveryPercent "," sectorsRecovered "," finishTime "," recoverSpeed
7491 if [[ $BSD_TYPE == 'bsd' ]];then
7496 temp_array=${A_RAID_DATA[@]}
7497 log_function_data "A_RAID_DATA: $temp_array"
7498 # echo -e "A_RAID_DATA:\n${temp_array}"
7506 local zpool_path=$( type -p zpool 2>/dev/null )
7509 if [[ -n $zpool_path ]];then
7511 # bsd sed does not support inserting a true \n so use this trick
7512 zpool_data="$( $zpool_path list -v | sed $SED_RX 's/^([^[:space:]])/\
7514 # echo "$zpool_data"
7524 chunkRaidAllocated=""
7527 sub(/.*ALLOC.*/,"", $0)
7537 chunkRaidAllocated=$3
7539 # go to the next line now, this will probably need fixing later with weird data sets
7545 while ( getline && $1 !~ /^$/ ) {
7547 components = components separator $1
7552 raidString = device "," deviceState "," raidLevel "," components "," reportSize "," uData
7553 raidString = raidString "," blocksAvailable "," superBlock "," algorithm "," chunkRaidAllocated
7554 # none of these are used currently
7555 raidString = raidString "," bitmapValues "," recoveryProgressBar "," recoveryPercent
7556 raidString = raidString "," sectorsRecovered "," finishTime "," recoverSpeed
7557 gsub(/~/,"",raidString)
7559 }' <<< "$zpool_data" ) )
7561 get_raid_component_data_bsd
7566 # note, we've already tested for zpool so no further tests required
7567 get_raid_component_data_bsd()
7570 local a_raid_data='' array_string='' component='' component_string=''
7571 local zpool_status='' device='' separator='' component_status=''
7573 for (( i=0; i<${#A_RAID_DATA[@]}; i++))
7576 a_raid_data=( ${A_RAID_DATA[i]} )
7582 device=${a_raid_data[0]}
7583 zpool_status="$( zpool status $device )"
7584 # we will remove ONLINE for status and only use OFFLINE/DEGRADED as tests
7585 # for print output display of issues with components
7586 for component in ${a_raid_data[3]}
7588 component_status=$( gawk '
7592 $1 ~ /^'$component'$/ {
7593 sub( /ONLINE/, "", $2 )
7594 print "'$component'" $2
7596 }' <<< "$zpool_status" )
7597 component_string="$component_string$separator$component_status"
7600 array_string="$device,${a_raid_data[1]},${a_raid_data[2]},$component_string,${a_raid_data[4]}"
7601 array_string="$array_string,${a_raid_data[5]},${a_raid_data[6]},${a_raid_data[7]},${a_raid_data[8]}"
7602 array_string="$array_string,${a_raid_data[9]},${a_raid_data[10]},${a_raid_data[11]},${a_raid_data[12]},"
7603 array_string="$array_string${a_raid_data[13]},${a_raid_data[14]},${a_raid_data[15]}"
7605 A_RAID_DATA[i]=$array_string
7611 # get_raid_data_bsd;exit
7613 # Repos will be added as we get distro package manager data to create the repo data.
7614 # This method will output the file name also, which is useful to create output that's
7615 # neat and readable. Each line of the total number contains the following sections,
7616 # separated by a : for splitting in the print function
7617 # part one, repo type/string : part two, file name, if present, of info : part 3, repo data
7621 local repo_file='' repo_data_working='' repo_data_working2='' repo_line='' repo_files=''
7623 local apt_file='/etc/apt/sources.list' yum_repo_dir='/etc/yum.repos.d/' yum_conf='/etc/yum.conf'
7624 local pacman_conf='/etc/pacman.conf' pacman_repo_dir='/etc/pacman.d/' pisi_dir='/etc/pisi/'
7625 local zypp_repo_dir='/etc/zypp/repos.d/' freebsd_conf='/etc/portsnap.conf'
7627 # apt - debian, buntus, also sometimes some yum/rpm repos may create apt repos here as well
7628 if [[ -f $apt_file || -d $apt_file.d ]];then
7629 REPO_DATA="$( grep -Esv '(^[[:space:]]*$|^[[:space:]]*#)' $apt_file $apt_file.d/*.list | sed $SED_RX 's/^(.*)/apt sources:\1/' )"
7631 # yum - fedora, redhat, centos, etc. Note that rpmforge also may create apt sources
7632 # in /etc/apt/sources.list.d/. Therefore rather than trying to assume what package manager is
7633 # actually running, inxi will merely note the existence of each repo type for apt/yum.
7634 # Also, in rpm, you can install apt-rpm for the apt-get command, so it's not good to check for
7635 # only the commands in terms of selecting which repos to show.
7636 if [[ -d $yum_repo_dir || -f $yum_conf || -d $zypp_repo_dir ]];then
7637 if [[ -d $yum_repo_dir || -f $yum_conf ]];then
7638 # older redhats put their yum data in /etc/yum.conf
7639 repo_files=$( ls $yum_repo_dir*.repo $yum_conf 2>/dev/null )
7641 elif [[ -d $zypp_repo_dir ]];then
7642 repo_files=$( ls $zypp_repo_dir*.repo 2>/dev/null )
7645 if [[ -n $repo_files ]];then
7646 for repo_file in $repo_files
7648 repo_data_working="$( gawk -v repoFile=$repo_file '
7649 # construct the string for the print function to work with, file name: data
7650 function print_line( fileName, repoId, repoUrl ){
7651 print "'$repo_name' sources:" fileName ":" repoId repoUrl
7660 # this is a hack, assuming that each item has these fields listed, we collect the 3
7661 # items one by one, then when the url/enabled fields are set, we print it out and
7662 # reset the data. Not elegant but it works. Note that if enabled was not present
7663 # we assume it is enabled then, and print the line, reset the variables. This will
7664 # miss the last item, so it is printed if found in END
7666 if ( urlData != "" && repoTitle != "" ){
7667 print_line( repoFile, repoTitle, urlData )
7672 gsub( /\[|\]/, "", $1 ) # strip out the brackets
7673 repoTitle = $1 " ~ "
7675 /^(mirrorlist|baseurl)/ {
7676 sub( /(mirrorlist|baseurl)[[:space:]]*=[[:space:]]*/, "", $1 ) # strip out the field starter
7679 # note: enabled = 1. enabled = 0 means disabled
7680 /^enabled[[:space:]]*=/ {
7683 # print out the line if all 3 values are found, otherwise if a new
7684 # repoTitle is hit above, it will print out the line there instead
7686 if ( urlData != "" && enabledStatus != "" && repoTitle != "" ){
7687 if ( enabledStatus !~ /enabled[[:space:]]*=[[:space:]]*0/ ){
7688 print_line( repoFile, repoTitle, urlData )
7696 # print the last one if there is data for it
7697 if ( urlData != "" && repoTitle != "" ){
7698 print_line( repoFile, repoTitle, urlData )
7703 # then load the global for each file as it gets filled
7704 if [[ -n $repo_data_working ]];then
7705 if [[ -z $REPO_DATA ]];then
7706 REPO_DATA="$repo_data_working"
7708 REPO_DATA="$REPO_DATA
7711 repo_data_working=''
7715 # pacman - archlinux, going to assume that pisi and arch/pacman, etc don't have the above issue with apt/yum
7716 elif [[ -f $pacman_conf ]];then
7717 # get list of mirror include files, trim white space off ends
7718 repo_data_working="$( gawk '
7723 /^[[:space:]]*Include/ {
7724 sub(/^[[:space:]]+|[[:space:]]+$/,"",$2)
7728 # sort into unique paths only, to be used to search for server = data
7729 repo_data_working=$( sort -bu <<< "$repo_data_working" | uniq )
7730 repo_data_working="$repo_data_working $pacman_conf"
7731 for repo_file in $repo_data_working
7733 if [[ -f $repo_file ]];then
7734 # inserting a new line after each found / processed match
7735 repo_data_working2="$repo_data_working2$( gawk -v repoFile=$repo_file '
7740 /^[[:space:]]*Server/ {
7741 sub(/^[[:space:]]+|[[:space:]]+$/,"",$2)
7742 print "pacman repo servers:" repoFile ":" $2 "\\n"
7746 echo "Error: file listed in $pacman_conf does not exist - $repo_file"
7749 # execute line breaks
7750 REPO_DATA="$( echo -e $repo_data_working2 )"
7752 elif [[ -d $pisi_dir && -n $( type -p pisi ) ]];then
7753 REPO_DATA="$( pisi list-repo )"
7754 # now we need to create the structure: repo info: repo path
7755 # we do that by looping through the lines of the output and then
7756 # putting it back into the <data>:<url> format print repos expects to see
7757 # note this structure in the data, so store first line and make start of line
7758 # then when it's an http line, add it, and create the full line collection.
7759 # Pardus-2009.1 [Aktiv]
7760 # http://packages.pardus.org.tr/pardus-2009.1/pisi-index.xml.bz2
7762 # http://packages.pardus.org.tr/contrib-2009/pisi-index.xml.bz2
7763 while read repo_line
7767 # need to dump leading/trailing spaces and clear out color codes for irc output
7768 sub(/^[[:space:]]+|[[:space:]]+$/,"",$0)
7769 # gsub(/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]/,"",$0) # leaving this pattern in case need it
7770 gsub(/
\e\[([0-9];)?[0-9]+m/,"",$0)
7773 if [[ -n $( grep '://' <<< $repo_line ) ]];then
7774 repo_data_working="$repo_data_working:$repo_line\n"
7776 repo_data_working="${repo_data_working}pisi repo:$repo_line"
7778 done <<< "$REPO_DATA"
7779 # echo and execute the line breaks inserted
7780 REPO_DATA="$( echo -e $repo_data_working )"
7781 # Mandriva/Mageia using: urpmq
7782 elif [[ -n $( type -p urpmq ) ]];then
7783 REPO_DATA="$( urpmq --list-media active --list-url )"
7784 # now we need to create the structure: repo info: repo path
7785 # we do that by looping through the lines of the output and then
7786 # putting it back into the <data>:<url> format print repos expects to see
7787 # note this structure in the data, so store first line and make start of line
7788 # then when it's an http line, add it, and create the full line collection.
7789 # Contrib ftp://ftp.uwsg.indiana.edu/linux/mandrake/official/2011/x86_64/media/contrib/release
7790 # Contrib Updates ftp://ftp.uwsg.indiana.edu/linux/mandrake/official/2011/x86_64/media/contrib/updates
7791 # Non-free ftp://ftp.uwsg.indiana.edu/linux/mandrake/official/2011/x86_64/media/non-free/release
7792 # Non-free Updates ftp://ftp.uwsg.indiana.edu/linux/mandrake/official/2011/x86_64/media/non-free/updates
7793 # Nonfree Updates (Local19) /mnt/data/mirrors/mageia/distrib/cauldron/x86_64/media/nonfree/updates
7794 while read repo_line
7798 # need to dump leading/trailing spaces and clear out color codes for irc output
7799 sub(/^[[:space:]]+|[[:space:]]+$/,"",$0)
7800 # gsub(/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]/,"",$0) # leaving this pattern in case need it
7801 gsub(/
\e\[([0-9];)?[0-9]+m/,"",$0)
7804 # urpmq output is the same each line, repo name space repo url, can be:
7805 # rsync://, ftp://, file://, http:// OR repo is locally mounted on FS in some cases
7806 if [[ -n $( grep -E '(://|[[:space:]]/)' <<< $repo_line ) ]];then
7807 # cut out the repo first
7808 repo_data_working2=$( grep -Eo '([^[:space:]]+://|[[:space:]]/).*' <<< $repo_line )
7809 # then get the repo name string by slicing out the url string
7810 repo_name=$( sed "s|[[:space:]]*$repo_data_working2||" <<< $repo_line )
7811 repo_data_working="${repo_data_working}urpmq repo:$repo_name:$repo_data_working2\n"
7813 done <<< "$REPO_DATA"
7814 # echo and execute the line breaks inserted
7815 REPO_DATA="$( echo -e $repo_data_working )"
7816 elif [[ -f $freebsd_conf ]];then
7817 REPO_DATA="$( gawk -F '=' -v repoFile=$freebsd_conf '
7822 print "BSD ports servers:" repoFile ":" $2
7833 local runlevel_path=$( type -p runlevel )
7834 if [[ -n $runlevel_path ]];then
7835 runlvl="$( $runlevel_path | gawk '{ print $2 }' )"
7841 # note: it appears that at least as of 2014-01-13, /etc/inittab is going to be used for
7842 # default runlevel in upstart/sysvinit. systemd default is not always set so check to see
7844 get_runlevel_default()
7847 local default_runlvl=''
7848 local inittab='/etc/inittab'
7849 local systemd_default='/etc/systemd/system/default.target'
7850 local upstart_default='/etc/init/rc-sysinit.conf'
7852 # note: systemd systems do not necessarily have this link created
7853 if [[ -L $systemd_default ]];then
7854 default_runlvl=$( readlink $systemd_default )
7855 if [[ -n $default_runlvl ]];then
7856 default_runlvl=$( basename $default_runlvl )
7858 # http://askubuntu.com/questions/86483/how-can-i-see-or-change-default-run-level
7859 # note that technically default can be changed at boot but for inxi purposes that does
7860 # not matter, we just want to know the system default
7861 elif [[ -e $upstart_default ]];then
7862 # env DEFAULT_RUNLEVEL=2
7863 default_runlvl=$( gawk -F '=' '/^env[[:space:]]+DEFAULT_RUNLEVEL/ {
7865 }' $upstart_default )
7868 # handle weird cases where null but inittab exists
7869 if [[ -z $default_runlvl && -f $inittab ]];then
7870 default_runlvl=$( gawk -F ':' '
7871 /^id.*initdefault/ {
7875 echo $default_runlvl
7887 if [[ -n $Sensors_Data ]];then
7888 # note: non-configured sensors gives error message, which we need to redirect to stdout
7889 # also, -F ':' no space, since some cases have the data starting right after,like - :1287
7891 gawk -F ':' -v userCpuNo="$SENSORS_CPU_NO" '
7894 core0Temp="" # only if all else fails...
7898 indexCountaFanMain=0
7899 indexCountaFanDefault=0
7909 tempFanType="" # set to 1 or 2
7914 # new data arriving: gpu temp in sensors, have to skip that
7915 /^('"$SENSORS_GPU_SEARCH"')-pci/ {
7916 while ( getline && !/^$/ ) {
7917 # do nothing, just skip it
7920 # dumping the extra + signs after testing for them, nobody has negative temps.
7921 # also, note gawk treats ° as a space, so we have to get the C/F data
7922 # there are some guesses here, but with more sensors samples it will get closer.
7923 # note: using arrays starting at 1 for all fan arrays to make it easier overall
7924 # more validation because gensub if fails to get match returns full string, so
7925 # we have to be sure we are working with the actual real string before assiging
7926 # data to real variables and arrays. Extracting C/F degree unit as well to use
7927 # when constructing temp items for array.
7928 # note that because of charset issues, no tempUnit="°" tempWorkingUnit degree sign
7929 # used, but it is required in testing regex to avoid error.
7930 /^(M\/B|MB|SIO|SYS)(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
7931 moboTemp=gensub( /[ \t]+\+([0-9\.]*)(.*)/, "\\1", 1, $2 )
7932 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
7933 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
7934 tempUnit=tempWorkingUnit
7937 /^CPU(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
7938 cpuTemp=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
7939 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
7940 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
7941 tempUnit=tempWorkingUnit
7944 /^(P\/S|Power)(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
7945 psuTemp=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
7946 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
7947 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
7948 tempUnit=tempWorkingUnit
7951 $1 ~ /^temp1$/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
7952 tempWorking=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
7953 if ( temp1 == "" || tempWorking > 0 ) {
7956 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
7957 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
7958 tempUnit=tempWorkingUnit
7961 $1 ~ /^temp2$/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
7962 tempWorking=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
7963 if ( temp2 == "" || tempWorking > 0 ) {
7966 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
7967 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
7968 tempUnit=tempWorkingUnit
7972 # final fallback if all else fails, funtoo user showed sensors putting
7973 # temp on wrapped second line, not handled
7974 /^(core0|core 0)(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
7975 tempWorking=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
7976 if ( core0Temp == "" || tempWorking > 0 ) {
7977 core0Temp=tempWorking
7979 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
7980 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
7981 tempUnit=tempWorkingUnit
7985 # note: can be cpu fan:, cpu fan speed:, etc. Some cases have no space before
7986 # $2 starts (like so :1234 RPM), so skip that space test in regex
7987 /^CPU(.*)[ \t]*([0-9]+)[ \t]RPM/ {
7988 aFanMain[1]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
7990 /^(M\/B|MB|SYS)(.*)[ \t]*([0-9]+)[ \t]RPM/ {
7991 aFanMain[2]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
7993 /(Power|P\/S|POWER)(.*)[ \t]*([0-9]+)[ \t]RPM/ {
7994 aFanMain[3]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
7996 # note that the counters are dynamically set for fan numbers here
7997 # otherwise you could overwrite eg aux fan2 with case fan2 in theory
7998 # note: cpu/mobo/ps are 1/2/3
7999 # NOTE: test: ! i in array does NOT work, this appears to be an awk/gawk bug
8000 /^(AUX(1)? |CASE(1)? |CHASSIS(1)? )(.*)[ \t]*([0-9]+)[ \t]RPM/ {
8001 for ( i = 4; i < 7; i++ ){
8002 if ( i in aFanMain ){
8006 aFanMain[i]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
8011 /^(AUX([2-9]) |CASE([2-9]) |CHASSIS([2-9]) )(.*)[ \t]*([0-9]+)[ \t]RPM/ {
8012 for ( i = 5; i < 30; i++ ){
8013 if ( i in aFanMain ) {
8018 aFanMain[i]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
8023 # in rare cases syntax is like: fan1: xxx RPM
8024 /^(FAN(1)?[ \t:])(.*)[ \t]*([0-9]+)[ \t]RPM/ {
8025 aFanDefault[1]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
8027 /^FAN([2-9]|1[0-9])(.*)[ \t]*([0-9]+)[ \t]RPM/ {
8028 fanWorking=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
8029 sysFanNu=gensub( /fan([0-9]+)/, "\\1", 1, $1 )
8030 if ( sysFanNu ~ /^([0-9]+)$/ ) {
8031 # add to array if array index does not exist OR if number is > existing number
8032 if ( sysFanNu in aFanDefault ) {
8033 if ( fanWorking >= aFanDefault[sysFanNu] ) {
8034 aFanDefault[sysFanNu]=fanWorking
8038 aFanDefault[sysFanNu]=fanWorking
8044 # first we need to handle the case where we have to determine which temp/fan to use for cpu and mobo:
8045 # note, for rare cases of weird cool cpus, user can override in their prefs and force the assignment
8046 if ( temp1 != "" && temp2 != "" ){
8047 if ( userCpuNo != "" && userCpuNo ~ /(1|2)/ ) {
8048 tempFanType=userCpuNo
8051 # first some fringe cases with cooler cpu than mobo: assume which is cpu temp based on fan speed
8052 # but only if other fan speed is 0
8053 if ( temp1 >= temp2 && 1 in aFanDefault && 2 in aFanDefault && aFanDefault[1] == 0 && aFanDefault[2] > 0 ) {
8056 else if ( temp2 >= temp1 && 1 in aFanDefault && 2 in aFanDefault && aFanDefault[2] == 0 && aFanDefault[1] > 0 ) {
8059 # then handle the standard case if these fringe cases are false
8060 else if ( temp1 >= temp2 ) {
8068 # need a case for no temps at all reported, like with old intels
8069 else if ( temp2 == "" && cpuTemp == "" ){
8070 if ( temp1 == "" && moboTemp == "" ){
8073 else if ( temp1 != "" && moboTemp == "" ){
8076 else if ( temp1 != "" && moboTemp != "" ){
8081 # then get the real cpu temp, best guess is hottest is real
8082 if ( cpuTemp != "" ){
8085 else if ( tempFanType != "" ){
8086 if ( tempFanType == 1 ){
8096 # if all else fails, use core0 temp if it is present and cpu is null
8097 if ( cpuTempReal == "" && core0Temp != "" ) {
8098 cpuTempReal=core0Temp
8101 # then the real mobo temp
8102 if ( moboTemp != "" ){
8103 moboTempReal=moboTemp
8105 else if ( tempFanType != "" ){
8106 if ( tempFanType == 1 ) {
8116 # then set the cpu fan speed
8117 if ( aFanMain[1] == "" ) {
8118 # note, you cannot test for aFanDefault[1] or [2] != ""
8119 # because that creates an array item in gawk just by the test itself
8120 if ( tempFanType == 1 && 1 in aFanDefault ) {
8121 aFanMain[1]=aFanDefault[1]
8124 else if ( tempFanType == 2 && 2 in aFanDefault ) {
8125 aFanMain[1]=aFanDefault[2]
8130 # then we need to get the actual numeric max array count for both fan arrays
8131 for (i = 0; i <= 29; i++) {
8132 if ( i in aFanMain && i > indexCountaFanMain ) {
8133 indexCountaFanMain=i
8136 for (i = 0; i <= 14; i++) {
8137 if ( i in aFanDefault && i > indexCountaFanDefault ) {
8138 indexCountaFanDefault=i
8142 # clear out any duplicates. Primary fan real trumps fan working always if same speed
8143 for (i = 1; i <= indexCountaFanMain; i++) {
8144 if ( i in aFanMain && aFanMain[i] != "" && aFanMain[i] != 0 ) {
8145 for (j = 1; j <= indexCountaFanDefault; j++) {
8146 if ( j in aFanDefault && aFanMain[i] == aFanDefault[j] ) {
8153 # now see if you can find the fast little mobo fan, > 5000 rpm and put it as mobo
8154 # note that gawk is returning true for some test cases when aFanDefault[j] < 5000
8155 # which has to be a gawk bug, unless there is something really weird with arrays
8156 # note: 500 > aFanDefault[j] < 1000 is the exact trigger, and if you manually
8157 # assign that value below, the > 5000 test works again, and a print of the value
8158 # shows the proper value, so the corruption might be internal in awk.
8159 # Note: gensub is the culprit I think, assigning type string for range 501-1000 but
8160 # type integer for all others, this triggers true for >
8161 for (j = 1; j <= indexCountaFanDefault; j++) {
8162 if ( j in aFanDefault && int( aFanDefault[j] ) > 5000 && aFanMain[2] == "" ) {
8163 aFanMain[2] = aFanDefault[j]
8165 # then add one if required for output
8166 if ( indexCountaFanMain < 2 ) {
8167 indexCountaFanMain = 2
8172 # then construct the sys_fan string for echo, note that iteration 1
8173 # makes: fanDefaultString separator null, ie, no space or ,
8174 for (j = 1; j <= indexCountaFanDefault; j++) {
8175 fanDefaultString = fanDefaultString separator aFanDefault[j]
8178 separator="" # reset to null for next loop
8179 # then construct the sys_fan string for echo
8180 for (j = 1; j <= indexCountaFanMain; j++) {
8181 fanMainString = fanMainString separator aFanMain[j]
8185 # and then build the temps:
8186 if ( moboTempReal != "" ) {
8187 moboTempReal = moboTempReal tempUnit
8189 if ( cpuTempReal != "" ) {
8190 cpuTempReal = cpuTempReal tempUnit
8193 # if they are ALL null, print error message. psFan is not used in output currently
8194 if ( cpuTempReal == "" && moboTempReal == "" && aFanMain[1] == "" && aFanMain[2] == "" && aFanMain[3] == "" && fanDefaultString == "" ) {
8195 print "No active sensors found. Have you configured your sensors yet?"
8198 # then build array arrays:
8199 print cpuTempReal "," moboTempReal "," psuTemp
8200 # this is for output, a null print line does NOT create a new array index in bash
8201 if ( fanMainString == "" ) {
8205 print fanDefaultString
8207 }' <<< "$Sensors_Data" ) )
8211 temp_array=${A_SENSORS_DATA[@]}
8212 log_function_data "A_SENSORS_DATA: $temp_array"
8213 # echo "A_SENSORS_DATA: ${A_SENSORS_DATA[@]}"
8217 get_sensors_output()
8219 local sensors_path=$( type -p sensors ) sensors_data=''
8221 if [[ -n $sensors_path ]];then
8222 sensors_data="$( $sensors_path 2>/dev/null )"
8223 if [[ -n "$sensors_data" ]];then
8224 # make sure the file ends in newlines then characters, the newlines are lost in the echo unless
8225 # the data ends in some characters
8226 sensors_data="$sensors_data\n\n###"
8229 echo -e "$sensors_data"
8236 local shell_type="$( ps -p $PPID -o comm= 2>/dev/null )"
8237 local shell_version=''
8239 if [[ $B_EXTRA_DATA == 'true' && -n $shell_type ]];then
8242 shell_version=$( get_de_app_version "$shell_type" "^GNU[[:space:]]bash,[[:space:]]version" "4" | \
8243 sed $SED_RX 's/(\(.*|-release|-version)//' )
8245 # csh/dash use dpkg package version data, debian/buntu only
8247 shell_version=$( get_de_app_version "$shell_type" "^tcsh" "2" )
8250 shell_version=$( get_de_app_version "$shell_type" "$shell_type" "3" )
8253 shell_version=$( get_de_app_version "$shell_type" "version" "5" )
8256 shell_version=$( get_de_app_version "$shell_type" "^tcsh" "2" )
8259 shell_version=$( get_de_app_version "$shell_type" "^zsh" "2" )
8263 if [[ -n $shell_version ]];then
8264 shell_type="$shell_type $shell_version"
8274 local shell_parent='' script_parent=''
8276 # removed --no-headers to make bsd safe, adding in -j to make output the same
8277 script_parent=$( ps -j -fp $PPID 2>/dev/null | gawk '/'"$PPID"'/ { print $3 }' )
8278 log_function_data "script parent: $script_parent"
8279 shell_parent=$( ps -j -p $script_parent 2>/dev/null | gawk '/'"$script_parent"'/ { print $NF}' )
8280 # no idea why have to do script_parent action twice in su case, but you do, oh well.
8281 if [[ $shell_parent == 'su' ]];then
8282 script_parent=$( ps -j -fp $script_parent 2>/dev/null | gawk '/'"$script_parent"'/ { print $3 }' )
8283 script_parent=$( ps -j -fp $script_parent 2>/dev/null | gawk '/'"$script_parent"'/ { print $3 }' )
8284 shell_parent=$( ps -j -p $script_parent 2>/dev/null | gawk '/'"$script_parent"'/ { print $NF}' )
8287 log_function_data "shell parent final: $shell_parent"
8291 # this will be used for some bsd data types
8292 # args: $1 - option type
8297 local sysctl_data=''
8299 if [[ $B_SYSCTL ]];then
8300 sysctl_data="$( sysctl -$1 )"
8302 # log_function_data "sysctl_data: $sysctl_data"
8307 get_tty_console_irc()
8311 if [[ -n ${IRC_CLIENT} ]];then
8312 tty_number=$( gawk '
8316 # if multiple irc clients open, can give wrong results
8317 # so make sure to also use the PPID number to get the right tty
8318 /.*'$PPID'.*'${IRC_CLIENT}'/ {
8319 gsub(/[^0-9]/, "", $7)
8322 }' <<< "$Ps_aux_Data" )
8324 log_function_data "tty_number: $tty_number"
8333 local tty_number=$( basename "$( tty 2>/dev/null )" | sed 's/[^0-9]*//g' )
8340 get_unmounted_partition_data()
8343 local a_unmounted_working='' mounted_partitions='' separator='|' unmounted_fs=''
8344 local dev_working='' uuid_working='' label_working='' a_raid_working='' raid_partitions=''
8346 if [[ $B_PARTITIONS_FILE == 'true' ]];then
8347 # set dev disk label/uuid data globals
8348 get_partition_dev_data 'label'
8349 get_partition_dev_data 'uuid'
8350 # load the raid data array here so we can exclude its partitions
8351 if [[ $B_RAID_SET != 'true' ]];then
8354 # sr0 type cd drives are showing up now as unmounted partitions
8355 mounted_partitions="scd[0-9]+|sr[0-9]+|cdrom[0-9]*|cdrw[0-9]*|dvd[0-9]*|dvdrw[0-9]*"
8356 # create list for slicing out the mounted partitions
8357 for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
8360 a_unmounted_working=( ${A_PARTITION_DATA[i]} )
8362 if [[ -n ${a_unmounted_working[6]} ]];then
8363 mounted_partitions="$mounted_partitions$separator${a_unmounted_working[6]}"
8366 # now we need to exclude the mdraid partitions from the unmounted partition output as well
8367 for (( i=0; i < ${#A_RAID_DATA[@]}; i++ ))
8370 a_raid_working=( ${A_RAID_DATA[i]} )
8372 if [[ -n ${a_raid_working[3]} ]];then
8373 raid_partitions=$( sed $SED_RX 's/(\([^\)]*\)|\[[^\]]*\])//g' <<< ${a_raid_working[3]}\
8374 | sed 's/[[:space:]]\+/|/g' )
8375 mounted_partitions="$mounted_partitions$separator$raid_partitions"
8379 A_UNMOUNTED_PARTITION_DATA=( $( grep -Ev '[[:space:]]('$mounted_partitions')$' $FILE_PARTITIONS | gawk '
8383 # note that size 1 means it is a logical extended partition container
8384 # lvm might have dm-1 type syntax
8385 # need to exclude loop type file systems, squashfs for example
8386 /[a-z][0-9]+$|dm-[0-9]+$/ && $3 != 1 && $NF !~ /loop/ {
8387 size = sprintf( "%.2f", $3*1024/1000**3 )
8388 print $4 "," size "G"
8391 for (( i=0; i < ${#A_UNMOUNTED_PARTITION_DATA[@]}; i++ ))
8394 a_unmounted_working=( ${A_UNMOUNTED_PARTITION_DATA[i]} )
8397 label_working=$( grep -E "${a_unmounted_working[0]}$" <<< "$DEV_DISK_LABEL" | gawk '{
8400 uuid_working=$( grep -E "${a_unmounted_working[0]}$" <<< "$DEV_DISK_UUID" | gawk '{
8403 unmounted_fs=$( get_unmounted_partition_filesystem "/dev/${a_unmounted_working[0]}" )
8406 A_UNMOUNTED_PARTITION_DATA[i]=${a_unmounted_working[0]}","${a_unmounted_working[1]}","$label_working","$uuid_working","$unmounted_fs
8410 # echo "${A_PARTITION_DATA[@]}"
8411 # echo "${A_UNMOUNTED_PARTITION_DATA[@]}"
8415 # a few notes, normally file -s requires root, but you can set user rights in /etc/sudoers.
8416 # list of file systems: http://en.wikipedia.org/wiki/List_of_file_systems
8417 # args: $1 - /dev/<disk><part> to be tested for
8418 get_unmounted_partition_filesystem()
8421 local partition_filesystem='' sudo_command=''
8423 if [[ $B_FILE_TESTED != 'true' ]];then
8424 B_FILE_TESTED='true'
8425 FILE_PATH=$( type -p file )
8428 if [[ $B_SUDO_TESTED != 'true' ]];then
8429 B_SUDO_TESTED='true'
8430 SUDO_PATH=$( type -p sudo )
8433 if [[ -n $FILE_PATH && -n $1 ]];then
8434 # only use sudo if not root, -n option requires sudo -V 1.7 or greater. sudo will just error out
8435 # which is the safest course here for now, otherwise that interactive sudo password thing is too annoying
8436 # important: -n makes it non interactive, no prompt for password
8437 if [[ $B_ROOT != 'true' && -n $SUDO_PATH ]];then
8438 sudo_command='sudo -n '
8440 # this will fail if regular user and no sudo present, but that's fine, it will just return null
8441 # note the hack that simply slices out the first line if > 1 items found in string
8442 # also, if grub/lilo is on partition boot sector, no file system data is available
8443 # BSD fix: -Eio -Em 1
8444 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 '.*' )
8445 if [[ -n $partition_filesystem ]];then
8446 echo $partition_filesystem
8452 ## return uptime string
8456 ## note: removing gsub(/ /,"",a); to get get space back in there, goes right before print a
8457 local uptime_value="$( uptime | gawk '{
8458 a = gensub(/^.*up *([^,]*).*$/,"\\1","g",$0)
8461 echo "$uptime_value"
8462 log_function_data "uptime_value: $uptime_value"
8470 local location_site='http://geoip.ubuntu.com/lookup'
8471 local weather_feed='http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query='
8472 local weather_spider='http://wunderground.com/'
8473 local data_grab_error='' wget_error=0
8474 local b_test_loc=false b_test_weather=false b_debug=false
8475 local test_dir="$HOME/bin/scripts/inxi/data/weather/"
8476 local test_location='location2.xml' test_weather='weather-feed.xml'
8477 local location_data='' location='' weather_data='' location_array_value='' a_location=''
8478 local weather_array_value='' site_elevation='' temp_array=''
8480 # first we get the location data, once that is parsed and handled, we move to getting the
8481 # actual weather data, assuming no errors
8482 if [[ -n $ALTERNATE_WEATHER_LOCATION ]];then
8483 # note, this api does not support spaces in names, replace spaces with + sign.
8484 location=$ALTERNATE_WEATHER_LOCATION
8485 # echo $ALTERNATE_WEATHER_LOCATION;exit
8487 if [[ $b_test_loc != 'true' ]];then
8488 location_data=$( wget -q -t 1 -T $WGET_TIMEOUT -O- $location_site || wget_error=$? )
8489 log_function_data "$location_data"
8490 if [[ $wget_error -ne 0 ]];then
8491 data_grab_error="Error: location server up but download error - wget: $wget_error"
8495 if [[ -f $test_dir$test_location ]];then
8496 location_data="$( cat $test_dir$test_location )"
8498 data_grab_error="Error: location xml local file not found."
8501 if [[ -n $data_grab_error ]];then
8503 elif [[ -z $( grep -i '<Response' <<< $location_data ) ]];then
8504 data_grab_error="Error: location downloaded but data contains no xml."
8506 # clean up xml and make easy to process with newlines, note, bsd sed has no support for inserting
8507 # \n dircctly so we have to use this hack
8508 # location_data="$( sed $SED_RX 's|><|>\n<|g' <<< $location_data )"
8509 location_data="$( sed $SED_RX 's|><|>\
8510 <|g' <<< $location_data )"
8511 # echo -e "ld:\n$location_data"
8512 location_array_value=$( gawk '
8513 function clean(data) {
8515 # some lines might be empty, so ignore those
8516 if (data !~ /^<[^>]+>$/ ) {
8517 returnData=gensub(/(.*>)([^<]*)(<.*)/, "\\2", 1, data)
8537 if ( $0 ~ /CountryCode3/ ){
8538 countryCode3=clean($0)
8541 countryCode=clean($0)
8545 countryName = clean($0)
8548 regionCode = clean($0)
8551 regionName = clean($0)
8557 postalCode = clean($0)
8560 latitude = clean($0)
8563 longitude = clean($0)
8566 timeZone = clean($0)
8569 locationString = city ";" regionCode ";" regionName ";" countryName ";" countryCode ";" countryCode3
8570 locationString = locationString ";" latitude "," longitude ";" postalCode ";" timeZone
8571 print locationString
8572 }' <<< "$location_data" )
8574 A_WEATHER_DATA[0]=$location_array_value
8576 a_location=( ${A_WEATHER_DATA[0]} )
8579 # assign location, cascade from most accurate
8580 # latitude,longitude first
8581 if [[ -n ${a_location[6]} ]];then
8582 location="${a_location[6]}"
8584 elif [[ -n ${a_location[0]} && -n ${a_location[1]} ]];then
8585 location="${a_location[0]},${a_location[1]}"
8586 # postal code last, that can be a very large region
8587 elif [[ -n ${a_location[7]} ]];then
8588 location=${a_location[7]}
8591 if [[ $b_debug == 'true' ]];then
8592 echo -e "location array:\n${A_WEATHER_DATA[0]}"
8593 echo "location: $location"
8595 log_function_data "location: $location"
8597 if [[ -z $location && -z $data_grab_error ]];then
8598 data_grab_error="Error: location data downloaded but no location detected."
8601 # now either dump process or go on to get weather data
8602 if [[ -z $data_grab_error ]];then
8603 if [[ $b_test_weather != 'true' ]];then
8604 weather_data="$( wget -q -t 1 -T $WGET_TIMEOUT -O- $weather_feed"$location" || wget_error=$? )"
8605 if [[ $wget_error -ne 0 ]];then
8606 data_grab_error="Error: weather server up but download error - wget: $wget_error"
8608 log_function_data "$weather_data"
8610 if [[ -f $test_dir$test_weather ]];then
8611 weather_data="$( cat $test_dir$test_weather)"
8613 data_grab_error="Error: weather feed xml local file not found."
8616 if [[ -z $data_grab_error && -z $( grep -i '<current_observation' <<< $weather_data ) ]];then
8617 data_grab_error="Error: weather data downloaded but shows no xml start."
8619 if [[ -z $data_grab_error ]];then
8621 weather_data=$( sed 's/^[[:space:]]*//' <<< "$weather_data" )
8622 site_elevation=$( grep -im 1 '<elevation>' <<< "$weather_data" | sed $SED_RX -e 's/<[^>]*>//g' \
8624 # we need to grab the location data from the feed for remote checks
8625 if [[ -n $ALTERNATE_WEATHER_LOCATION && -n $weather_data ]];then
8626 location_data=$( sed -e '/<current_observation>/,/<display_location>/d' -e '/<\/display_location>/,/<\/current_observation>/d' <<< "$weather_data" )
8627 # echo -e "ld1:\n$location_data"
8628 A_WEATHER_DATA[0]=$( gawk '
8629 function clean(data) {
8631 # some lines might be empty, so ignore those
8632 if (data !~ /^<[^>]+>$/ ) {
8633 returnData=gensub(/(.*>)([^<]*)(<.*)/, "\\2", 1, data)
8634 gsub(/^[[:space:]]+|[[:space:]]+$|^NA$|^N\/A$/, "", returnData)
8654 print city ";" state ";;;;" country
8655 }' <<< "$location_data" )
8656 # echo -e "location:\n${A_WEATHER_DATA[0]}"
8659 # clean off everything before/after observation_location
8660 weather_data=$( sed -e '/<current_observation>/,/<observation_location>/d' \
8661 -e '/<icons>/,/<\/current_observation>/d' <<< "$weather_data" -e 's/^[[:space:]]*$//g' -e '/^$/d' )
8663 # echo "$weather_data";exit
8664 weather_array_value=$( gawk -v siteElevation="$site_elevation" '
8665 function clean(data) {
8667 # some lines might be empty, so ignore those
8668 if (data !~ /^<[^>]+>$/ ) {
8669 returnData=gensub(/(.*>)([^<]*)(<.*)/, "\\2", 1, data)
8670 gsub(/^[[:space:]]+|[[:space:]]+$|^NA$|^N\/A$/, "", returnData)
8688 /observation_time>/ {
8689 observationTime=clean($0)
8690 sub(/Last Updated on /, "", observationTime )
8698 /temperature_string/ {
8699 tempString=clean($0)
8701 /relative_humidity/ {
8705 windString=clean($0)
8708 pressureString=clean($0)
8710 /heat_index_string/ {
8711 heatIndexString=clean($0)
8713 /windchill_string/ {
8714 windChillString=clean($0)
8717 weatherString = observationTime ";" localTime ";" weather ";" tempString ";" humidity
8718 weatherString = weatherString ";" windString ";" pressureString ";" dewpointString ";" heatIndexString
8719 weatherString = weatherString ";" windChillString ";" siteElevation
8721 }' <<< "$weather_data" )
8723 if [[ -z $weather_array_value ]];then
8724 data_grab_error="Error: weather info downloaded but no data detected."
8726 A_WEATHER_DATA[1]=$weather_array_value
8729 # now either dump process or go on to get weather data
8730 if [[ -n $data_grab_error ]];then
8731 A_WEATHER_DATA=$data_grab_error
8732 log_function_data "data grab error: $data_grab_error"
8735 if [[ $b_debug == 'true' ]];then
8736 echo "site_elevation: $site_elevation"
8737 echo "${A_WEATHER_DATA[1]}"
8739 temp_array=${A_WEATHER_DATA[@]}
8740 log_function_data "A_WEATHER_DATA: $temp_array"
8744 # ALTERNATE_WEATHER_LOCATION='portland,or'
8745 # get_weather_data;exit
8747 #### -------------------------------------------------------------------
8748 #### special data handling for specific options and conditions
8749 #### -------------------------------------------------------------------
8751 # args: $1 - string to strip color code characters out of
8752 # returns count of string length minus colors
8753 calculate_line_length()
8756 # ansi:
\e[1;34m irc: \x0312
8757 string=$( sed -e "s/\x1b\[[0-9]\{1,2\}\(;[0-9]\{1,2\}\)\{0,2\}m//g" -e "s/\\\x0[0-9]\{1,3\}//g" <<< $string )
8762 ## multiply the core count by the data to be calculated, bmips, cache
8763 # args: $1 - string to handle; $2 - cpu count
8764 calculate_multicore_data()
8767 local string_number=$1 string_data=''
8769 if [[ -n $( grep -Ei '( mb| kb)' <<< $1 ) ]];then
8770 string_data=" $( gawk '{print $2}' <<< $1 )" # add a space for output
8771 string_number=$( gawk '{print $1}' <<< $1 )
8773 # handle weird error cases where it's not a number
8774 if [[ -n $( grep -E '^[0-9\.,]+$' <<< $string_number ) ]];then
8775 string_number=$( echo $string_number $2 | gawk '{
8779 elif [[ $string_number == '' ]];then
8782 # I believe that the above returns 'unknown' by default so no need for extra text
8783 string_number="$string_number "
8785 echo "$string_number$string_data"
8786 log_function_data "string_numberstring_data: $string_number$string_data"
8790 # prints out shortened list of flags, the main ones of interest
8791 # args: $1 - string of cpu flags to process
8796 local cpu_flags_working=$1
8797 local bits=$( uname -m | grep 64 )
8799 # no need to show pae for 64 bit cpus, it's pointless
8800 if [[ -n $bits ]];then
8801 cpu_flags_working=$( sed 's/[[:space:]]*pae//' <<< "$cpu_flags_working" )
8803 # must have a space after last item in list for RS=" "
8804 cpu_flags_working="$cpu_flags_working "
8806 # nx = AMD stack protection extensions
8807 # lm = Intel 64bit extensions
8808 # sse, sse2, pni = sse1,2,3,4,5 gfx extensions
8809 # svm = AMD pacifica virtualization extensions
8810 # vmx = Intel IVT (vanderpool) virtualization extensions
8812 echo "$cpu_flags_working" | gawk '
8816 i = 1 # start at one because of for increment issue
8820 /^(lm|nx|pae|pni|svm|vmx|(sss|ss)e([2-9])?([a-z])?(_[0-9])?)$/ {
8830 count = asort( a_flags )
8831 # note: why does gawk increment before the loop and not after? weird.
8832 for ( i=0; i <= count; i++ ){
8833 if ( flag_string == "" ) {
8834 flag_string = a_flags[i]
8837 flag_string = flag_string " " a_flags[i]
8843 #grep -oE '\<(nx|lm|sse[0-9]?|pni|svm|vmx)\>' | tr '\n' ' '))
8844 if [[ -z $cpu_flags ]];then
8848 log_function_data "cpu_flags: $cpu_flags"
8852 #### -------------------------------------------------------------------
8853 #### print and processing of output data
8854 #### -------------------------------------------------------------------
8856 #### MASTER PRINT FUNCTION - triggers all line item print functions
8857 ## main function to print out, master for all sub print functions.
8861 # note that print_it_out passes local variable values on to its children,
8862 # and in some cases, their children, with Lspci_v_Data
8863 local Lspci_v_Data='' Lspci_n_Data='' # only for verbose
8864 local Sysctl_a_Data='' Dmesg_Boot_Data=''
8866 if [[ -n $BSD_TYPE ]];then
8867 Sysctl_a_Data="$( get_sysctl_data 'a' )"
8868 Dmesg_Boot_Data="$( get_dmesg_boot_data )"
8871 if [[ $B_SHOW_SHORT_OUTPUT == 'true' ]];then
8874 Lspci_v_Data="$( get_lspci_data 'v' )"
8875 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
8876 Lspci_n_Data="$( get_lspci_data 'n' )"
8878 if [[ $B_SHOW_SYSTEM == 'true' ]];then
8881 if [[ $B_SHOW_MACHINE == 'true' ]];then
8884 if [[ $B_SHOW_WEATHER == 'true' ]];then
8887 if [[ $B_SHOW_BASIC_CPU == 'true' || $B_SHOW_CPU == 'true' ]];then
8890 if [[ $B_SHOW_GRAPHICS == 'true' ]];then
8893 if [[ $B_SHOW_AUDIO == 'true' ]];then
8896 if [[ $B_SHOW_NETWORK == 'true' ]];then
8897 print_networking_data
8899 if [[ $B_SHOW_DISK_TOTAL == 'true' || $B_SHOW_BASIC_DISK == 'true' || $B_SHOW_DISK == 'true' ]];then
8900 print_hard_disk_data
8902 if [[ $B_SHOW_PARTITIONS == 'true' ]];then
8903 print_partition_data
8905 if [[ $B_SHOW_RAID == 'true' || $B_SHOW_BASIC_RAID == 'true' ]];then
8908 if [[ $B_SHOW_UNMOUNTED_PARTITIONS == 'true' ]];then
8909 print_unmounted_partition_data
8911 if [[ $B_SHOW_SENSORS == 'true' ]];then
8914 if [[ $B_SHOW_REPOS == 'true' ]];then
8917 if [[ $B_SHOW_PS_CPU_DATA == 'true' || $B_SHOW_PS_MEM_DATA == 'true' ]];then
8920 if [[ $B_SHOW_INFO == 'true' ]];then
8927 #### SHORT OUTPUT PRINT FUNCTION, ie, verbosity 0
8928 # all the get data stuff is loaded here to keep execution time down for single line print commands
8929 # these will also be loaded in each relevant print function for long output
8933 local current_kernel=$( get_kernel_version )
8934 local processes=$(( $( wc -l <<< "$Ps_aux_Data" ) - 1 ))
8935 local short_data='' i='' b_background_black='false'
8936 local memory=$( get_memory_data )
8937 local up_time="$( get_uptime )"
8939 # set A_CPU_CORE_DATA
8941 local cpc_plural='' cpu_count_print='' model_plural=''
8942 local cpu_physical_count=${A_CPU_CORE_DATA[0]}
8943 local cpu_core_count=${A_CPU_CORE_DATA[3]}
8944 local cpu_core_alpha=${A_CPU_CORE_DATA[1]}
8945 local cpu_type=${A_CPU_CORE_DATA[2]}
8947 if [[ $cpu_physical_count -gt 1 ]];then
8950 cpu_count_print="$cpu_physical_count "
8953 local cpu_data_string="${cpu_count_print}${cpu_core_alpha} core"
8954 # local cpu_core_count=${A_CPU_CORE_DATA[0]}
8958 ## note: if hdd_model is declared prior to use, whatever string you want inserted will
8959 ## be inserted first. In this case, it's desirable to print out (x) before each disk found.
8960 local a_hdd_data_count=$(( ${#A_HDD_DATA[@]} - 1 ))
8962 local a_hdd_basic_working=( ${A_HDD_DATA[$a_hdd_data_count]} )
8964 local hdd_capacity=${a_hdd_basic_working[0]}
8965 local hdd_used=${a_hdd_basic_working[1]}
8971 local a_cpu_working=(${A_CPU_DATA[0]})
8973 local cpu_model="${a_cpu_working[0]}"
8974 ## assemble data for output
8975 local cpu_clock="${a_cpu_working[1]}" # old CPU3
8976 # this gets that weird min/max final array item, which almost never contains any data of use
8977 local min_max_clock_nu=$(( ${#A_CPU_DATA[@]} - 1 ))
8978 local min_max_clock=${A_CPU_DATA[$min_max_clock_nu]}
8979 # this handles the case of for example ARM cpus, which will not have data for
8980 # min/max, since they don't have speed. Since that sets a flag, not found, just
8981 # look for that and use the speed from the first array array, same where we got
8983 if [[ "$min_max_clock" == 'N/A' && ${a_cpu_working[1]} != '' ]];then
8984 min_max_clock="${a_cpu_working[1]} MHz"
8986 local patch_version_number=$( get_patch_version_string )
8988 #set_color_scheme 12
8989 if [[ $B_RUNNING_IN_SHELL == 'false' ]];then
8990 for i in $C1 $C2 $CN
8993 "$GREEN"|"$WHITE"|"$YELLOW"|"$CYAN")
8994 b_background_black='true'
8998 if [[ $b_background_black == 'true' ]];then
9001 ## these need to be in quotes, don't know why
9002 if [[ ${!i} == $NORMAL ]];then
9003 declare $i="${!i}15,1"
9005 declare $i="${!i},1"
9008 #C1="${C1},1"; C2="${C2},1"; CN="${CN},1"
9011 short_data="${C1}CPU$cpc_plural${C2}${SEP1}${cpu_data_string} ${cpu_model}$model_plural (${cpu_type}) clocked at ${min_max_clock}${SEP2}${C1}Kernel${C2}${SEP1}${current_kernel}${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}"
9013 if [[ $SHOW_IRC -gt 0 ]];then
9014 short_data="${short_data}${C1}Client${C2}${SEP1}${IRC_CLIENT}${IRC_CLIENT_VERSION}${SEP2}"
9016 short_data="${short_data}${C1}$SCRIPT_NAME${C2}${SEP1}$SCRIPT_VERSION_NUMBER$patch_version_number${SEP2}${CN}"
9017 if [[ $SCHEME -gt 0 ]];then
9018 short_data="${short_data} $NORMAL"
9020 print_screen_output "$short_data"
9024 #### LINE ITEM PRINT FUNCTIONS
9026 # print sound card data
9030 local i='' card_id='' audio_data='' a_audio_data='' port_data='' pci_bus_id='' card_string=''
9031 local a_audio_working='' audio_driver='' alsa_data='' port_plural='' module_version='' chip_id=''
9032 local bus_usb_text='' bus_usb_id='' line_starter='Audio:' alsa='' alsa_version='' print_data=''
9034 # set A_AUDIO_DATA and get alsa data
9035 if [[ $BSD_TYPE == 'bsd' ]];then
9036 if [[ $B_PCICONF_SET == 'false' ]];then
9039 get_pciconf_card_data 'audio'
9045 # alsa driver data now prints out no matter what
9046 if [[ -n $A_ALSA_DATA ]];then
9048 if [[ -n ${A_ALSA_DATA[0]} ]];then
9049 alsa=${A_ALSA_DATA[0]}
9053 if [[ -n ${A_ALSA_DATA[1]} ]];then
9054 alsa_version=${A_ALSA_DATA[1]}
9058 alsa_data="${C1}Sound:${C2} $alsa ${C1}ver$SEP3${C2} $alsa_version"
9061 # note, error handling is done in the get function, so this will never be null, but
9062 # leaving the test just in case it's changed.
9063 if [[ -n ${A_AUDIO_DATA[@]} ]];then
9064 for (( i=0; i< ${#A_AUDIO_DATA[@]}; i++ ))
9067 a_audio_working=( ${A_AUDIO_DATA[i]} )
9082 if [[ ${#A_AUDIO_DATA[@]} -gt 1 ]];then
9083 card_id="-$(( $i + 1 ))"
9085 if [[ $BSD_TYPE != 'bsd' ]];then
9086 if [[ -n ${a_audio_working[3]} && $B_EXTRA_DATA == 'true' ]];then
9087 module_version=$( print_module_version "${a_audio_working[3]}" 'audio' )
9088 elif [[ -n ${a_audio_working[1]} && $B_EXTRA_DATA == 'true' ]];then
9089 module_version=$( print_module_version "${a_audio_working[1]}" 'audio' )
9092 # we're testing for the presence of the 2nd array item here, which is the driver name
9093 if [[ -n ${a_audio_working[1]} ]];then
9094 # note: linux drivers can have numbers, like tg3
9095 if [[ $BSD_TYPE == 'bsd' ]];then
9096 driver=$( sed 's/[0-9]$//' <<< ${a_audio_working[1]} )
9098 driver=${a_audio_working[1]}
9100 audio_driver="${C1}driver$SEP3${C2} ${driver} "
9102 if [[ -n ${a_audio_working[2]} && $B_EXTRA_DATA == 'true' ]];then
9103 if [[ $( wc -w <<< ${a_audio_working[2]} ) -gt 1 ]];then
9106 port_data="${C1}port$port_plural$SEP3${C2} ${a_audio_working[2]} "
9108 if [[ -n ${a_audio_working[4]} && $B_EXTRA_DATA == 'true' ]];then
9109 if [[ ${a_audio_working[1]} != 'USB Audio' ]];then
9110 bus_usb_text='bus-ID'
9111 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
9112 if [[ $BSD_TYPE != 'bsd' ]];then
9113 chip_id=$( get_lspci_chip_id "${a_audio_working[4]}" )
9115 chip_id=${a_audio_working[6]}
9119 bus_usb_text='usb-ID'
9120 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
9121 chip_id=${a_audio_working[5]}
9124 bus_usb_id=${a_audio_working[4]}
9125 pci_bus_id="${C1}$bus_usb_text$SEP3${C2} $bus_usb_id "
9126 if [[ -n $chip_id ]];then
9127 chip_id="${C1}chip-ID$SEP3${C2} $chip_id "
9130 if [[ -n ${a_audio_working[0]} ]];then
9131 card_string="${C1}Card$card_id:${C2} ${a_audio_working[0]} "
9132 audio_data="$audio_driver$port_data$pci_bus_id$chip_id"
9134 # only print alsa on last line if short enough, otherwise print on its own line
9135 if [[ $i -eq 0 ]];then
9136 if [[ -n $alsa_data && $( calculate_line_length "$card_string${audio_data}$alsa_data" ) -lt $COLS_INNER ]];then
9137 audio_data="$audio_data$alsa_data"
9141 if [[ -n $audio_data ]];then
9142 if [[ $( calculate_line_length "$card_string$audio_data" ) -lt $COLS_INNER ]];then
9143 print_data=$( create_print_line "$line_starter" "$card_string$audio_data" )
9144 print_screen_output "$print_data"
9147 # keep the driver on the same line no matter what, looks weird alone on its own line
9148 if [[ $B_EXTRA_DATA != 'true' ]];then
9149 print_data=$( create_print_line "$line_starter" "$card_string$audio_data" )
9150 print_screen_output "$print_data"
9152 print_data=$( create_print_line "$line_starter" "$card_string" )
9153 print_screen_output "$print_data"
9155 print_data=$( create_print_line "$line_starter" "$audio_data" )
9156 print_screen_output "$print_data"
9163 if [[ -n $alsa_data ]];then
9164 alsa_data=$( sed 's/ALSA/Advanced Linux Sound Architecture/' <<< $alsa_data )
9165 alsa_data=$( create_print_line "$line_starter" "$alsa_data" )
9166 print_screen_output "$alsa_data"
9174 local cpu_data='' i='' cpu_clock_speed='' cpu_multi_clock_data=''
9175 local bmip_data='' cpu_cache='' cpu_vendor='' cpu_flags='' flag_feature='flags'
9176 local a_cpu_working='' cpu_model='' cpu_clock='' cpu_null_error=''
9177 local cpc_plural='' cpu_count_print='' model_plural='' cpu_data_string=''
9178 local cpu_physical_count='' cpu_core_count='' cpu_core_alpha='' cpu_type=''
9181 ##print_screen_output "A_CPU_DATA[0]=\"${A_CPU_DATA[0]}\""
9182 # Array A_CPU_DATA always has one extra element: max clockfreq found.
9183 # that's why its count is one more than you'd think from cores/cpus alone
9188 a_cpu_working=(${A_CPU_DATA[0]})
9191 # Strange (and also some expected) behavior encountered. If print_screen_output() uses $1
9192 # as the parameter to output to the screen, then passing "<text1> ${ARR[@]} <text2>"
9193 # will output only <text1> and first element of ARR. That "@" splits in elements and "*" _doesn't_,
9194 # is to be expected. However, that text2 is consecutively truncated is somewhat strange, so take note.
9195 # This has been confirmed by #bash on freenode.
9196 # The above mentioned only emerges when using the debugging markers below
9197 ## print_screen_output "a_cpu_working=\"***${a_cpu_working[@]} $hostName+++++++\"----------"
9198 # unless all these are null, process whatever you have
9199 if [[ -n ${a_cpu_working[0]} || -n ${a_cpu_working[1]} || -n ${a_cpu_working[2]} || -n ${a_cpu_working[3]} ]];then
9200 cpu_model="${a_cpu_working[0]}"
9201 ## assemble data for output
9202 cpu_clock="${a_cpu_working[1]}"
9204 cpu_vendor=${a_cpu_working[5]}
9206 # set A_CPU_CORE_DATA
9208 cpu_physical_count=${A_CPU_CORE_DATA[0]}
9209 cpu_core_count=${A_CPU_CORE_DATA[3]}
9210 cpu_core_alpha=${A_CPU_CORE_DATA[1]}
9211 cpu_type=${A_CPU_CORE_DATA[2]}
9213 if [[ $cpu_physical_count -gt 1 ]];then
9215 cpu_count_print="$cpu_physical_count "
9219 cpu_data_string="${cpu_count_print}${cpu_core_alpha} core"
9220 cpu_data=$( create_print_line "CPU$cpc_plural:" "${C1}${cpu_data_string}${C2} ${a_cpu_working[0]}$model_plural (${cpu_type})" )
9221 if [[ $B_SHOW_CPU == 'true' ]];then
9222 # update for multicore, bogomips x core count.
9223 if [[ $B_EXTRA_DATA == 'true' ]];then
9224 # if [[ $cpu_vendor != 'intel' ]];then
9225 # ARM may use the faked 1 cpucorecount to make this work
9226 # echo $cpu_core_count $cpu_physical_count
9227 if [[ -n ${a_cpu_working[4]} ]];then
9228 bmip_data=$( calculate_multicore_data "${a_cpu_working[4]}" "$(( $cpu_core_count * $cpu_physical_count ))" )
9231 # bmip_data="${a_cpu_working[4]}"
9233 # bogomips are a linux thing, but my guess is over time bsds will use them somewhere anyway
9234 if [[ $BSD_TYPE == 'bsd' && -z $bmip_data ]];then
9237 bmip_data="${C1}bmips$SEP3${C2} $bmip_data "
9240 ## note: this handles how intel reports L2, total instead of per core like AMD does
9241 # note that we need to multiply by number of actual cpus here to get true cache size
9242 if [[ -n ${a_cpu_working[2]} ]];then
9243 if [[ $cpu_vendor != 'intel' ]];then
9244 cpu_cache=$( calculate_multicore_data "${a_cpu_working[2]}" "$(( $cpu_core_count * $cpu_physical_count ))" )
9246 cpu_cache=$( calculate_multicore_data "${a_cpu_working[2]}" "$cpu_physical_count" )
9251 # only print shortened list
9252 if [[ $B_CPU_FLAGS_FULL != 'true' ]];then
9253 # gawk has already sorted this output, no flags returns -
9254 if [[ $B_EXTRA_DATA == 'true' ]];then
9255 cpu_flags=$( process_cpu_flags "${a_cpu_working[3]}" "${a_cpu_working[6]}" )
9256 cpu_flags="($cpu_flags)"
9257 if [[ ${a_cpu_working[6]} == 'true' ]];then
9258 flag_feature='features'
9260 cpu_flags="${C1}$flag_feature$SEP3${C2} $cpu_flags "
9263 # arm cpus do not have flags or cache
9264 if [[ ${a_cpu_working[6]} != 'true' ]];then
9265 cpu_data="$cpu_data${C2} ${C1}cache$SEP3${C2} $cpu_cache${CN}"
9266 cpu_2_data="$cpu_flags$bmip_data${CN}"
9268 cpu_data="$cpu_data${C2} (ARM)$bmip_data${CN}"
9271 # we don't this printing out extra line unless > 1 cpu core
9272 if [[ ${#A_CPU_DATA[@]} -gt 2 && $B_SHOW_CPU == 'true' ]];then
9273 cpu_clock_speed='' # null < verbosity level 5
9275 cpu_data="$cpu_data ${C1}clocked at${C2} ${a_cpu_working[1]} MHz${CN}"
9277 cpu_2_data="$cpu_2_data$cpu_clock_speed"
9279 if [[ $BSD_TYPE == 'bsd' && $B_ROOT != 'true' ]];then
9280 cpu_null_error=' No permissions for sysctl use?'
9282 cpu_data=$( create_print_line "CPU:" "${C2}No CPU data available.$cpu_null_error" )
9284 # echo ln: $( calculate_line_length "$cpu_data $cpu_2_data" )
9285 # echo icols: $COLS_INNER
9286 # echo tc: $TERM_COLUMNS
9287 # echo :$cpu_2_data:
9288 if [[ -n $cpu_2_data && $( calculate_line_length "$cpu_data $cpu_2_data" ) -gt $COLS_INNER ]];then
9289 print_screen_output "$cpu_data"
9290 cpu_data=$( create_print_line " " "$cpu_2_data" )
9291 print_screen_output "$cpu_data"
9293 print_screen_output "$cpu_data $cpu_2_data"
9295 # we don't this printing out extra line unless > 1 cpu core
9296 # note the numbering, the last array item is the min/max/not found for cpu speeds
9297 if [[ ${#A_CPU_DATA[@]} -gt 2 && $B_SHOW_CPU == 'true' ]];then
9298 for (( i=0; i < ${#A_CPU_DATA[@]}-1; i++ ))
9301 a_cpu_working=(${A_CPU_DATA[i]})
9303 # note: the first iteration will create a first space, for color code separation below
9304 cpu_multi_clock_data="$cpu_multi_clock_data ${C1}$(( i + 1 )):${C2} ${a_cpu_working[1]} MHz${CN}"
9305 # someone actually appeared with a 16 core system, so going to stop the cpu core throttle
9306 # if this had some other purpose which we can't remember we'll add it back in
9307 #if [[ $i -gt 10 ]];then
9311 if [[ -n $cpu_multi_clock_data ]];then
9312 cpu_multi_clock_data=$( create_print_line " " "${C1}Clock Speeds:${C2}$cpu_multi_clock_data" )
9313 print_screen_output "$cpu_multi_clock_data"
9316 if [[ $B_CPU_FLAGS_FULL == 'true' ]];then
9317 print_cpu_flags_full "${a_cpu_working[3]}" "${a_cpu_working[6]}"
9322 # takes list of all flags, split them and prints x per line
9323 # args: $1 - cpu flag string; $2 - arm true/false
9324 print_cpu_flags_full()
9327 # note: sort only sorts lines, not words in a string, so convert to lines
9328 local cpu_flags_full="$( echo $1 | tr " " "\n" | sort )"
9329 local a_cpu_flags='' line_starter='' temp_string=''
9330 local i=0 counter=0 starter_length=15 flag='' flag_data=''
9331 local line_length='' flag_feature='Flags' spacer='' flag_string=''
9333 if [[ $2 == 'true' ]];then
9334 flag_feature='Features'
9336 # build the flag line array
9337 for flag in $cpu_flags_full
9339 temp_string="$flag_string$spacer$flag"
9341 # handle inner line starter
9342 if [[ $counter -eq 0 ]];then
9343 line_length=$(( $COLS_INNER - $starter_length ))
9345 line_length=$COLS_INNER
9347 if [[ ${#temp_string} -gt $line_length ]];then
9348 a_cpu_flags[$counter]=$temp_string
9353 flag_string=$temp_string
9357 if [[ -n $flag_string ]];then
9358 a_cpu_flags[$counter]=$flag_string
9361 for (( i=0; i < ${#a_cpu_flags[@]};i++ ))
9363 if [[ $i -eq 0 ]];then
9364 line_starter="${C1}CPU $flag_feature$SEP3${C2} "
9368 flag_data=$( create_print_line " " "$line_starter${a_cpu_flags[$i]}" )
9369 print_screen_output "$flag_data"
9374 print_graphics_data()
9377 local graphics_data='' card_id='' i='' root_alert='' root_x_string='' a_graphics_working=''
9378 local b_is_mesa='false' display_full_string='' card_bus_id='' card_data=''
9379 local res_tty='Resolution' xorg_data='' display_vendor_string='' chip_id=''
9380 local spacer='' driver='' driver_string='' driver_plural='' direct_render_string=''
9381 local separator_loaded='' separator_unloaded='' separator_failed=''
9382 local loaded='' unloaded='' failed='' display_server_string=''
9383 local line_starter='Graphics:'
9384 local screen_resolution="$( get_graphics_res_data )"
9386 # set A_DISPLAY_SERVER_DATA
9387 get_graphics_display_server_data
9388 local display_vendor=${A_DISPLAY_SERVER_DATA[0]}
9389 local display_version=${A_DISPLAY_SERVER_DATA[1]}
9391 get_graphics_glx_data
9392 local glx_renderer="${A_GLX_DATA[0]}"
9393 local glx_version="${A_GLX_DATA[1]}"
9394 # this can contain a long No case debugging message, so it's being sliced off
9395 # note: using grep -ioE '(No|Yes)' <<< ${A_GLX_DATA[2]} did not work in Arch, no idea why
9396 local glx_direct_render=$( gawk '{print $1}' <<< "${A_GLX_DATA[2]}" )
9398 # set A_GRAPHICS_CARD_DATA
9399 if [[ $BSD_TYPE == 'bsd' ]];then
9400 if [[ $B_PCICONF_SET == 'false' ]];then
9403 get_pciconf_card_data 'display'
9405 get_graphics_card_data
9407 # set A_GRAPHIC_DRIVERS
9410 if [[ ${#A_GRAPHIC_DRIVERS[@]} -eq 0 ]];then
9413 for (( i=0; i < ${#A_GRAPHIC_DRIVERS[@]}; i++ ))
9416 a_graphics_working=( ${A_GRAPHIC_DRIVERS[i]} )
9418 case ${a_graphics_working[1]} in
9420 loaded="$loaded$separator_loaded${a_graphics_working[0]}"
9421 separator_loaded=','
9424 unloaded="$unloaded$separator_unloaded${a_graphics_working[0]}"
9425 separator_unloaded=','
9428 failed="$failed$separator_failed${a_graphics_working[0]}"
9429 separator_failed=','
9434 if [[ -n $loaded ]];then
9435 driver="${driver} $loaded"
9437 if [[ -n $unloaded ]];then
9438 driver="${driver} (unloaded: $unloaded)"
9440 if [[ -n $failed ]];then
9441 driver="${driver} ${RED}FAILED:${C2} $failed"
9443 # sometimes for some reason there is no driver found but the array is started
9444 if [[ -z $driver ]];then
9448 if [[ ${#A_GRAPHIC_DRIVERS[@]} -gt 1 ]];then
9451 driver_string="${C1}driver$driver_plural$SEP3${C2}$driver "
9453 # some basic error handling:
9454 if [[ -z $screen_resolution ]];then
9455 screen_resolution='N/A'
9457 if [[ -z $display_vendor || -z $display_version ]];then
9458 display_vendor_string="N/A"
9460 display_vendor_string="$display_vendor $display_version"
9462 display_server_string="${C1}Display Server${SEP3}${C2} $display_vendor_string "
9464 if [[ $B_ROOT == 'true' ]];then
9465 root_x_string='for root '
9466 if [[ $B_RUNNING_IN_SHELL == 'true' || $B_CONSOLE_IRC == 'true' ]];then
9470 if [[ $B_RUNNING_IN_DISPLAY != 'true' ]];then
9471 root_x_string="${root_x_string}out of X"
9475 if [[ -n $root_x_string ]];then
9476 root_x_string="${C1}Advanced Data:${C2} N/A $root_x_string"
9479 display_full_string="$display_server_string$driver_string${C1}${res_tty}$SEP3${C2} ${screen_resolution} $root_x_string"
9481 if [[ ${#A_GRAPHICS_CARD_DATA[@]} -gt 0 ]];then
9482 for (( i=0; i < ${#A_GRAPHICS_CARD_DATA[@]}; i++ ))
9485 a_graphics_working=( ${A_GRAPHICS_CARD_DATA[i]} )
9488 card_data=${a_graphics_working[0]}
9489 if [[ $B_EXTRA_DATA == 'true' ]];then
9490 if [[ -n ${a_graphics_working[1]} ]];then
9491 card_bus_id=" ${C1}bus-ID$SEP3${C2} ${a_graphics_working[1]}"
9492 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
9493 if [[ $BSD_TYPE != 'bsd' ]];then
9494 chip_id=$( get_lspci_chip_id "${a_graphics_working[1]}" )
9496 chip_id=${a_graphics_working[2]}
9500 card_bus_id=" ${C1}bus-ID$SEP3${C2} N/A"
9503 if [[ -n $chip_id ]];then
9504 chip_id=" ${C1}chip-ID$SEP3${C2} $chip_id"
9506 if [[ ${#A_GRAPHICS_CARD_DATA[@]} -gt 1 ]];then
9507 card_id="Card-$(($i+1)):"
9511 graphics_data="${C1}$card_id${C2} $card_data$card_bus_id$chip_id "
9512 if [[ ${#A_GRAPHICS_CARD_DATA[@]} -gt 1 ]];then
9513 graphics_data=$( create_print_line "$line_starter" "${graphics_data}" )
9514 print_screen_output "$graphics_data"
9519 # handle cases where card detection fails, like in PS3, where lspci gives no output, or headless boxes..
9521 graphics_data="${C1}Card:${C2} Failed to Detect Video Card! "
9523 if [[ -n $graphics_data && $( calculate_line_length "${graphics_data}$display_full_string" ) -lt $COLS_INNER ]];then
9524 graphics_data=$( create_print_line "$line_starter" "${graphics_data}$display_full_string" )
9526 if [[ -n $graphics_data ]];then
9527 graphics_data=$( create_print_line "$line_starter" "$graphics_data" )
9528 print_screen_output "$graphics_data"
9531 graphics_data=$( create_print_line "$line_starter" "$display_full_string" )
9533 print_screen_output "$graphics_data"
9534 # if [[ -z $glx_renderer || -z $glx_version ]];then
9538 ## note: if glx render or display_version have no content, then mesa is true
9539 # if [[ $B_SHOW_DISPLAY_DATA == 'true' ]] && [[ $b_is_mesa != 'true' ]];then
9540 if [[ $B_SHOW_DISPLAY_DATA == 'true' && $B_ROOT != 'true' ]];then
9541 if [[ -z $glx_renderer ]];then
9544 if [[ -z $glx_version ]];then
9547 if [[ -z $glx_direct_render ]];then
9548 glx_direct_render='N/A'
9550 if [[ $B_HANDLE_CORRUPT_DATA == 'true' || $B_EXTRA_DATA == 'true' ]];then
9551 direct_render_string=" ${C1}Direct Rendering$SEP3${C2} ${glx_direct_render}${CN}"
9553 graphics_data="${C1}GLX Renderer$SEP3${C2} ${glx_renderer} ${C1}GLX Version$SEP3${C2} ${glx_version}${CN}$direct_render_string"
9554 graphics_data=$( create_print_line " " "$graphics_data" )
9556 print_screen_output "$graphics_data"
9561 print_hard_disk_data()
9564 local hdd_data='' hdd_data_2='' a_hdd_working='' hdd_temp_data='' hdd_string=''
9566 local dev_data='' size_data='' hdd_model='' usb_data='' hdd_name='' divisor=5
9567 local Line_Starter='Drives:' # inherited by print_optical_drives
9571 ## note: if hdd_model is declared prior to use, whatever string you want inserted will
9572 ## be inserted first. In this case, it's desirable to print out (x) before each disk found.
9573 local a_hdd_data_count=$(( ${#A_HDD_DATA[@]} - 1 ))
9575 local a_hdd_basic_working=( ${A_HDD_DATA[$a_hdd_data_count]} )
9577 local hdd_capacity="${a_hdd_basic_working[0]}"
9578 local hdd_used=${a_hdd_basic_working[1]}
9579 local bsd_unsupported='Hard drive data not yet supported for BSD systems.'
9580 local hdd_name_temp=''
9582 if [[ $B_SHOW_BASIC_DISK == 'true' || $B_SHOW_DISK == 'true' ]];then
9583 ## note: the output part of this should be in the print hdd data function, not here
9584 get_hard_drive_data_advanced
9585 for (( i=0; i < ${#A_HDD_DATA[@]} - 1; i++ ))
9587 # this adds the (x) numbering in front of each disk found, and creates the full disk string
9589 a_hdd_working=( ${A_HDD_DATA[i]} )
9591 if [[ $B_SHOW_DISK == 'true' ]];then
9592 if [[ -n ${a_hdd_working[3]} ]];then
9593 usb_data="${a_hdd_working[3]} "
9597 dev_data="/dev/${a_hdd_working[0]} "
9598 size_data=" ${C1}size$SEP3${C2} ${a_hdd_working[1]}"
9599 if [[ $B_EXTRA_DATA == 'true' && -n $dev_data ]];then
9600 hdd_temp_data=$( get_hdd_temp_data "$dev_data" )
9601 # error handling is done in get data function
9602 if [[ -n $hdd_temp_data ]];then
9603 hdd_temp_data=" ${C1}temp$SEP3${C2} ${hdd_temp_data}C"
9608 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
9609 hdd_serial=$( get_hdd_serial_number "${a_hdd_working[0]}" )
9610 if [[ -z $hdd_serial ]];then
9613 hdd_serial=" ${C1}serial$SEP3${C2} $hdd_serial"
9614 divisor=1 # print every line
9616 divisor=2 # for modulus line print out, either 2 items for full, or default for short
9618 dev_data="${C1}id$SEP3${C2} /dev/${a_hdd_working[0]} "
9620 if [[ -n ${a_hdd_working[2]} ]];then
9621 hdd_name_temp=${a_hdd_working[2]}
9625 hdd_name="${C1}model$SEP3${C2} $hdd_name_temp"
9626 hdd_string="$usb_data$dev_data$hdd_name$size_data$hdd_serial$hdd_temp_data"
9627 hdd_model="${hdd_model}${C1}$(($i+1)):${C2} $hdd_string "
9628 # printing line one, then new lines according to $divisor setting, and after, if leftovers, print that line.
9631 if [[ $divisor -eq 1 ]];then
9632 hdd_data=$( create_print_line "$Line_Starter" "${C1}HDD Total Size:${C2} ${hdd_capacity} (${hdd_used})" )
9633 print_screen_output "$hdd_data"
9635 hdd_data=$( create_print_line "$Line_Starter" "${hdd_model}" )
9636 print_screen_output "$hdd_data"
9639 hdd_data=$( create_print_line "$Line_Starter" "${C1}HDD Total Size:${C2} ${hdd_capacity} (${hdd_used}) ${hdd_model}" )
9640 print_screen_output "$hdd_data"
9646 # using modulus here, if divisible by $divisor, print line, otherwise skip
9647 if [[ $(( $i % $divisor )) -eq 0 ]];then
9648 hdd_data=$( create_print_line "$Line_Starter" "${hdd_model}${CN}" )
9649 print_screen_output "$hdd_data"
9656 # then print any leftover items
9657 if [[ -n $hdd_model ]];then
9658 hdd_data=$( create_print_line "$Line_Starter" "${hdd_model}${CN}" )
9659 print_screen_output "$hdd_data"
9661 # temporary message to indicate not yet supported
9662 if [[ $BSD_TYPE == 'bsd' ]];then
9663 hdd_data=$bsd_unsupported
9664 hdd_data=$( create_print_line "$Line_Starter" "$hdd_data${CN}" )
9665 print_screen_output "$hdd_data"
9669 # temporary message to indicate not yet supported
9670 hdd_data="${C1}HDD Total Size:${C2} ${hdd_capacity} (${hdd_used})"
9671 if [[ $BSD_TYPE == 'bsd' ]];then
9672 hdd_data=$bsd_unsupported
9674 hdd_data=$( create_print_line "$Line_Starter" "$hdd_data${CN}" )
9675 print_screen_output "$hdd_data"
9678 if [[ $B_SHOW_FULL_OPTICAL == 'true' || $B_SHOW_BASIC_OPTICAL == 'true' ]];then
9679 print_optical_drive_data
9689 local info_data='' line_starter='Info:' runlvl_default='' runlvl='' runlvl_title='runlevel'
9690 local init_data='' init_type='' init_version='' rc_type='' rc_version=''
9691 local client_data='' shell_data='' shell_parent='' tty_session=''
9692 local memory="$( get_memory_data )"
9693 local processes=$(( $( wc -l <<< "$Ps_aux_Data" ) - 1 ))
9694 local up_time="$( get_uptime )"
9695 local patch_version_number=$( get_patch_version_string )
9696 local gcc_string='' gcc_installed='' gcc_others='' closing_data=''
9698 if [[ -z $memory ]];then
9702 if [[ $B_EXTRA_DATA == 'true' ]];then
9703 get_gcc_system_version
9704 if [[ ${#A_GCC_VERSIONS[@]} -gt 0 ]];then
9705 if [[ -n ${A_GCC_VERSIONS[0]} ]];then
9706 gcc_installed=${A_GCC_VERSIONS[0]}
9710 if [[ $B_EXTRA_EXTRA_DATA == 'true' && -n ${A_GCC_VERSIONS[1]} ]];then
9711 gcc_others=" ${C1}alt$SEP3${C2} $( tr ',' '/' <<< ${A_GCC_VERSIONS[1]} )"
9713 gcc_installed="${C1}Gcc sys$SEP3${C2} $gcc_installed$gcc_others "
9716 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
9717 shell_data=$( get_shell_data )
9718 if [[ -n $shell_data ]];then
9719 # note, if you start this in tty, it will give 'login' as the parent, which we don't want.
9720 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
9721 if [[ $B_RUNNING_IN_DISPLAY != 'true' ]];then
9722 shell_parent=$( get_tty_number )
9723 shell_parent="tty $shell_parent"
9725 shell_parent=$( get_shell_parent )
9727 if [[ $shell_parent == 'login' ]];then
9729 elif [[ -n $shell_parent ]];then
9730 shell_parent=" running in $shell_parent"
9733 IRC_CLIENT="$IRC_CLIENT ($shell_data$shell_parent)"
9737 # Some code could look superfluous but BitchX doesn't like lines not ending in a newline. F*&k that bitch!
9738 # long_last=$( echo -ne "${C1}Processes$SEP3${C2} ${processes}${CN} | ${C1}Uptime$SEP3${C2} ${up_time}${CN} | ${C1}Memory$SEP3${C2} ${MEM}${CN}" )
9739 info_data="${C1}Processes$SEP3${C2} ${processes} ${C1}Uptime$SEP3${C2} ${up_time} ${C1}Memory$SEP3${C2} ${memory}${CN} "
9741 # this only triggers if no X data is present or if extra data switch is on
9742 if [[ $B_SHOW_DISPLAY_DATA != 'true' || $B_EXTRA_DATA == 'true' ]];then
9744 if [[ ${A_INIT_DATA[0]} == 'systemd' && -z $( grep -E '^[0-9]$' <<< ${A_INIT_DATA[4]} ) ]];then
9745 runlvl_title='target'
9747 init_type=${A_INIT_DATA[0]}
9748 if [[ -z $init_type ]];then
9752 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
9753 init_version=${A_INIT_DATA[1]}
9754 if [[ -z $init_version ]];then
9757 init_version=" ${C1}v$SEP3${C2} $init_version"
9758 rc_version=${A_INIT_DATA[3]}
9759 if [[ -n $rc_version ]];then
9760 rc_version=" ${C1}v$SEP3${C2} $rc_version"
9763 runlvl_default=${A_INIT_DATA[5]}
9765 # currently only using openrc here, otherwise show nothing
9766 rc_type=${A_INIT_DATA[2]}
9767 if [[ -n $rc_type ]];then
9768 rc_type=" ${C1}rc$SEP3${C2} $rc_type$rc_version"
9770 init_type="${C1}Init$SEP3${C2} $init_type$init_version "
9772 runlvl=${A_INIT_DATA[4]}
9773 if [[ -n $runlvl ]];then
9774 runlvl="${C1}$runlvl_title$SEP3${C2} $runlvl "
9776 if [[ -n $runlvl_default ]];then
9777 runlvl_default="${C1}default$SEP3${C2} $runlvl_default "
9779 init_data="$init_type$rc_type$runlvl$runlvl_default"
9781 if [[ $SHOW_IRC -gt 0 ]];then
9782 client_data="${C1}Client$SEP3${C2} ${IRC_CLIENT}${IRC_CLIENT_VERSION} "
9784 info_data="${info_data}"
9785 closing_data="$client_data${C1}$SCRIPT_NAME$SEP3${C2} $SCRIPT_VERSION_NUMBER$patch_version_number${CN}"
9787 # sometimes gcc is very long, and default runlevel can be long with systemd, so create a gcc-less line first
9788 if [[ $( calculate_line_length "${info_data}${init_data}${gcc_installed}${closing_data}" ) -gt $COLS_INNER ]];then
9789 info_data=${info_data}${init_data}
9790 info_data=$( create_print_line "$line_starter" "$info_data" )
9791 print_screen_output "$info_data"
9798 if [[ $( calculate_line_length "${info_data}${init_data}${gcc_installed}${closing_data}" ) -gt $COLS_INNER ]];then
9799 info_data=${info_data}${init_data}${gcc_installed}
9800 info_data=$( create_print_line "$line_starter" "$info_data" )
9801 print_screen_output "$info_data"
9808 info_data="${info_data}${init_data}${gcc_installed}${closing_data}"
9810 info_data=$( create_print_line "$line_starter" "$info_data" )
9811 if [[ $SCHEME -gt 0 ]];then
9812 info_data="${info_data} ${NORMAL}"
9814 print_screen_output "$info_data"
9819 print_machine_data()
9823 local system_line='' mobo_line='' bios_line='' chassis_line=''
9824 local mobo_vendor='' mobo_model='' mobo_version='' mobo_serial=''
9825 local bios_vendor='' bios_version='' bios_date='' bios_rom=''
9826 local system_vendor='' product_name='' product_version='' product_serial='' product_uuid=''
9827 local chassis_vendor='' chassis_type='' chassis_version='' chassis_serial=''
9828 local b_skip_system='false' b_skip_chassis='false'
9829 local sysDmiError='No /sys/class/dmi, using '
9830 local sysDmiNull='No /sys/class/dmi machine data: try newer kernel, or install dmidecode'
9831 # set A_MACHINE_DATA
9834 if [[ -n $BSD_TYPE ]];then
9836 sysDmiNull='No machine data available. Is dmidecode installed?'
9840 ## keys for machine data are:
9841 # 0-sys_vendor 1-product_name 2-product_version 3-product_serial 4-product_uuid
9842 # 5-board_vendor 6-board_name 7-board_version 8-board_serial
9843 # 9-bios_vendor 10-bios_version 11-bios_date
9845 # 12-chassis_vendor 13-chassis_type 14-chassis_version 15-chassis_serial
9847 if [[ ${#A_MACHINE_DATA[@]} -gt 0 ]];then
9848 # note: in some case a mobo/version will match a product name/version, do not print those
9849 # but for laptops, or even falsely id'ed desktops with batteries, let's print it all if it matches
9850 # there can be false id laptops if battery appears so need to make sure system is filled
9851 if [[ -z ${A_MACHINE_DATA[0]} ]];then
9852 b_skip_system='true'
9854 if [[ $B_PORTABLE != 'true' ]];then
9855 # ibm / ibm can be true; dell / quantum is false, so in other words, only do this
9856 # in case where the vendor is the same and the version is the same and not null,
9857 # otherwise the version information is going to be different in all cases I think
9858 if [[ -n ${A_MACHINE_DATA[0]} && ${A_MACHINE_DATA[0]} == ${A_MACHINE_DATA[5]} ]];then
9859 if [[ -n ${A_MACHINE_DATA[2]} && ${A_MACHINE_DATA[2]} == ${A_MACHINE_DATA[7]} ]] || \
9860 [[ -z ${A_MACHINE_DATA[2]} && ${A_MACHINE_DATA[1]} == ${A_MACHINE_DATA[6]} ]];then
9861 b_skip_system='true'
9866 # no point in showing chassis if system isn't there, it's very unlikely that would be correct
9867 if [[ $B_EXTRA_EXTRA_DATA == 'true' && $b_skip_system != 'true' ]];then
9868 if [[ -n ${A_MACHINE_DATA[7]} && ${A_MACHINE_DATA[14]} == ${A_MACHINE_DATA[7]} ]];then
9869 b_skip_chassis='true'
9871 if [[ -n ${A_MACHINE_DATA[12]} && $b_skip_chassis != 'true' ]];then
9872 # no need to print the vendor string again if it's the same
9873 if [[ ${A_MACHINE_DATA[12]} != ${A_MACHINE_DATA[0]} ]];then
9874 chassis_vendor=" ${A_MACHINE_DATA[12]}"
9876 if [[ -n ${A_MACHINE_DATA[13]} ]];then
9877 chassis_type=" ${C1}type$SEP3${C2} ${A_MACHINE_DATA[13]}"
9879 if [[ -n ${A_MACHINE_DATA[14]} ]];then
9880 chassis_version=" ${C1}version$SEP3${C2} ${A_MACHINE_DATA[14]}"
9882 if [[ -n ${A_MACHINE_DATA[15]} && $B_OUTPUT_FILTER != 'true' ]];then
9883 chassis_serial=" ${C1}serial$SEP3${C2} ${A_MACHINE_DATA[15]}"
9885 if [[ -n "$chassis_vendor$chassis_type$chassis_version$chassis_serial" ]];then
9886 chassis_line="${C1}Chassis$SEP3${C2}$chassis_vendor$chassis_type$chassis_version$chassis_serial"
9890 if [[ -n ${A_MACHINE_DATA[5]} ]];then
9891 mobo_vendor=${A_MACHINE_DATA[5]}
9895 if [[ -n ${A_MACHINE_DATA[6]} ]];then
9896 mobo_model=${A_MACHINE_DATA[6]}
9900 if [[ -n ${A_MACHINE_DATA[7]} ]];then
9901 mobo_version=" ${C1}version$SEP3${C2} ${A_MACHINE_DATA[7]}"
9903 if [[ -n ${A_MACHINE_DATA[8]} && $B_OUTPUT_FILTER != 'true' ]];then
9904 mobo_serial=" ${C1}serial$SEP3${C2} ${A_MACHINE_DATA[8]}"
9906 if [[ -n ${A_MACHINE_DATA[9]} ]];then
9907 bios_vendor=${A_MACHINE_DATA[9]}
9911 if [[ -n ${A_MACHINE_DATA[10]} ]];then
9912 bios_version=${A_MACHINE_DATA[10]}
9913 if [[ -n ${A_MACHINE_DATA[16]} ]];then
9914 bios_version="$bios_version rv ${A_MACHINE_DATA[16]}"
9919 if [[ -n ${A_MACHINE_DATA[11]} ]];then
9920 bios_date=${A_MACHINE_DATA[11]}
9924 if [[ $B_EXTRA_EXTRA_DATA == 'true' && -n ${A_MACHINE_DATA[17]} ]];then
9925 bios_rom=" ${C1}rom size$SEP3${C2} ${A_MACHINE_DATA[17]}"
9927 mobo_line="${C1}Mobo$SEP3${C2} $mobo_vendor ${C1}model$SEP3${C2} $mobo_model$mobo_version$mobo_serial"
9928 bios_line="${C1}Bios$SEP3${C2} $bios_vendor ${C1}version$SEP3${C2} $bios_version ${C1}date$SEP3${C2} $bios_date$bios_rom"
9929 if [[ $( calculate_line_length "$mobo_line$bios_line" ) -lt $COLS_INNER ]];then
9930 mobo_line="$mobo_line $bios_line"
9933 if [[ $b_skip_system == 'true' ]];then
9934 system_line=$mobo_line
9937 # this has already been tested for above so we know it's not null
9938 system_vendor=${A_MACHINE_DATA[0]}
9939 if [[ $B_PORTABLE == 'true' ]];then
9940 system_vendor="$system_vendor (portable)"
9942 if [[ -n ${A_MACHINE_DATA[1]} ]];then
9943 product_name=${A_MACHINE_DATA[1]}
9947 if [[ -n ${A_MACHINE_DATA[2]} ]];then
9948 product_version=" ${C1}version$SEP3${C2} ${A_MACHINE_DATA[2]}"
9950 if [[ -n ${A_MACHINE_DATA[3]} && $B_OUTPUT_FILTER != 'true' ]];then
9951 product_serial=" ${C1}serial$SEP3${C2} ${A_MACHINE_DATA[3]} "
9953 system_line="${C1}System$SEP3${C2} $system_vendor ${C1}product$SEP3${C2} $product_name$product_version$product_serial"
9954 if [[ -n $chassis_line && $( calculate_line_length "$system_line$chassis_line" ) -lt $COLS_INNER ]];then
9955 system_line="$system_line $chassis_line"
9961 system_line="${C2}$sysDmiNull${CN}"
9963 # patch to dump all of above if dmidecode was data source and non root user
9964 if [[ ${A_MACHINE_DATA[0]} == 'dmidecode-non-root-user' || ${A_MACHINE_DATA[0]} == 'dmidecode-no-smbios-dmi-data' ]];then
9965 if [[ ${A_MACHINE_DATA[0]} == 'dmidecode-non-root-user' ]];then
9966 system_line="${C2}${sysDmiError}dmidecode: you must be root to run dmidecode${CN}"
9967 elif [[ ${A_MACHINE_DATA[0]} == 'dmidecode-no-smbios-dmi-data' ]];then
9968 system_line="${C2}${sysDmiError}dmidecode: no machine data available${CN}"
9974 system_line=$( create_print_line "Machine:" "$system_line" )
9975 print_screen_output "$system_line"
9976 if [[ -n $mobo_line ]];then
9977 mobo_line=$( create_print_line " " "$mobo_line" )
9978 print_screen_output "$mobo_line"
9980 if [[ -n $bios_line ]];then
9981 bios_line=$( create_print_line " " "$bios_line" )
9982 print_screen_output "$bios_line"
9984 if [[ -n $chassis_line ]];then
9985 chassis_line=$( create_print_line " " "$chassis_line" )
9986 print_screen_output "$chassis_line"
9992 # args: $1 - module name (could be > 1, so loop it ); $2 - audio (optional)
9993 print_module_version()
9996 local module_versions='' module='' version='' prefix='' modules=$1
9998 # note that sound driver data tends to have upper case, but modules are lower
9999 if [[ $2 == 'audio' ]];then
10000 if [[ -z $( grep -E '^snd' <<< $modules ) ]];then
10001 prefix='snd_' # sound modules start with snd_
10003 modules=$( tr '[A-Z]' '[a-z]' <<< $modules )
10004 modules=$( tr '-' '_' <<< $modules )
10005 # special intel processing, generally no version info though
10006 if [[ $modules == 'hda intel' ]];then
10007 modules='hda_intel'
10008 elif [[ $modules == 'intel ich' ]];then
10013 for module in $modules
10015 version=$( get_module_version_number "$prefix$module" )
10016 if [[ -n $version ]];then
10017 module_versions="$module_versions $version"
10021 if [[ -n $module_versions ]];then
10022 echo " ${C1}ver$SEP3${C2}$module_versions"
10027 print_networking_data()
10030 local i='' card_id='' network_data='' a_network_working='' port_data='' driver_data=''
10031 local card_string='' port_plural='' module_version='' pci_bus_id='' bus_usb_text=''
10032 local bus_usb_id='' line_starter='Network:' card_string='' card_data='' chip_id=''
10034 # set A_NETWORK_DATA
10035 if [[ $BSD_TYPE == 'bsd' ]];then
10036 if [[ $B_PCICONF_SET == 'false' ]];then
10039 get_pciconf_card_data 'network'
10041 get_networking_data
10044 # will never be null because null is handled in get_network_data, but in case we change
10045 # that leaving this test in place.
10046 if [[ -n ${A_NETWORK_DATA[@]} ]];then
10047 for (( i=0; i < ${#A_NETWORK_DATA[@]}; i++ ))
10050 a_network_working=( ${A_NETWORK_DATA[i]} )
10051 IFS="$ORIGINAL_IFS"
10065 if [[ ${#A_NETWORK_DATA[@]} -gt 1 ]];then
10066 chip_id="-$(( $i + 1 ))"
10068 if [[ -n ${a_network_working[1]} && $B_EXTRA_DATA == 'true' && $BSD_TYPE != 'bsd' ]];then
10069 module_version=$( print_module_version "${a_network_working[1]}" )
10071 if [[ -n ${a_network_working[1]} ]];then
10072 # note: linux drivers can have numbers, like tg3
10073 if [[ $BSD_TYPE == 'bsd' ]];then
10074 driver=$( sed 's/[0-9]*$//' <<< ${a_network_working[1]} )
10076 driver=${a_network_working[1]}
10078 driver_data="${C1}driver$SEP3${C2} ${driver}$module_version "
10080 if [[ -n ${a_network_working[2]} && $B_EXTRA_DATA == 'true' ]];then
10081 if [[ $( wc -w <<< ${a_network_working[2]} ) -gt 1 ]];then
10084 port_data="${C1}port$port_plural$SEP3${C2} ${a_network_working[2]} "
10086 if [[ -n ${a_network_working[4]} && $B_EXTRA_DATA == 'true' ]];then
10087 if [[ -z $( grep '^usb-' <<< ${a_network_working[4]} ) ]];then
10088 bus_usb_text='bus-ID'
10089 bus_usb_id=${a_network_working[4]}
10090 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
10091 if [[ $BSD_TYPE != 'bsd' ]];then
10092 chip_id=$( get_lspci_chip_id "${a_network_working[4]}" )
10094 chip_id=${a_network_working[10]}
10098 bus_usb_text='usb-ID'
10099 bus_usb_id=$( cut -d '-' -f '2-4' <<< ${a_network_working[4]} )
10100 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
10101 chip_id=${a_network_working[10]}
10104 pci_bus_id="${C1}$bus_usb_text$SEP3${C2} $bus_usb_id"
10105 if [[ -n $chip_id ]];then
10106 chip_id=" ${C1}chip-ID$SEP3${C2} $chip_id"
10109 card_string="${C1}Card$card_id:${C2} ${a_network_working[0]} "
10110 card_data="$driver_data$port_data$pci_bus_id$chip_id"
10111 if [[ $( calculate_line_length "$card_string$card_data" ) -gt $COLS_INNER ]];then
10112 network_data=$( create_print_line "$line_starter" "$card_string" )
10115 print_screen_output "$network_data"
10117 network_data=$( create_print_line "$line_starter" "$card_string$card_data" )
10119 print_screen_output "$network_data"
10120 if [[ $B_SHOW_ADVANCED_NETWORK == 'true' ]];then
10121 print_network_advanced_data
10125 network_data="${C1}Card:${C2} Failed to Detect Network Card! "
10126 network_data=$( create_print_line "$line_starter" "$network_data" )
10127 print_screen_output "$network_data"
10129 if [[ $B_SHOW_IP == 'true' ]];then
10130 print_networking_ip_data
10135 print_network_advanced_data()
10138 local network_data='' if_id='N/A' duplex='N/A' mac_id='N/A' speed='N/A' oper_state='N/A'
10139 local b_is_wifi='false' speed_string='' duplex_string=''
10141 # first check if it's a known wifi id'ed card, if so, no print of duplex/speed
10142 if [[ -n $( grep -Esi '(wireless|wifi|wi-fi|wlan|802\.11|centrino)' <<< ${a_network_working[0]} ) ]];then
10145 if [[ -n ${a_network_working[5]} ]];then
10146 if_id=${a_network_working[5]}
10148 if [[ -n ${a_network_working[6]} ]];then
10149 oper_state=${a_network_working[6]}
10151 # no print out for wifi since it doesn't have duplex/speed data availabe
10152 # note that some cards show 'unknown' for state, so only testing explicitly
10153 # for 'down' string in that to skip showing speed/duplex
10154 if [[ $b_is_wifi != 'true' && $oper_state != 'down' ]];then
10155 if [[ -n ${a_network_working[7]} ]];then
10156 # make sure the value is strictly numeric before appending Mbps
10157 if [[ -n $( grep -E '^[0-9\.,]+$' <<< "${a_network_working[7]}" ) ]];then
10158 speed="${a_network_working[7]} Mbps"
10160 speed=${a_network_working[7]}
10163 speed_string="${C1}speed$SEP3${C2} $speed "
10164 if [[ -n ${a_network_working[8]} ]];then
10165 duplex=${a_network_working[8]}
10167 duplex_string="${C1}duplex$SEP3${C2} $duplex "
10169 if [[ -n ${a_network_working[9]} ]];then
10170 if [[ $B_OUTPUT_FILTER == 'true' ]];then
10171 mac_id=$FILTER_STRING
10173 mac_id=${a_network_working[9]}
10176 network_data="${C1}IF:${C2} $if_id ${C1}state$SEP3${C2} $oper_state $speed_string$duplex_string${C1}mac$SEP3${C2} $mac_id"
10177 network_data=$( create_print_line " " "$network_data" )
10178 print_screen_output "$network_data"
10183 print_networking_ip_data()
10186 local ip=$( get_networking_wan_ip_data )
10187 local wan_ip_data='' a_interfaces_working='' interfaces='' i=''
10188 local if_id='' if_ip='' if_ipv6='' if_ipv6_string='' full_string='' if_string=''
10189 local if_id_string='' if_ip_string=''
10190 local line_max=$(( $COLS_INNER - 40 ))
10192 # set A_INTERFACES_DATA
10193 get_networking_local_ip_data
10194 # first print output for wan ip line. Null is handled in the get function
10195 if [[ -z $ip ]];then
10198 if [[ $B_OUTPUT_FILTER == 'true' ]];then
10202 wan_ip_data="${C1}WAN IP:${C2} $ip "
10203 # then create the list of local interface/ip
10204 i=0 ## loop starts with 1 by auto-increment so it only shows cards > 1
10205 while [[ -n ${A_INTERFACES_DATA[i]} ]]
10208 a_interfaces_working=(${A_INTERFACES_DATA[i]})
10209 IFS="$ORIGINAL_IFS"
10214 if [[ -z $( grep '^Interface' <<< ${a_interfaces_working[0]} ) ]];then
10215 if [[ -n ${a_interfaces_working[1]} ]];then
10216 if [[ $B_OUTPUT_FILTER == 'true' ]];then
10217 if_ip=$FILTER_STRING
10219 if_ip=${a_interfaces_working[1]}
10222 if_ip_string=" ${C1}ip$SEP3${C2} $if_ip"
10223 if [[ $B_EXTRA_DATA == 'true' ]];then
10224 if [[ -n ${a_interfaces_working[3]} ]];then
10225 if [[ $B_OUTPUT_FILTER == 'true' ]];then
10226 if_ipv6=$FILTER_STRING
10228 if_ipv6=${a_interfaces_working[3]}
10231 if_ipv6_string=" ${C1}ip-v6$SEP3${C2} $if_ipv6"
10234 if [[ -n ${a_interfaces_working[0]} ]];then
10235 if_id=${a_interfaces_working[0]}
10237 if_string="$wan_ip_data$if_string${C1}IF:${C2} $if_id$if_ip_string$if_ipv6_string "
10239 if [[ $( calculate_line_length "$if_string" ) -gt $line_max ]];then
10240 full_string=$( create_print_line " " "$if_string" )
10241 print_screen_output "$full_string"
10247 # then print out anything not printed already
10248 if [[ -n $if_string ]];then
10249 full_string=$( create_print_line " " "$if_string" )
10250 print_screen_output "$full_string"
10255 print_optical_drive_data()
10258 local a_drives='' drive_data='' counter=''
10259 local drive_id='' drive_links='' vendor='' speed='' multisession='' mcn='' audio=''
10260 local dvd='' state='' rw_support='' rev='' separator='' drive_string=''
10261 get_optical_drive_data
10262 # 0 - true dev path, ie, sr0, hdc
10263 # 1 - dev links to true path
10264 # 2 - device vendor - for hdx drives, vendor model are one string from proc
10266 # 4 - device rev version
10267 if [[ ${#A_OPTICAL_DRIVE_DATA[@]} -gt 0 ]];then
10268 for (( i=0; i < ${#A_OPTICAL_DRIVE_DATA[@]}; i++ ))
10271 a_drives=(${A_OPTICAL_DRIVE_DATA[i]})
10272 IFS="$ORIGINAL_IFS"
10286 if [[ ${#A_OPTICAL_DRIVE_DATA[@]} -eq 1 && -z ${a_drives[0]} && -z ${a_drives[1]} ]];then
10287 drive_string="No optical drives detected."
10288 B_SHOW_FULL_OPTICAL='false'
10290 if [[ ${#A_OPTICAL_DRIVE_DATA[@]} -gt 1 ]];then
10291 counter="-$(( i + 1 ))"
10293 if [[ -z ${a_drives[0]} ]];then
10296 drive_id="/dev/${a_drives[0]}"
10298 drive_links=$( sed 's/~/,/g' <<< ${a_drives[1]} )
10299 if [[ -z $drive_links ]];then
10302 if [[ -n ${a_drives[2]} ]];then
10303 vendor=${a_drives[2]}
10304 if [[ -n ${a_drives[3]} ]];then
10305 vendor="$vendor ${a_drives[3]}"
10308 if [[ -z $vendor ]];then
10309 if [[ -n ${a_drives[3]} ]];then
10310 vendor=${a_drives[3]}
10315 if [[ $B_EXTRA_DATA == 'true' ]];then
10316 if [[ -n ${a_drives[4]} ]];then
10321 rev=" ${C1}rev$SEP3${C2} $rev"
10323 drive_string="$drive_id ${C1}model$SEP3${C2} $vendor$rev ${C1}dev-links$SEP3${C2} $drive_links"
10325 drive_data="${C1}Optical${counter}:${C2} $drive_string"
10326 drive_data=$( create_print_line "$Line_Starter" "$drive_data" )
10327 print_screen_output "$drive_data"
10330 # 6 - multisession support
10339 if [[ $B_SHOW_FULL_OPTICAL == 'true' ]];then
10340 if [[ -z ${a_drives[5]} ]];then
10343 speed="${a_drives[5]}x"
10345 if [[ -z ${a_drives[8]} ]];then
10347 elif [[ ${a_drives[8]} == 1 ]];then
10352 audio=" ${C1}audio$SEP3${C2} $audio"
10353 if [[ -z ${a_drives[6]} ]];then
10355 elif [[ ${a_drives[6]} == 1 ]];then
10360 multisession=" ${C1}multisession$SEP3${C2} $multisession"
10361 if [[ -z ${a_drives[11]} ]];then
10363 elif [[ ${a_drives[11]} == 1 ]];then
10368 if [[ $B_EXTRA_DATA == 'true' ]];then
10369 if [[ -z ${a_drives[14]} ]];then
10372 state="${a_drives[14]}"
10374 state=" ${C1}state$SEP3${C2} $state"
10376 if [[ -n ${a_drives[9]} && ${a_drives[9]} == 1 ]];then
10380 if [[ -n ${a_drives[10]} && ${a_drives[10]} == 1 ]];then
10381 rw_support="${rw_support}${separator}cd-rw"
10384 if [[ -n ${a_drives[12]} && ${a_drives[12]} == 1 ]];then
10385 rw_support="${rw_support}${separator}dvd-r"
10388 if [[ -n ${a_drives[13]} && ${a_drives[13]} == 1 ]];then
10389 rw_support="${rw_support}${separator}dvd-ram"
10392 if [[ -z $rw_support ]];then
10396 drive_data="${C1}Features: speed$SEP3${C2} $speed$multisession$audio ${C1}dvd$SEP3${C2} $dvd ${C1}rw$SEP3${C2} $rw_support$state"
10397 drive_data=$( create_print_line "$Line_Starter" "$drive_data" )
10398 print_screen_output "$drive_data"
10407 print_partition_data()
10410 local a_partition_working='' partition_used='' partition_data=''
10411 local counter=0 i=0 a_partition_data='' line_starter='' line_max=$(( $COLS_INNER - 25 ))
10412 local partitionIdClean='' part_dev='' full_dev='' part_label='' full_label=''
10413 local part_uuid='' full_uuid='' dev_remote='' full_fs='' line_max_label_uuid=$COLS_INNER
10414 local b_non_dev='false' holder=''
10416 # set A_PARTITION_DATA
10419 for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
10422 a_partition_working=(${A_PARTITION_DATA[i]})
10423 IFS="$ORIGINAL_IFS"
10427 if [[ $B_SHOW_PARTITIONS_FULL == 'true' ]] || [[ ${a_partition_working[4]} == 'main' ]];then
10428 if [[ -n ${a_partition_working[2]} ]];then
10429 partition_used="${C1}used$SEP3${C2} ${a_partition_working[2]} (${a_partition_working[3]}) "
10431 partition_used='' # reset partition used to null
10433 if [[ -n ${a_partition_working[5]} ]];then
10434 full_fs="${a_partition_working[5]}"
10436 full_fs='N/A' # reset partition fs type
10438 full_fs="${C1}fs$SEP3${C2} $full_fs "
10440 if [[ $B_SHOW_LABELS == 'true' || $B_SHOW_UUIDS == 'true' ]];then
10441 if [[ -n ${a_partition_working[6]} ]];then
10442 if [[ -z $( grep -E '(^//|:/|non-dev)' <<< ${a_partition_working[6]} ) ]];then
10443 part_dev="/dev/${a_partition_working[6]}"
10445 elif [[ -n $( grep '^non-dev' <<< ${a_partition_working[6]} ) ]];then
10446 holder=$( sed 's/non-dev-//' <<< ${a_partition_working[6]} )
10450 part_dev="${a_partition_working[6]}"
10451 dev_remote='remote'
10457 full_dev="${C1}$dev_remote$SEP3${C2} $part_dev "
10458 if [[ $B_SHOW_LABELS == 'true' && $dev_remote != 'remote' ]];then
10459 if [[ -n ${a_partition_working[7]} ]];then
10460 part_label="${a_partition_working[7]}"
10464 full_label="${C1}label$SEP3${C2} $part_label "
10466 if [[ $B_SHOW_UUIDS == 'true' && $dev_remote != 'remote' ]];then
10467 if [[ -n ${a_partition_working[8]} ]];then
10468 part_uuid="${a_partition_working[8]}"
10472 full_uuid="${C1}uuid$SEP3${C2} $part_uuid"
10475 # don't show user names in output
10476 if [[ $B_OUTPUT_FILTER == 'true' ]];then
10477 partitionIdClean=$( sed $SED_RX "s|/home/([^/]+)/(.*)|/home/$FILTER_STRING/\2|" <<< ${a_partition_working[0]} )
10479 partitionIdClean=${a_partition_working[0]}
10481 id_size_fs="${C1}ID:${C2} $partitionIdClean ${C1}size$SEP3${C2} ${a_partition_working[1]} $partition_used$full_fs$full_dev"
10482 label_uuid="$full_label$full_uuid"
10483 # label/uuid always print one per line, so only wrap if it's very long
10484 if [[ $B_SHOW_UUIDS == 'true' && $B_SHOW_LABELS == 'true' && $( calculate_line_length "$id_size_fs$label_uuid" ) -gt $line_max_label_uuid ]];then
10485 a_partition_data[$counter]="$id_size_fs"
10487 a_partition_data[$counter]="$label_uuid"
10489 a_partition_data[$counter]="${a_partition_data[$counter]}$id_size_fs$label_uuid"
10491 # because these lines can vary widely, using dynamic length handling here
10492 if [[ $B_SHOW_LABELS == 'true' || $B_SHOW_UUIDS == 'true' ]] || [[ $( calculate_line_length "${a_partition_data[$counter]}" ) -gt $line_max ]];then
10497 # print out all lines, line starter on first line
10498 for (( i=0; i < ${#a_partition_data[@]};i++ ))
10500 if [[ $i -eq 0 ]];then
10501 line_starter='Partition:'
10505 partition_data=$( create_print_line "$line_starter" "${a_partition_data[$i]}" )
10506 print_screen_output "$partition_data"
10512 print_program_version()
10514 local patch_version_number=$( get_patch_version_string )
10515 local program_version="${C1}$SCRIPT_NAME$SEP3${C2} $SCRIPT_VERSION_NUMBER$patch_version_number${CN}"
10516 # great trick from: http://ideatrash.net/2011/01/bash-string-padding-with-sed.html
10517 # left pad: sed -e :a -e 's/^.\{1,80\}$/& /;ta'
10518 # right pad: sed -e :a -e 's/^.\{1,80\}$/ &/;ta'
10519 # center pad: sed -e :a -e 's/^.\{1,80\}$/ & /;ta'
10520 #local line_max=$COLS_INNER
10521 #program_version="$( sed -e :a -e "s/^.\{1,$line_max\}$/ &/;ta" <<< $program_version )" # use to create padding if needed
10522 # program_version=$( create_print_line "Version:" "$program_version" )
10523 print_screen_output "$program_version"
10530 local b_print_first='true'
10532 if [[ $B_SHOW_PS_CPU_DATA == 'true' ]];then
10533 get_ps_tcm_data 'cpu'
10534 print_ps_item 'cpu' "$b_print_first"
10535 b_print_first='false'
10537 if [[ $B_SHOW_PS_MEM_DATA == 'true' ]];then
10538 get_ps_tcm_data 'mem'
10539 print_ps_item 'mem' "$b_print_first"
10545 # args: $1 - cpu/mem; $2 true/false
10549 local a_ps_data='' ps_data='' line_starter='' line_start_data='' full_line=''
10550 local app_name='' app_pid='' app_cpu='' app_mem='' throttled='' app_daemon=''
10551 local b_print_first=$2 line_counter=0 i=0 count_nu='' extra_data=''
10553 if [[ -n $PS_THROTTLED ]];then
10554 throttled=" ${C1} - throttled from${C2} $PS_THROTTLED"
10558 line_start_data="${C1}CPU - % used - top ${C2} $PS_COUNT ${C1}active$throttled "
10561 line_start_data="${C1}Memory - MB / % used - top ${C2} $PS_COUNT ${C1}active$throttled"
10565 if [[ $b_print_first == 'true' ]];then
10566 line_starter='Processes:'
10571 # appName, appPath, appStarterName, appStarterPath, cpu, mem, pid, vsz, user
10572 ps_data=$( create_print_line "$line_starter" "$line_start_data" )
10573 print_screen_output "$ps_data"
10575 for (( i=0; i < ${#A_PS_DATA[@]}; i++ ))
10578 a_ps_data=(${A_PS_DATA[i]})
10579 IFS="$ORIGINAL_IFS"
10581 # handle the converted app names, with ~..~ means it didn't have a path
10582 if [[ -n $( grep -E '^~.*~$' <<< ${a_ps_data[0]} ) ]];then
10583 app_daemon='daemon'
10585 app_daemon='command'
10588 app_name=" ${C1}$app_daemon$SEP3${C2} ${a_ps_data[0]}"
10589 if [[ ${a_ps_data[0]} != ${a_ps_data[2]} ]];then
10590 app_name="$app_name ${C1}(started by$SEP3${C2} ${a_ps_data[2]}${C1})${C2}"
10592 app_pid=" ${C1}pid$SEP3${C2} ${a_ps_data[6]}"
10593 # ${C1}user:${C2} ${a_ps_data[8]}
10596 app_cpu=" ${C1}cpu$SEP3${C2} ${a_ps_data[4]}%"
10597 if [[ $B_EXTRA_DATA == 'true' ]];then
10598 extra_data=" ${C1}mem$SEP3${C2} ${a_ps_data[7]}MB (${a_ps_data[5]}%)${C2}"
10602 app_mem=" ${C1}mem$SEP3${C2} ${a_ps_data[7]}MB (${a_ps_data[5]}%)${C2}"
10603 if [[ $B_EXTRA_DATA == 'true' ]];then
10604 extra_data=" ${C1}cpu$SEP3${C2} ${a_ps_data[4]}%"
10608 (( line_counter++ ))
10609 count_nu="${C1}$line_counter:${C2}"
10610 full_line="$count_nu$app_cpu$app_mem$app_name$app_pid$extra_data"
10611 ps_data=$( create_print_line " " "$full_line" )
10612 print_screen_output "$ps_data"
10621 local device='' device_string='' device_state='' raid_level='' device_components=''
10622 local device_report='' u_data='' blocks='' super_blocks='' algorithm='' chunk_size=''
10623 local bitmap_values='' recovery_progress_bar='' recovery_percent='' recovered_sectors=''
10624 local finish_time='' recovery_speed='' raid_counter=0 device_counter=1 basic_counter=1
10625 local a_raid_working='' raid_data='' kernel_support='' read_ahead='' unused_devices=''
10626 local basic_raid='' basic_raid_separator='' basic_raid_plural='' inactive=''
10627 local component_separator='' device_id='' print_string='' loop_limit=0 array_count_unused=''
10628 local array_count='' raid_event='' b_print_lines='true'
10629 local no_raid_detected='' dev_string='/dev/'
10630 local empty_raid_data='' report_size='report' blocks_avail='blocks' chunk_raid_usage='chunk size'
10632 if [[ -n $BSD_TYPE ]];then
10633 no_raid_detected='No zfs software RAID detected - other types not yet supported.'
10634 empty_raid_data='No zfs RAID data available - other types not yet supported.'
10635 report_size='full size'
10636 blocks_avail='available size'
10637 chunk_raid_usage='raid allocated'
10639 no_raid_detected="No RAID data available - $FILE_MDSTAT is missing - is md_mod kernel module loaded?"
10640 empty_raid_data="No RAID devices detected - $FILE_MDSTAT and md_mod kernel raid module present"
10643 if [[ $BSD_TYPE == 'bsd' ]];then
10646 if [[ $B_RAID_SET != 'true' ]];then
10650 for (( i=0; i < ${#A_RAID_DATA[@]}; i++ ))
10653 a_raid_working=(${A_RAID_DATA[i]})
10654 IFS="$ORIGINAL_IFS"
10656 # reset on each iteration
10660 component_separator=''
10662 device_components=''
10671 recovery_percent=''
10672 recovery_progress_bar=''
10673 recovered_sectors=''
10679 if [[ -n $( grep '^md' <<< ${a_raid_working[0]} ) && -z $BSD_TYPE ]] || \
10680 [[ -n $BSD_TYPE && ${a_raid_working[0]} != '' ]];then
10681 if [[ $B_SHOW_BASIC_RAID == 'true' ]];then
10682 if [[ $basic_raid != '' ]];then
10683 basic_raid_plural='s'
10685 if [[ ${a_raid_working[1]} == 'inactive' ]];then
10686 inactive=" - ${a_raid_working[1]}"
10688 basic_raid="$basic_raid$basic_raid_separator${C1}$basic_counter${SEP3}${C2} $dev_string${a_raid_working[0]}$inactive"
10689 basic_raid_separator=' '
10690 (( basic_counter++ ))
10692 device_id="-$device_counter"
10693 device="$dev_string${a_raid_working[0]}"
10695 (( device_counter++ ))
10696 if [[ ${a_raid_working[1]} != '' ]];then
10697 device_state=" - ${a_raid_working[1]}"
10700 if [[ ${a_raid_working[2]} == '' ]];then
10703 raid_level=${a_raid_working[2]}
10705 # there's one case: md0 : inactive that has to be protected against
10706 if [[ ${a_raid_working[2]} == '' && ${a_raid_working[1]} == 'inactive' ]];then
10709 raid_level=" ${C1}raid${SEP3}${C2} $raid_level"
10711 if [[ ${a_raid_working[4]} != '' ]];then
10712 device_report="${a_raid_working[4]}"
10714 device_report="N/A"
10716 if [[ $B_EXTRA_DATA == 'true' ]];then
10717 if [[ ${a_raid_working[6]} != '' ]];then
10718 blocks=${a_raid_working[6]}
10722 blocks=" ${C1}$blocks_avail${SEP3}${C2} $blocks"
10724 if [[ ${a_raid_working[9]} != '' ]];then
10725 chunk_size=${a_raid_working[9]}
10729 chunk_size=" ${C1}$chunk_raid_usage${SEP3}${C2} $chunk_size"
10730 if [[ ${a_raid_working[10]} != '' ]];then
10731 bitmap_value='true'
10732 bitmap_value=" ${C1}bitmap${SEP3}${C2} $bitmap_value"
10735 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
10736 if [[ ${a_raid_working[5]} != '' ]];then
10737 u_data=" ${a_raid_working[5]}"
10739 if [[ ${a_raid_working[7]} != '' ]];then
10740 super_blocks=" ${C1}super blocks${SEP3}${C2} ${a_raid_working[7]}"
10742 if [[ ${a_raid_working[8]} != '' ]];then
10743 algorithm=" ${C1}algorithm${SEP3}${C2} ${a_raid_working[8]}"
10746 if [[ ${a_raid_working[3]} == '' ]];then
10747 if [[ ${a_raid_working[1]} != 'inactive' ]];then
10748 device_components='N/A'
10751 for component in ${a_raid_working[3]}
10753 if [[ $B_EXTRA_DATA != 'true' ]];then
10754 component=$( sed 's/\[[0-9]\+\]//' <<< $component )
10756 # NOTE: for bsd zfs, states are: ONLINE,DEGRADED,OFFLINE (at least)
10757 if [[ -n $( grep -E '(F|DEGRADED)' <<< $component ) ]];then
10758 component=$( sed -e 's/(F)//' -e 's/F//' -e 's/DEGRADED//' <<< $component )
10759 failed="$failed $component"
10761 elif [[ -n $( grep -E '(S|OFFLINE)' <<< $component ) ]];then
10762 component=$( sed -e 's/(S)//' -e 's/S//' -e 's/OFFLINE//' <<< $component )
10763 spare="$spare $component"
10766 device_components="$device_components$component_separator$component"
10767 component_separator=' '
10771 if [[ $failed != '' ]];then
10772 failed=" ${C1}FAILED${SEP3}${C2}$failed${C2}"
10774 if [[ $spare != '' ]];then
10775 spare=" ${C1}spare${SEP3}${C2}$spare${C2}"
10778 if [[ -n $device_components || -n $spare || -n $failed ]];then
10779 if [[ $B_EXTRA_DATA != 'true' && -z $BSD_TYPE ]];then
10780 if [[ $device_report != 'N/A' && -n $device_components ]];then
10781 device_components="$device_report - $device_components"
10784 if [[ $device_components == '' ]];then
10785 device_components='none'
10787 device_components="${C1}online${SEP3}${C2} $device_components"
10788 device_components=" ${C1}components${SEP3}${C2} $device_components$failed$spare"
10791 a_raid_data[$raid_counter]="${C1}Device$device_id${SEP3}${C2} $device$device_state$raid_level$device_components"
10793 if [[ $B_EXTRA_DATA == 'true' && ${a_raid_working[1]} != 'inactive' ]];then
10794 a_raid_data[$raid_counter]="${C1}Device$device_id${SEP3}${C2} $device$device_state$device_components"
10795 (( raid_counter++ ))
10796 print_string="${C1}Info${SEP3}${C2}$raid_level ${C1}$report_size${SEP3}${C2} $device_report$u_data"
10797 print_string="$print_string$blocks$chunk_size$bitmap_value$super_blocks$algorithm"
10798 a_raid_data[$raid_counter]="$print_string"
10800 a_raid_data[$raid_counter]="${C1}Device$device_id${SEP3}${C2} $device$device_state$raid_level$device_components"
10802 (( raid_counter++ ))
10804 # now let's do the recover line if required
10805 if [[ ${a_raid_working[12]} != '' ]];then
10806 recovery_percent=$( cut -d '~' -f 2 <<< ${a_raid_working[12]} )
10807 if [[ ${a_raid_working[14]} != '' ]];then
10808 finish_time=${a_raid_working[14]}
10812 finish_time=" ${C1}time remaining${SEP3}${C2} $finish_time"
10813 if [[ $B_EXTRA_DATA == 'true' ]];then
10814 if [[ ${a_raid_working[13]} != '' ]];then
10815 recovered_sectors=" ${C1}sectors${SEP3}${C2} ${a_raid_working[13]}"
10818 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
10819 if [[ ${a_raid_working[11]} != '' ]];then
10820 recovery_progress_bar=" ${a_raid_working[11]}"
10822 if [[ ${a_raid_working[15]} != '' ]];then
10823 recovery_speed=" ${C1}speed${SEP3}${C2} ${a_raid_working[15]}"
10827 a_raid_data[$raid_counter]="${C1}Recovering${SEP3}${C2} $recovery_percent$recovery_progress_bar$recovered_sectors$finish_time$recovery_speed"
10828 (( raid_counter++ ))
10831 elif [[ ${a_raid_working[0]} == 'KernelRaidSupport' ]];then
10832 if [[ ${a_raid_working[1]} == '' ]];then
10833 kernel_support='N/A'
10835 kernel_support=${a_raid_working[1]}
10837 kernel_support=" ${C1}supported${SEP3}${C2} $kernel_support"
10838 elif [[ ${a_raid_working[0]} == 'ReadAhead' ]];then
10839 if [[ ${a_raid_working[1]} != '' ]];then
10840 read_ahead=${a_raid_working[1]}
10841 read_ahead=" ${C1}read ahead${SEP3}${C2} $read_ahead"
10843 elif [[ ${a_raid_working[0]} == 'UnusedDevices' ]];then
10844 if [[ ${a_raid_working[1]} == '' ]];then
10845 unused_devices='N/A'
10847 unused_devices=${a_raid_working[1]}
10849 unused_devices="${C1}Unused Devices${SEP3}${C2} $unused_devices"
10850 elif [[ ${a_raid_working[0]} == 'raidEvent' ]];then
10851 if [[ ${a_raid_working[1]} != '' ]];then
10852 raid_event=${a_raid_working[1]}
10853 raid_event=" ${C1}Raid Event${SEP3}${C2} ${a_raid_working[1]}"
10858 if [[ $B_SHOW_BASIC_RAID == 'true' && $basic_raid != '' ]];then
10859 a_raid_data[0]="${C1}Device$basic_raid_plural${SEP3}${C2} $basic_raid"
10861 # note bsd temp test hack to make it run
10862 if [[ $B_MDSTAT_FILE != 'true' && -z $BSD_TYPE ]] || \
10863 [[ -n $BSD_TYPE && $B_BSD_RAID == 'false' ]];then
10864 if [[ $B_SHOW_RAID_R == 'true' ]];then
10865 a_raid_data[0]="$no_raid_detected"
10867 b_print_lines='false'
10870 if [[ ${a_raid_data[0]} == '' ]];then
10871 if [[ $B_SHOW_BASIC_RAID != 'true' ]];then
10872 a_raid_data[0]="$empty_raid_data"
10874 b_print_lines='false'
10877 # now let's add on the system line and the unused device line. Only print on -xx
10878 if [[ $kernel_support$read_ahead$raid_event != '' ]];then
10879 array_count=${#a_raid_data[@]}
10880 a_raid_data[array_count]="${C1}System${SEP3}${C2}$kernel_support$read_ahead$raid_event"
10883 if [[ $unused_devices != '' ]];then
10884 array_count_unused=${#a_raid_data[@]}
10885 a_raid_data[array_count_unused]="$unused_devices"
10890 # we don't want to print anything if it's -b and no data is present, just a waste of a line
10891 if [[ $b_print_lines == 'true' ]];then
10892 # print out all lines, line starter on first line
10893 for (( i=0; i < ${#a_raid_data[@]} - $loop_limit;i++ ))
10895 if [[ $i -eq 0 ]];then
10896 line_starter='RAID:'
10900 if [[ $B_EXTRA_EXTRA_DATA == 'true' && $array_count != '' ]];then
10901 if [[ $i == 0 ]];then
10902 raid_data=$( create_print_line "$line_starter" "${a_raid_data[array_count]}" )
10903 print_screen_output "$raid_data"
10907 raid_data=$( create_print_line "$line_starter" "${a_raid_data[i]}" )
10908 print_screen_output "$raid_data"
10909 if [[ $B_EXTRA_EXTRA_DATA == 'true' && $array_count_unused != '' ]];then
10910 if [[ $i == $(( array_count_unused - 2 )) ]];then
10911 raid_data=$( create_print_line "$line_starter" "${a_raid_data[array_count_unused]}" )
10912 print_screen_output "$raid_data"
10921 # currently only apt using distros support this feature, but over time we can add others
10925 local repo_count=0 repo_line='' file_name='' file_content='' file_name_holder=''
10926 local repo_full='' b_print_next_line='false' repo_type=''
10930 if [[ -n $REPO_DATA ]];then
10931 # loop through the variable's lines one by one, update counter each iteration
10932 while read repo_line
10935 repo_type=$( cut -d ':' -f 1 <<< $repo_line )
10936 file_name=$( cut -d ':' -f 2 <<< $repo_line )
10937 file_content=$( cut -d ':' -f 3-7 <<< $repo_line )
10938 # this will dump unwanted white space line starters. Some irc channels
10939 # use bots that show page title for urls, so need to break the url by adding
10941 if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
10942 file_content=$( echo $file_content | sed 's|://|: //|' )
10944 file_content=$( echo $file_content )
10946 # echo $file_name : $file_name_holder : $repo_type : $file_content
10947 # check file name, if different, update the holder for print out
10948 if [[ $file_name != $file_name_holder ]];then
10949 if [[ $repo_type == 'pisi repo' || $repo_type == 'urpmq repo' ]];then
10950 repo_full="${C1}$repo_type:${C2} $file_name"
10952 repo_full="${C1}Active $repo_type in file:${C2} $file_name"
10954 file_name_holder=$file_name
10955 b_print_next_line='true'
10957 repo_full=$file_content
10959 # first line print Repos:
10960 if [[ $repo_count -eq 1 ]];then
10961 repo_full=$( create_print_line "Repos:" "$repo_full" )
10963 repo_full=$( create_print_line " " "$repo_full" )
10965 print_screen_output "$repo_full"
10966 # this prints the content of the file as well as the file name
10967 if [[ $b_print_next_line == 'true' ]];then
10968 repo_full=$( create_print_line " " "$file_content" )
10969 print_screen_output "$repo_full"
10970 b_print_next_line='false'
10972 done <<< "$REPO_DATA"
10974 repo_full=$( create_print_line "Repos:" "${C1}Error:${C2} $SCRIPT_NAME does not support this feature for your distro yet." )
10975 print_screen_output "$repo_full"
10980 print_sensors_data()
10983 local mobo_temp='' cpu_temp='' psu_temp='' cpu_fan='' mobo_fan='' ps_fan='' sys_fans='' sys_fans2=''
10984 local temp_data='' fan_data='' fan_data2='' b_is_error='false' fan_count=0 gpu_temp=''
10985 local a_sensors_working=''
10986 local no_sensors_message='None detected - is lm-sensors installed and configured?'
10987 local Sensors_Data="$( get_sensors_output )"
10990 if [[ $BSD_TYPE == 'bsd' ]];then
10991 no_sensors_message='This feature is not yet supported for BSD systems.'
10995 a_sensors_working=( ${A_SENSORS_DATA[0]} )
10996 IFS="$ORIGINAL_IFS"
10997 # initial error cases, for missing app or unconfigured sensors. Note that array 0
10998 # always has at least 3 items, cpu/mobo/psu temp in it. If the count is 0, then
10999 # no sensors are installed/configured
11000 if [[ ${#a_sensors_working[@]} -eq 0 ]];then
11001 cpu_temp=$no_sensors_message
11004 for (( i=0; i < ${#A_SENSORS_DATA[@]}; i++ ))
11007 a_sensors_working=( ${A_SENSORS_DATA[i]} )
11008 IFS="$ORIGINAL_IFS"
11010 # first the temp data
11012 if [[ -n ${a_sensors_working[0]} ]];then
11013 cpu_temp=${a_sensors_working[0]}
11017 cpu_temp="${C1}System Temperatures: cpu$SEP3${C2} $cpu_temp "
11019 if [[ -n ${a_sensors_working[1]} ]];then
11020 mobo_temp=${a_sensors_working[1]}
11024 mobo_temp="${C1}mobo$SEP3${C2} $mobo_temp "
11026 if [[ -n ${a_sensors_working[2]} ]];then
11027 psu_temp="${C1}psu$SEP3${C2} ${a_sensors_working[2]} "
11029 gpu_temp=$( get_gpu_temp_data )
11030 # dump the unneeded screen data for single gpu systems
11031 if [[ $( wc -w <<< $gpu_temp ) -eq 1 && $B_EXTRA_DATA != 'true' ]];then
11032 gpu_temp=$( cut -d ':' -f 2 <<< $gpu_temp )
11034 if [[ -n $gpu_temp ]];then
11035 gpu_temp="${C1}gpu$SEP3${C2} ${gpu_temp} "
11038 # then the fan data from main fan array
11040 for (( j=0; j < ${#a_sensors_working[@]}; j++ ))
11044 # we need to make sure it's either cpu fan OR cpu fan and sys fan 1
11045 if [[ -n ${a_sensors_working[0]} ]];then
11046 cpu_fan="${a_sensors_working[0]}"
11047 elif [[ -z ${a_sensors_working[0]} && -n ${a_sensors_working[1]} ]];then
11048 cpu_fan="${a_sensors_working[1]}"
11052 cpu_fan="${C1}Fan Speeds (in rpm): cpu$SEP3${C2} $cpu_fan "
11056 if [[ -n ${a_sensors_working[1]} ]];then
11057 mobo_fan="${C1}mobo$SEP3${C2} ${a_sensors_working[1]} "
11062 if [[ -n ${a_sensors_working[2]} ]];then
11063 ps_fan="${C1}psu$SEP3${C2} ${a_sensors_working[2]} "
11068 if [[ -n ${a_sensors_working[$j]} ]];then
11069 fan_number=$(( $j - 2 )) # sys fans start on array key 5
11070 # wrap after fan 6 total
11071 if [[ $fan_count -lt 7 ]];then
11072 sys_fans="$sys_fans${C1}sys-$fan_number$SEP3${C2} ${a_sensors_working[$j]} "
11074 sys_fans2="$sys_fans2${C1}sys-$fan_number$SEP3${C2} ${a_sensors_working[$j]} "
11083 for (( j=0; j < ${#a_sensors_working[@]}; j++ ))
11087 if [[ -n ${a_sensors_working[$j]} ]];then
11088 fan_number=$(( $j + 1 )) # sys fans start on array key 5
11089 # wrap after fan 6 total
11090 if [[ $fan_count -lt 7 ]];then
11091 sys_fans="$sys_fans${C1}fan-$fan_number$SEP3${C2} ${a_sensors_working[$j]} "
11093 sys_fans2="$sys_fans2${C1}fan-$fan_number$SEP3${C2} ${a_sensors_working[$j]} "
11104 # turning off all output for case where no sensors detected or no sensors output
11105 # unless -s used explicitly. So for -F type output won't show unless valid or -! 1 used
11106 if [[ $b_is_error != 'true' || $B_SHOW_SENSORS == 'true' || $B_TESTING_1 == 'true' ]];then
11107 temp_data="$cpu_temp$mobo_temp$psu_temp$gpu_temp"
11108 temp_data=$( create_print_line "Sensors:" "$temp_data" )
11109 print_screen_output "$temp_data"
11110 # don't print second or subsequent lines if error data
11111 fan_data="$cpu_fan$mobo_fan$ps_fan$sys_fans"
11112 if [[ $b_is_error != 'true' && -n $fan_data ]];then
11113 fan_data=$( create_print_line " " "$fan_data" )
11114 print_screen_output "$fan_data"
11115 # and then second wrapped fan line if needed
11116 if [[ -n $sys_fans2 ]];then
11117 fan_data2=$( create_print_line " " "$sys_fans2" )
11118 print_screen_output "$fan_data2"
11125 print_system_data()
11128 local system_data='' bits='' desktop_environment='' dm_data='' de_extra_data=''
11129 local host_kernel_string='' de_distro_string='' host_string='' desktop_type='Desktop'
11130 local host_name=$HOSTNAME
11131 local current_kernel=$( get_kernel_version )
11132 local distro="$( get_distro_data )"
11133 local tty_session=''
11135 # I think these will work, maybe, if logged in as root and in X
11136 if [[ $B_RUNNING_IN_DISPLAY == 'true' ]];then
11137 desktop_environment=$( get_desktop_environment )
11138 if [[ -z $desktop_environment ]];then
11139 desktop_environment='N/A'
11142 if [[ $B_EXTRA_EXTRA_EXTRA_DATA == 'true' ]];then
11143 de_extra_data=$( get_desktop_extra_data )
11144 if [[ -n $de_extra_data ]];then
11145 de_extra_data=" ${C1}info$SEP3${C2} $de_extra_data"
11149 tty_session=$( get_tty_number )
11150 if [[ -z $tty_session && $B_CONSOLE_IRC == 'true' ]];then
11151 tty_session=$( get_tty_console_irc )
11153 if [[ -n $tty_session ]];then
11154 tty_session=" $tty_session"
11156 desktop_environment="tty$tty_session"
11157 desktop_type='Console'
11159 # having dm type can be useful if you are accessing remote system
11160 # or are out of X and don't remember which dm is running the system
11161 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
11162 dm_data=$( get_display_manager )
11163 # here we only want the dm info to show N/A if in X
11164 if [[ -z $dm_data && $B_RUNNING_IN_DISPLAY == 'true' ]];then
11167 # only print out of X if dm_data has info, then it's actually useful, but
11168 # for headless servers, no need to print dm stuff.
11169 if [[ -n $dm_data ]];then
11170 dm_data=" ${C1}dm$SEP3${C2} $dm_data"
11174 de_distro_string="${C1}$desktop_type$SEP3${C2} $desktop_environment$de_extra_data$dm_data ${C1}Distro$SEP3${C2} $distro"
11175 if [[ $B_EXTRA_DATA == 'true' ]];then
11176 gcc_string=$( get_gcc_kernel_version )
11177 if [[ -n $gcc_string ]];then
11178 gcc_string=", ${C1}gcc$SEP3${C2} $gcc_string"
11181 # check for 64 bit first
11182 if [[ -n $( uname -m | grep -E '(x86_64|amd64)' ) ]];then
11187 bits=" (${bits} bit${gcc_string})"
11188 if [[ $B_SHOW_HOST == 'true' ]];then
11189 if [[ -z $HOSTNAME ]];then
11190 if [[ -n $( type p hostname ) ]];then
11191 host_name=$( hostname )
11193 if [[ -z $host_name ]];then
11197 host_string="${C1}Host$SEP3${C2} $host_name "
11198 system_data=$( create_print_line "System:" "$host_string$host_name ${C1}Kernel$SEP3${C2}" )
11200 host_kernel_string="$host_string${C1}Kernel$SEP3${C2} $current_kernel$bits "
11201 if [[ $( calculate_line_length "$host_kernel_string$de_distro_string" ) -lt $COLS_INNER ]];then
11202 system_data="$host_kernel_string$de_distro_string"
11203 system_data=$( create_print_line "System:" "$system_data" )
11205 system_data=$( create_print_line "System:" "$host_kernel_string" )
11206 print_screen_output "$system_data"
11207 system_data=$( create_print_line " " "$de_distro_string" )
11209 print_screen_output "$system_data"
11213 print_unmounted_partition_data()
11216 local a_unmounted_data='' line_starter='' unmounted_data='' full_fs=''
11217 local full_dev='' full_size='' full_label='' full_uuid='' full_string=''
11218 local bsd_unsupported='This feature is not yet supported for BSD systems.'
11220 if [[ -z ${A_PARTITION_DATA} ]];then
11223 get_unmounted_partition_data
11225 if [[ ${#A_UNMOUNTED_PARTITION_DATA[@]} -ge 1 ]];then
11226 for (( i=0; i < ${#A_UNMOUNTED_PARTITION_DATA[@]}; i++ ))
11229 a_unmounted_data=(${A_UNMOUNTED_PARTITION_DATA[i]})
11230 IFS="$ORIGINAL_IFS"
11231 if [[ -z ${a_unmounted_data[0]} ]];then
11234 full_dev="/dev/${a_unmounted_data[0]}"
11236 full_dev="${C1}ID:${C2} $full_dev"
11237 if [[ -z ${a_unmounted_data[1]} ]];then
11240 full_size=${a_unmounted_data[1]}
11242 full_size="${C1}size$SEP3${C2} $full_size"
11243 if [[ -z ${a_unmounted_data[2]} ]];then
11246 full_label=${a_unmounted_data[2]}
11248 full_label="${C1}label$SEP3${C2} $full_label"
11249 if [[ -z ${a_unmounted_data[3]} ]];then
11252 full_uuid=${a_unmounted_data[3]}
11254 full_uuid="${C1}uuid$SEP3${C2} $full_uuid"
11255 if [[ -z ${a_unmounted_data[4]} ]];then
11258 full_fs="${C1}fs$SEP3${C2} ${a_unmounted_data[4]}"
11260 full_string="$full_dev $full_size $full_label $full_uuid $full_fs"
11261 if [[ $i -eq 0 ]];then
11262 line_starter='Unmounted:'
11266 # temporary message to indicate not yet supported
11267 if [[ $BSD_TYPE == 'bsd' ]];then
11268 full_string=$bsd_unsupported
11270 unmounted_data=$( create_print_line "$line_starter" "$full_string" )
11271 print_screen_output "$unmounted_data"
11274 unmounted_data=$( create_print_line "Unmounted:" "No unmounted partitions detected" )
11275 print_screen_output "$unmounted_data"
11281 print_weather_data()
11285 local weather_data='' location_string='' local_time='' time_string='' pressure=''
11286 local a_location='' a_weather='' weather_string='' weather='' temp='' winds='' humidity=''
11287 local time_zone='' observation_time='' city='' state='' country='' altitude=''
11288 local heat_index="" wind_chill='' dewpoint='' xxx_humidity=''
11289 local openP='(' closeP=')'
11291 if [[ $B_RUNNING_IN_SHELL == 'false' ]];then
11298 # city ";" regionCode ";" regionName ";" countryName ";" countryCode ";" countryCode3
11299 # ";" latitude "," longitude ";" postalCode ";" timeZone
11301 # observationTime ";" localTime ";" weather ";" tempString ";" humidity
11302 # ";" windString ";" pressureString ";" dewpointString ";" heatIndexString
11303 # ";" windChillString ";" siteElevation
11305 if [[ ${#A_WEATHER_DATA[@]} -eq 2 ]];then
11307 a_location=(${A_WEATHER_DATA[0]})
11308 a_weather=(${A_WEATHER_DATA[1]})
11309 IFS="$ORIGINAL_IFS"
11311 if [[ -n ${a_weather[3]} ]];then
11312 temp=${a_weather[3]}
11316 if [[ -n ${a_weather[2]} ]];then
11317 weather=" - ${a_weather[2]}"
11321 if [[ $B_EXTRA_DATA == 'true' ]];then
11322 if [[ -n ${a_weather[5]} ]];then
11323 winds=" ${C1}Wind$SEP3${C2} ${a_weather[5]}"
11326 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
11327 if [[ -n ${a_weather[4]} ]];then
11328 humidity=" ${C1}Humidity$SEP3${C2} ${a_weather[4]}"
11330 if [[ -n ${a_weather[6]} ]];then
11331 pressure="${C1}Pressure$SEP3${C2} ${a_weather[6]} "
11334 weather_string="${C1}Conditions$SEP3${C2} $temp$weather$winds$humidity"
11336 if [[ -n ${a_weather[1]} ]];then
11337 local_time=" ${a_weather[1]}"
11339 local_time=" $(date)"
11341 if [[ $B_EXTRA_DATA == 'true' && -n ${a_location[8]} ]];then
11342 time_zone=" (${a_location[8]})"
11344 time_string="${C1}Time$SEP3${C2}$local_time$time_zone"
11346 if [[ $B_EXTRA_DATA != 'true' ]];then
11347 weather_data="$weather_string $time_string"
11348 weather_data=$( create_print_line "Weather:" "$weather_data" )
11349 print_screen_output "$weather_data"
11351 weather_data="$weather_string"
11352 weather_data=$( create_print_line "Weather:" "$weather_data" )
11353 print_screen_output "$weather_data"
11354 if [[ $B_EXTRA_EXTRA_EXTRA_DATA == 'true' ]];then
11355 if [[ -n ${a_weather[8]} ]];then
11356 heat_index="${C1}Heat Index$SEP3${C2} ${a_weather[8]} "
11358 if [[ -n ${a_weather[9]} ]];then
11359 wind_chill="${C1}Wind Chill$SEP3${C2} ${a_weather[9]} "
11361 if [[ -n ${a_weather[7]} ]];then
11362 dew_point="${C1}Dew Point$SEP3${C2} ${a_weather[7]} "
11364 if [[ -n ${a_weather[0]} ]];then
11365 observation_time=" ${C1}Observation Time$SEP3${C2} ${a_weather[0]} "
11367 if [[ $B_OUTPUT_FILTER != 'true' ]];then
11368 if [[ -n ${a_location[0]} ]];then
11369 city=" ${a_location[0]}"
11371 if [[ -n ${a_location[1]} ]];then
11372 state=" ${a_location[1]}"
11374 if [[ -n ${a_location[5]} ]];then
11375 country=" $openP${a_location[5]}$closeP"
11377 if [[ -n ${a_weather[10]} ]];then
11378 altitude=" ${C1}Altitude$SEP3${C2} ${a_weather[10]}"
11380 location_string="${C1}Location$SEP3${C2}$city$state$country$altitude "
11382 location_string=$time_string$observation_time
11384 observation_time=''
11386 # the last three are oftenblank
11387 if [[ -z "$heat_index$wind_chill$dew_point" ]];then
11388 weather_data=$( create_print_line " " "$pressure$location_string" )
11389 print_screen_output "$weather_data"
11391 weather_data=$( create_print_line " " "$pressure$heat_index$wind_chill$dew_point" )
11392 print_screen_output "$weather_data"
11393 if [[ $B_OUTPUT_FILTER != 'true' ]];then
11394 weather_data=$( create_print_line " " "$location_string" )
11395 print_screen_output "$weather_data"
11398 if [[ -n $time_string$observation_time ]];then
11399 weather_data=$( create_print_line " " "$time_string$observation_time" )
11400 print_screen_output "$weather_data"
11403 if [[ -n $pressure$time_string ]];then
11404 weather_data="$pressure$time_string"
11405 weather_data=$( create_print_line " " "$weather_data" )
11406 print_screen_output "$weather_data"
11411 weather_data=$( create_print_line "Weather:" "Weather data failure: $(date)" )
11412 print_screen_output "$weather_data"
11413 weather_data=$( create_print_line " " "${A_WEATHER_DATA}" )
11414 print_screen_output "$weather_data"
11419 ########################################################################
11420 #### SCRIPT EXECUTION
11421 ########################################################################
11423 main $@ ## From the End comes the Beginning
11425 ## note: this EOF is needed for smxi handling, this is what triggers the full download ok