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 ## sometimes will trigger an error (mageia) if not in shell
498 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
499 if [[ -n $( type -p tput ) ]];then
500 TERM_COLUMNS=$(tput cols)
501 TERM_LINES=$(tput lines)
503 # double check, just in case it's missing functionality or whatever
504 if [[ -n ${TERM_COLUMNS##[0-9]*} ]];then
510 # Only for legacy user config files se we can test and convert the var name
515 # Defaults to 2, make this 1 for normal, 0 for no colorcodes at all. Use following variables in config
516 # files to change defaults for each type, or global
517 # Same as runtime parameter.
518 DEFAULT_COLOR_SCHEME=2
519 ## color variables - set dynamically
524 ## Always leave these blank, these are only going to be set in inxi.conf files, that makes testing
525 ## for user changes easier after sourcing the files
526 GLOBAL_COLOR_SCHEME=''
528 IRC_CONS_COLOR_SCHEME=''
529 IRC_X_TERM_COLOR_SCHEME=''
530 CONSOLE_COLOR_SCHEME=''
531 VIRT_TERM_COLOR_SCHEME=''
534 # A more elegant way to have a scheme that doesn't print color codes (neither ANSI nor mIRC) at all. See below.
536 # DGREY BLACK RED DRED GREEN DGREEN YELLOW DYELLOW
537 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"
538 IRC_COLORS=" \x0314 \x0301 \x0304 \x0305 \x0309 \x0303 \x0308 \x0307"
539 # BLUE DBLUE MAGENTA DMAGENTA CYAN DCYAN WHITE GREY NORMAL
540 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"
541 IRC_COLORS=" $IRC_COLORS \x0312 \x0302 \x0313 \x0306 \x0311 \x0310 \x0300 \x0315 \x03"
543 #ANSI_COLORS=($ANSI_COLORS); IRC_COLORS=($IRC_COLORS)
544 A_COLORS_AVAILABLE=( DGREY BLACK RED DRED GREEN DGREEN YELLOW DYELLOW BLUE DBLUE MAGENTA DMAGENTA CYAN DCYAN WHITE GREY NORMAL )
546 # See above for notes on EMPTY
547 ## note: group 1: 0, 1 are null/normal
548 ## Following: group 2: generic, light/dark or dark/light; group 3: dark on light; group 4 light on dark;
549 # this is the count of the first two groups, starting at zero
561 DYELLOW,NORMAL,NORMAL
564 MAGENTA,NORMAL,NORMAL
569 DBLUE,DMAGENTA,NORMAL
572 DGREEN,DYELLOW,NORMAL
574 DMAGENTA,BLACK,NORMAL
584 MAGENTA,YELLOW,NORMAL
590 # WARNING: In the main part below (search for 'KONVI')
591 # there's a check for Konversation-specific config files.
592 # Any one of these can override the above if inxi is run
596 # In cases of derived distros where the version file of the base distro can also be found under /etc,
597 # the derived distro's version file should go first. (Such as with Sabayon / Gentoo)
598 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"
599 # debian_version excluded from DISTROS_PRIMARY so Debian can fall through to /etc/issue detection. Same goes for Ubuntu.
600 DISTROS_EXCLUDE_LIST="debian_version ubuntu_version"
601 DISTROS_PRIMARY="arch-release gentoo-release redhat-release slackware-version SuSE-release"
602 DISTROS_LSB_GOOD="mandrake-release mandriva-release mandrakelinux-release"
603 # this is being used both by core distros and derived distros now, eg, solusos 1 uses it for solusos id, while
604 # debian, solusos base, uses it as well, so we have to know which it is.
605 DISTROS_OS_RELEASE_GOOD="arch-release SuSE-release"
606 ## Distros with known problems
607 # DSL (Bash 2.05b: grep -m doesn't work; arrays won't work) --> unusable output
608 # Puppy Linux 4.1.2 (Bash 3.0: arrays won't work) --> works partially
610 ## OUTPUT FILTERS/SEARCH ##
611 # Note that \<ltd\> bans only words, not parts of strings; in \<corp\> you can't use punctuation characters like . or ,
612 # we're saving about 10+% of the total script exec time by hand building the ban lists here, using hard quotes.
613 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 ..\)'
614 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]'
616 SENSORS_GPU_SEARCH='intel|radeon|nouveau'
618 ### USB networking search string data, because some brands can have other products than
619 ### wifi/nic cards, they need further identifiers, with wildcards.
620 ### putting the most common and likely first, then the less common, then some specifics
621 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"
622 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"
623 # then a few known hard to ID ones added
624 # belkin=050d; d-link=07d1; netgear=0846; ralink=148f; realtek=0bda;
625 USB_NETWORK_SEARCH="$USB_NETWORK_SEARCH|050d:935b|0bda:8189|0bda:8197"
627 ########################################################################
628 #### MAIN: Where it all begins
629 ########################################################################
634 local color_scheme=''
635 # this will be used by all functions following
636 local Ps_aux_Data="$( ps aux )"
638 # This function just initializes variables
641 # Source global config overrides, needs to be here because some things
642 # can be reset that were set in initialize, but check_required_apps needs
643 if [[ -s /etc/$SCRIPT_NAME.conf ]];then
644 source /etc/$SCRIPT_NAME.conf
646 # Source user config variables override /etc/inxi.conf variables
647 if [[ -s $HOME/.$SCRIPT_NAME/$SCRIPT_NAME.conf ]];then
648 source $HOME/.$SCRIPT_NAME/$SCRIPT_NAME.conf
650 # Convert to new variable names if set in config files, legacy test
651 if [[ -n $LINE_MAX_CONSOLE ]];then
652 COLS_MAX_CONSOLE=$LINE_MAX_CONSOLE
654 if [[ -n $LINE_MAX_IRC ]];then
655 COLS_MAX_IRC=$LINE_MAX_IRC
657 # TERM_COLUMNS is set in top globals, using tput cols
658 if [[ $TERM_COLUMNS -lt $COLS_MAX_CONSOLE ]];then
659 COLS_MAX_CONSOLE=$TERM_COLUMNS
661 # adjust, some terminals will wrap if output cols == term cols
662 COLS_MAX_CONSOLE=$(( $COLS_MAX_CONSOLE - 2 ))
664 # comes after source for user set stuff
665 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
666 COLS_MAX=$COLS_MAX_CONSOLE
669 # too hard to read if no colors, so force that for users on irc
670 if [[ $SCHEME == 0 ]];then
675 COLS_MAX=$COLS_MAX_IRC
678 COLS_INNER=$(( $COLS_MAX - $INDENT - 1 ))
679 # Check for dependencies BEFORE running ANYTHING else except above functions
680 # Not all distro's have these depends installed by default. Don't want to run
681 # this if the user is requesting to see this information in the first place
682 # Only continue if required apps tests ok
683 if [[ $1 != '--recommends' ]];then
685 check_recommended_apps
688 SCRIPT_VERSION_NUMBER=$( parse_version_data 'main' )
689 SCRIPT_PATCH_NUMBER=$( parse_version_data 'patch' )
691 # previous source location, check for bugs
693 ## this needs to run before the KONVI stuff is set below
694 ## Konversation 1.2 apparently does not like the $PPID test in get_start_client
695 ## So far there is no known way to detect if qt4_konvi is the parent process
696 ## this method will infer qt4_konvi as parent
699 # note: this only works if it's run from inside konversation as a script builtin or something
700 # only do this if inxi has been started as a konversation script, otherwise bypass this
701 # KONVI=3 ## for testing puroses
702 if [[ $KONVI -eq 1 || $KONVI -eq 3 ]];then
703 if [[ $KONVI -eq 1 ]]; then ## dcop Konversation (ie 1.x < 1.2(qt3))
708 elif [[ $KONVI -eq 3 ]]; then ## dbus Konversation (> 1.2 (qt4))
709 DCSERVER="$1" ##dbus testing
710 DCTARGET="$2" ##dbus testing
714 # The section below is on request of Argonel from the Konversation developer team:
715 # it sources config files like $HOME/.kde/share/apps/konversation/scripts/inxi.conf
717 for kde_config in $( kde-config --path data )
719 if [[ -r ${kde_config}${KONVI_CFG} ]];then
720 source "${kde_config}${KONVI_CFG}"
727 ## leave this for debugging dcop stuff if we get that working
728 # print_screen_output "DCPORT: $DCPORT"
729 # print_screen_output "DCSERVER: $DCSERVER"
730 # print_screen_output "DCTARGET: $DCTARGET"
732 # first init function must be set first for colors etc. Remember, no debugger
733 # stuff works on this function unless you set the debugging flag manually.
734 # Debugging flag -@ [number] will not work until get_parameters runs.
736 # "$@" passes every parameter separately quoted, "$*" passes all parameters as one quoted parameter.
737 # must be here to allow debugger and other flags to be set.
740 # If no colorscheme was set in the parameter handling routine, then set the default scheme
741 if [[ $B_COLOR_SCHEME_SET != 'true' ]];then
742 # This let's user pick their color scheme. For IRC, only shows the color schemes, no interactive
743 # The override value only will be placed in user config files. /etc/inxi.conf can also override
744 if [[ $B_RUN_COLOR_SELECTOR == 'true' ]];then
745 select_default_color_scheme
747 # set the default, then override as required
748 color_scheme=$DEFAULT_COLOR_SCHEME
749 if [[ -n $GLOBAL_COLOR_SCHEME ]];then
750 color_scheme=$GLOBAL_COLOR_SCHEME
752 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
753 if [[ -n $CONSOLE_COLOR_SCHEME && -z $DISPLAY ]];then
754 color_scheme=$CONSOLE_COLOR_SCHEME
755 elif [[ -n $VIRT_TERM_COLOR_SCHEME ]];then
756 color_scheme=$VIRT_TERM_COLOR_SCHEME
759 if [[ -n $IRC_X_TERM_COLOR_SCHEME && $B_CONSOLE_IRC == 'true' && -n $B_RUNNING_IN_DISPLAY ]];then
760 color_scheme=$IRC_X_TERM_COLOR_SCHEME
761 elif [[ -n $IRC_CONS_COLOR_SCHEME && -z $DISPLAY ]];then
762 color_scheme=$IRC_CONS_COLOR_SCHEME
763 elif [[ -n $IRC_COLOR_SCHEME ]];then
764 color_scheme=$IRC_COLOR_SCHEME
768 set_color_scheme $color_scheme
772 # all the pre-start stuff is in place now
774 script_debugger "Debugger: $SCRIPT_NAME is up and running..."
776 # then create the output
780 if [[ $B_RUNNING_IN_SHELL == 'true' && $SCHEME -gt 0 ]];then
784 # weechat's executor plugin forced me to do this, and rightfully so, because else the exit code
785 # from the last command is taken..
789 #### -------------------------------------------------------------------
790 #### basic tests: set script data, booleans, PATH, version numbers
791 #### -------------------------------------------------------------------
793 # Set PATH data so we can access all programs as user. Set BAN lists.
794 # initialize some boleans, these directories are used throughout the script
795 # some apps are used for extended functions any directory used, should be
796 # checked here first.
801 BSD_VERSION=$( uname -s 2>/dev/null | tr '[A-Z]' '[a-z]' )
803 # note: archbsd says they are a freebsd distro, so assuming it's the same as freebsd
804 if [[ -n $( grep 'bsd' <<< "$BSD_VERSION" ) ]];then
805 # GNU/kfreebsd will by definition have GNU tools like sed/grep
806 if [[ -n $( grep 'kfreebsd' <<< "$BSD_VERSION" ) ]];then
807 BSD_TYPE='debian-bsd' # debian gnu bsd
809 BSD_TYPE='bsd' # all other bsds
814 # now set the script BOOLEANS for files required to run features
815 # note that freebsd has /proc but it's empty
816 if [[ -d "/proc/" && -z $BSD_TYPE ]];then
818 elif [[ -n $BSD_TYPE ]];then
826 if [[ -n $BSD_TYPE ]];then
827 if [[ -e $FILE_DMESG_BOOT ]];then
828 B_DMESG_BOOT_FILE='true'
831 # found a case of battery existing but having nothing in it on desktop mobo
832 # not all laptops show the first,
833 if [[ -n $( ls /proc/acpi/battery 2>/dev/null ) ]];then
839 if [[ -e $FILE_CPUINFO ]]; then
840 B_CPUINFO_FILE='true'
843 if [[ -e $FILE_MEMINFO ]];then
844 B_MEMINFO_FILE='true'
847 if [[ -e $FILE_ASOUND_DEVICE ]];then
848 B_ASOUND_DEVICE_FILE='true'
851 if [[ -e $FILE_ASOUND_VERSION ]];then
852 B_ASOUND_VERSION_FILE='true'
855 if [[ -f $FILE_LSB_RELEASE ]];then
859 if [[ -f $FILE_OS_RELEASE ]];then
860 B_OS_RELEASE_FILE='true'
863 if [[ -e $FILE_SCSI ]];then
867 if [[ -n $DISPLAY ]];then
868 B_SHOW_DISPLAY_DATA='true'
869 B_RUNNING_IN_DISPLAY='true'
872 if [[ -e $FILE_MDSTAT ]];then
876 if [[ -e $FILE_MODULES ]];then
877 B_MODULES_FILE='true'
880 if [[ -e $FILE_MOUNTS ]];then
884 if [[ -e $FILE_PARTITIONS ]];then
885 B_PARTITIONS_FILE='true'
887 # default to the normal location, then search for it
888 if [[ -e $FILE_XORG_LOG ]];then
891 # Detect location of the Xorg log file
892 if [[ -n $( type -p xset ) ]]; then
893 FILE_XORG_LOG=$( xset q 2>/dev/null | grep -i 'Log file' | gawk '{print $3}')
894 if [[ -e $FILE_XORG_LOG ]];then
899 # gfx output will require this flag
900 if [[ $( whoami ) == 'root' ]];then
906 # arg: $1 - version number: main/patch/date
909 local version_data=''
911 # note, using ####[[:space:]]+ to avoid having this function also trip the version datas
914 version_data="$( gawk -F ': ' '
915 /####[[:space:]]+Date:/ {
917 }' $SCRIPT_PATH/$SCRIPT_NAME )"
920 version_data="$( gawk '
921 /####[[:space:]]+Version:/ {
923 }' $SCRIPT_PATH/$SCRIPT_NAME )"
926 version_data="$( gawk '
927 /####[[:space:]]+Patch Number:/ {
929 }' $SCRIPT_PATH/$SCRIPT_NAME )"
937 local path='' added_path='' b_path_found='' sys_path=''
938 # Extra path variable to make execute failures less likely, merged below
939 local extra_paths="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
941 # this needs to be set here because various options call the parent initialize function directly.
942 SCRIPT_PATH=$( dirname $0 )
944 # Fallback paths put into $extra_paths; This might, among others, help on gentoo.
945 # Now, create a difference of $PATH and $extra_paths and add that to $PATH:
947 for path in $extra_paths
950 for sys_path in $PATH
952 if [[ $path == $sys_path ]];then
956 if [[ $b_path_found == 'false' ]];then
957 added_path="$added_path:$path"
962 PATH="${PATH}${added_path}"
963 ##echo "PATH='$PATH'"
964 ##/bin/sh -c 'echo "PATH in subshell=\"$PATH\""'
968 check_recommended_apps()
971 local bash_array_test=( "one" "two" )
973 # check for array ability of bash, this is only good for the warning at this time
974 # the boolean could be used later
975 # bash version 2.05b is used in DSL
976 # bash version 3.0 is used in Puppy Linux; it has a known array bug <reference to be placed here>
977 # versions older than 3.1 don't handle arrays
978 # distro's using below 2.05b are unknown, released in 2002
979 if [[ ${bash_array_test[1]} -eq "two" ]];then
982 script_debugger "Suggestion: update to Bash v3.1 for optimal inxi output"
984 # test for a few apps that bsds may not have after initial tests
985 if [[ -n $( type -p lspci ) ]];then
988 if [[ -n $BSD_TYPE ]];then
989 if [[ -n $( type -p sysctl ) ]];then
992 if [[ -n $( type -p pciconf ) ]];then
996 # now setting qdbus/dcop for first run, some systems can have both by the way
997 if [[ -n $( type -p qdbus ) ]];then
1000 if [[ -n $( type -p dcop ) ]];then
1006 # Determine if any of the absolutely necessary tools are absent
1008 check_required_apps()
1011 local app_name='' app_path=''
1012 # bc removed from deps for now
1013 local depends="df gawk grep ps readlink tr uname uptime wc"
1015 if [[ -z $BSD_TYPE ]];then
1016 depends="$depends lspci"
1017 elif [[ $BSD_TYPE == 'bsd' ]];then
1018 depends="$depends sysctl"
1019 # debian-bsd has lspci but you must be root to run it
1020 elif [[ $BSD_TYPE == 'debian-bsd' ]];then
1021 depends="$depends sysctl lspci"
1023 # no need to add xprop because it will just give N/A if not there, but if we expand use of xprop,
1024 # should add that here as a test, then use the B_SHOW_DISPLAY_DATA flag to trigger the tests in de function
1025 local x_apps="xrandr xdpyinfo glxinfo"
1027 if [[ $B_RUNNING_IN_DISPLAY == 'true' ]];then
1028 for app_name in $x_apps
1030 app_path=$( type -p $app_name )
1031 if [[ -z $app_path ]];then
1032 script_debugger "Resuming in non X mode: $app_name not found. For package install advice run: $SCRIPT_NAME --recommends"
1033 B_SHOW_DISPLAY_DATA='false'
1041 for app_name in $depends
1043 app_path=$( type -p $app_name )
1044 if [[ -z $app_path ]];then
1045 error_handler 5 "$app_name"
1051 ## note: this is now running inside each gawk sequence directly to avoid exiting gawk
1052 ## looping in bash through arrays, then re-entering gawk to clean up, then writing back to array
1053 ## in bash. For now I'll leave this here because there's still some interesting stuff to get re methods
1054 # Enforce boilerplate and buzzword filters
1055 # args: $1 - BAN_LIST_NORMAL/BAN_LIST_CPU; $2 - string to sanitize
1056 sanitize_characters()
1059 # Cannot use strong quotes to unquote a string with pipes in it!
1060 # bash will interpret the |'s as usual and try to run a subshell!
1061 # Using weak quotes instead, or use '"..."'
1068 gsub(/ [ ]+/,\" \") ## ([ ]+) with (space)
1069 gsub(/^ +| +$/,\"\") ## (pipe char) with (nothing)
1070 print ## prints (returns) cleaned input
1075 # Set the colorscheme
1076 # args: $1 = <scheme number>|<"none">
1080 local i='' a_output_colors='' a_color_codes=''
1082 if [[ $1 -ge ${#A_COLOR_SCHEMES[@]} ]];then
1085 # Set a global variable to allow checking for chosen scheme later
1087 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1088 a_color_codes=( $ANSI_COLORS )
1090 a_color_codes=( $IRC_COLORS )
1092 for (( i=0; i < ${#A_COLORS_AVAILABLE[@]}; i++ ))
1094 eval "${A_COLORS_AVAILABLE[i]}=\"${a_color_codes[i]}\""
1097 a_output_colors=( ${A_COLOR_SCHEMES[$1]} )
1099 # then assign the colors globally
1100 C1="${!a_output_colors[0]}"
1101 C2="${!a_output_colors[1]}"
1102 CN="${!a_output_colors[2]}"
1103 # ((COLOR_SCHEME++)) ## note: why is this? ##
1107 select_default_color_scheme()
1110 local spacer=' ' options='' user_selection='' config_variable=''
1111 local config_file="$HOME/.$SCRIPT_NAME/$SCRIPT_NAME.conf"
1112 local irc_clear="
\e[0m"
1113 local irc_gui='Unset' irc_console='Unset' irc_x_term='Unset'
1114 local console='Unset' virt_term='Unset' global='Unset'
1116 if [[ -n $IRC_COLOR_SCHEME ]];then
1117 irc_gui="Set: $IRC_COLOR_SCHEME"
1119 if [[ -n $IRC_CONS_COLOR_SCHEME ]];then
1120 irc_console="Set: $IRC_CONS_COLOR_SCHEME"
1122 if [[ -n $IRC_X_TERM_COLOR_SCHEME ]];then
1123 irc_x_term="Set: $IRC_X_TERM_COLOR_SCHEME"
1125 if [[ -n $VIRT_TERM_COLOR_SCHEME ]];then
1126 virt_term="Set: $VIRT_TERM_COLOR_SCHEME"
1128 if [[ -n $CONSOLE_COLOR_SCHEME ]];then
1129 console="Set: $CONSOLE_COLOR_SCHEME"
1131 if [[ -n $GLOBAL_COLOR_SCHEME ]];then
1132 global="Set: $GLOBAL_COLOR_SCHEME"
1135 # don't want these printing in irc since they show literally
1136 if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
1139 # first make output neutral so it's just plain default for console client
1140 set_color_scheme "0"
1141 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1142 print_screen_output "Welcome to $SCRIPT_NAME! Please select the default $COLOR_SELECTION color scheme."
1143 # print_screen_output "You will see this message only one time per user account, unless you set preferences in: /etc/$SCRIPT_NAME.conf"
1144 print_screen_output " "
1146 print_screen_output "Because there is no way to know your $COLOR_SELECTION foreground/background colors, you can"
1147 print_screen_output "set your color preferences from color scheme option list below. 0 is no colors, 1 neutral."
1148 print_screen_output "After these, there are 3 sets: 1-dark or light backgrounds; 2-light backgrounds; 3-dark backgrounds."
1149 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1150 print_screen_output "Please note that this will set the $COLOR_SELECTION preferences only for user: $(whoami)"
1152 print_screen_output "------------------------------------------------------------------------------"
1153 for (( i=0; i < ${#A_COLOR_SCHEMES[@]}; i++ ))
1155 if [[ $i -gt 9 ]];then
1158 # only offer the safe universal defaults
1159 case $COLOR_SELECTION in
1160 global|irc|irc-console|irc-virtual-terminal)
1161 if [[ $i -gt $SAFE_COLOR_COUNT ]];then
1167 print_screen_output "$irc_clear $i)$spacer${C1}Card:${C2} nVidia G86 [GeForce 8400 GS] ${C1}X.Org${C2} 1.7.7"
1171 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1173 print_screen_output "$irc_clear $i)${spacer}Remove all color settings. Restore $SCRIPT_NAME default."
1174 print_screen_output "$irc_clear $(($i+1)))${spacer}Continue, no changes or config file setting."
1175 print_screen_output "$irc_clear $(($i+2)))${spacer}Exit, use another terminal, or set manually."
1176 print_screen_output "------------------------------------------------------------------------------"
1177 print_screen_output "Simply type the number for the color scheme that looks best to your eyes for your $COLOR_SELECTION settings"
1178 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:"
1179 print_screen_output "94 (console, no X - $console); 95 (terminal, X - $virt_term); 96 (irc, gui, X - $irc_gui);"
1180 print_screen_output "97 (irc, X, in terminal - $irc_x_term); 98 (irc, no X - $irc_console); 99 (global - $global)"
1181 print_screen_output "Your selection(s) will be stored here: $config_file"
1182 print_screen_output "Global overrides all individual color schemes. Individual schemes remove the global setting."
1183 print_screen_output "------------------------------------------------------------------------------"
1185 if [[ -n $( grep -Es '^([0-9]+)$' <<< "$user_selection" ) && $user_selection -lt $i ]];then
1186 case $COLOR_SELECTION in
1188 config_variable='IRC_COLOR_SCHEME'
1191 config_variable='IRC_CONS_COLOR_SCHEME'
1193 irc-virtual-terminal)
1194 config_variable='IRC_X_TERM_COLOR_SCHEME'
1197 config_variable='CONSOLE_COLOR_SCHEME'
1200 config_variable='VIRT_TERM_COLOR_SCHEME'
1203 config_variable='GLOBAL_COLOR_SCHEME'
1206 set_color_scheme $user_selection
1207 # make file/directory first if missing
1208 if [[ ! -f $config_file ]];then
1209 if [[ ! -d $HOME/.$SCRIPT_NAME ]];then
1210 mkdir $HOME/.$SCRIPT_NAME
1214 if [[ -z $( grep -s "$config_variable=" $config_file ) ]];then
1215 print_screen_output "Creating and updating config file for $COLOR_SELECTION color scheme now..."
1216 echo "$config_variable=$user_selection" >> $config_file
1218 print_screen_output "Updating config file for $COLOR_SELECTION color scheme now..."
1219 sed $SED_I "s/$config_variable=.*/$config_variable=$user_selection/" $config_file
1221 # file exists now so we can go on to cleanup
1222 case $COLOR_SELECTION in
1223 irc|irc-console|irc-virtual-terminal|console|virtual-terminal)
1224 sed $SED_I '/GLOBAL_COLOR_SCHEME=/d' $config_file
1227 sed $SED_I -e '/VIRT_TERM_COLOR_SCHEME=/d' -e '/CONSOLE_COLOR_SCHEME=/d' -e '/IRC_COLOR_SCHEME=/d' \
1228 -e '/IRC_CONS_COLOR_SCHEME=/d' -e '/IRC_X_TERM_COLOR_SCHEME=/d' $config_file
1231 elif [[ $user_selection == $i ]];then
1232 print_screen_output "Removing all color settings from config file now..."
1233 sed $SED_I -e '/VIRT_TERM_COLOR_SCHEME=/d' -e '/GLOBAL_COLOR_SCHEME=/d' -e '/CONSOLE_COLOR_SCHEME=/d' \
1234 -e '/IRC_COLOR_SCHEME=/d' -e '/IRC_CONS_COLOR_SCHEME=/d' -e '/IRC_X_TERM_COLOR_SCHEME=/d' $config_file
1235 set_color_scheme $DEFAULT_COLOR_SCHEME
1236 elif [[ $user_selection == $(( $i+1 )) ]];then
1237 print_screen_output "Ok, continuing $SCRIPT_NAME unchanged. You can set the colors anytime by starting with: -c 95 to 99"
1238 if [[ -n $CONSOLE_COLOR_SCHEME && -z $DISPLAY ]];then
1239 set_color_scheme $CONSOLE_COLOR_SCHEME
1240 elif [[ -n $VIRT_TERM_COLOR_SCHEME ]];then
1241 set_color_scheme $VIRT_TERM_COLOR_SCHEME
1243 set_color_scheme $DEFAULT_COLOR_SCHEME
1245 elif [[ $user_selection == $(( $i+2 )) ]];then
1246 set_color_scheme $DEFAULT_COLOR_SCHEME
1247 print_screen_output "Ok, exiting $SCRIPT_NAME now. You can set the colors later."
1250 print_screen_output "Error - Invalid Selection. You entered this: $user_selection"
1251 print_screen_output " "
1252 select_default_color_scheme
1255 print_screen_output "------------------------------------------------------------------------------"
1256 print_screen_output "After finding the scheme number you like, simply run this again in a terminal to set the configuration"
1257 print_screen_output "data file for your irc client. You can set color schemes for the following: start inxi with -c plus:"
1258 print_screen_output "94 (console, no X - $console); 95 (terminal, X - $virt_term); 96 (irc, gui, X - $irc_gui);"
1259 print_screen_output "97 (irc, X, in terminal - $irc_x_term); 98 (irc, no X - $irc_console); 99 (global - $global)"
1266 ########################################################################
1267 #### UTILITY FUNCTIONS
1268 ########################################################################
1270 #### -------------------------------------------------------------------
1271 #### error handler, debugger, script updater
1272 #### -------------------------------------------------------------------
1275 # args: $1 - error number; $2 - optional, extra information; $3 - optional extra info
1279 local error_message=''
1281 # assemble the error message
1283 2) error_message="large flood danger, debug buffer full!"
1285 3) error_message="unsupported color scheme number: $2"
1287 4) error_message="unsupported verbosity level: $2"
1289 5) error_message="dependency not met: $2 not found in path.\nFor distribution installation package names and missing apps information, run: $SCRIPT_NAME --recommends"
1291 6) error_message="/proc not found! Quitting..."
1293 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"
1295 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"
1297 9) error_message="unsupported debugging level: $2"
1300 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/"
1303 error_message="unsupported testing option argument: -! $2"
1306 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."
1309 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"
1312 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"
1315 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"
1318 error_message="$SCRIPT_NAME downloaded but the file data is corrupted. Purged data and using current version."
1321 error_message="All $SCRIPT_NAME self updater features have been disabled by the distribution\npackage maintainer. This includes the option you used: $2"
1324 error_message="The argument you provided for $2 does not have supported syntax.\nPlease use the following formatting:\n$3"
1327 error_message="The option $2 has been deprecated. Please use $3 instead.\nSee -h for instructions and syntax."
1330 error_message="The option you selected has been deprecated. $2\nSee the -h (help) menu for currently supported options."
1332 *) error_message="error unknown: $@"
1336 # then print it and exit
1337 print_screen_output "Error $1: $error_message"
1342 # prior to script up set, pack the data into an array
1343 # then we'll print it out later.
1344 # args: $1 - $@ debugging string text
1348 if [[ $B_SCRIPT_UP == 'true' ]];then
1349 # only return if debugger is off and no pre start up errors have occured
1350 if [[ $DEBUG -eq 0 && $DEBUG_BUFFER_INDEX -eq 0 ]];then
1352 # print out the stored debugging information if errors occured
1353 elif [[ $DEBUG_BUFFER_INDEX -gt 0 ]];then
1354 for (( DEBUG_BUFFER_INDEX=0; DEBUG_BUFFER_INDEX < ${#A_DEBUG_BUFFER[@]}; DEBUG_BUFFER_INDEX++ ))
1356 print_screen_output "${A_DEBUG_BUFFER[$DEBUG_BUFFER_INDEX]}"
1358 DEBUG_BUFFER_INDEX=0
1360 # or print out normal debugger messages if debugger is on
1361 if [[ $DEBUG -gt 0 ]];then
1362 print_screen_output "$1"
1365 if [[ $B_DEBUG_FLOOD == 'true' && $DEBUG_BUFFER_INDEX -gt 10 ]];then
1367 # this case stores the data for later printout, will print out only
1368 # at B_SCRIPT_UP == 'true' if array index > 0
1370 A_DEBUG_BUFFER[$DEBUG_BUFFER_INDEX]="$1"
1371 # increment count for next pre script up debugging error
1372 (( DEBUG_BUFFER_INDEX++ ))
1378 # NOTE: no logging available until get_parameters is run, since that's what sets logging
1379 # in order to trigger earlier logging manually set B_USE_LOGGING to true in top variables.
1380 # $1 alone: logs data; $2 with or without $3 logs func start/end.
1381 # $1 type (fs/fe/cat/raw) or logged data; [$2 is $FUNCNAME; [$3 - function args]]
1384 if [ "$B_USE_LOGGING" == 'true' ];then
1385 local logged_data='' spacer=' ' line='----------------------------------------'
1388 logged_data="Function: $2 - Primary: Start"
1390 logged_data="$logged_data\n${spacer}Args: $3"
1395 logged_data="Function: $2 - Primary: End"
1399 if [[ $B_LOG_FULL_DATA == 'true' ]];then
1400 logged_data="\n$line\nFull file data: cat $2\n\n$( cat $2 )\n$line\n"
1405 if [[ $B_LOG_FULL_DATA == 'true' ]];then
1406 logged_data="\n$line\nRaw system data:\n\n$2\n$line\n"
1414 # Create any required line breaks and strip out escape color code, either ansi (case 1)or irc (case 2).
1415 # This pattern doesn't work for irc colors, if we need that someone can figure it out
1416 if [[ -n $logged_data ]];then
1417 if [[ $B_LOG_COLORS != 'true' ]];then
1418 echo -e "${spacer}$logged_data" | sed $SED_RX 's/\x1b\[[0-9]{1,2}(;[0-9]{1,2}){0,2}m//g' >> $LOG_FILE
1420 echo -e "${spacer}$logged_data" >> $LOG_FILE
1426 # called in the initial -@ 10 script args setting so we can get logging as soon as possible
1427 # will have max 3 files, inxi.log, inxi.1.log, inxi.2.log
1428 create_rotate_logfiles()
1430 if [[ ! -d $SCRIPT_DATA_DIR ]];then
1431 mkdir $SCRIPT_DATA_DIR
1433 # do the rotation if logfile exists
1434 if [[ -f $LOG_FILE ]];then
1435 # copy if present second to third
1436 if [[ -f $LOG_FILE_1 ]];then
1437 mv -f $LOG_FILE_1 $LOG_FILE_2
1439 # then copy initial to second
1440 mv -f $LOG_FILE $LOG_FILE_1
1442 # now create the logfile
1444 # and echo the start data
1445 echo "=========================================================" >> $LOG_FILE
1446 echo "START $SCRIPT_NAME LOGGING:" >> $LOG_FILE
1447 echo "Script started: $( date +%Y-%m-%d-%H:%M:%S )" >> $LOG_FILE
1448 echo "=========================================================" >> $LOG_FILE
1451 # args: $1 - download url, not including file name; $2 - string to print out
1452 # $3 - update type option
1453 # note that $1 must end in / to properly construct the url path
1454 script_self_updater()
1457 local wget_error=0 file_contents='' wget_man_error=0
1458 local man_file_path="$MAN_FILE_LOCATION/inxi.1.gz"
1460 if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
1461 print_screen_output "Sorry, you can't run the $SCRIPT_NAME self updater option (-$3) in an IRC client."
1465 print_screen_output "Starting $SCRIPT_NAME self updater."
1466 print_screen_output "Currently running $SCRIPT_NAME version number: $SCRIPT_VERSION_NUMBER"
1467 print_screen_output "Current version patch number: $SCRIPT_PATCH_NUMBER"
1468 print_screen_output "Updating $SCRIPT_NAME in $SCRIPT_PATH using $2 as download source..."
1470 file_contents="$( wget -q -O - $1$SCRIPT_NAME )" || wget_error=$?
1471 # then do the actual download
1472 if [[ $wget_error -eq 0 ]];then
1473 # make sure the whole file got downloaded and is in the variable
1474 if [[ -n $( grep '###\*\*EOF\*\*###' <<< "$file_contents" ) ]];then
1475 echo "$file_contents" > $SCRIPT_PATH/$SCRIPT_NAME || error_handler 14 "$?"
1476 chmod +x $SCRIPT_PATH/$SCRIPT_NAME || error_handler 15 "$?"
1477 SCRIPT_VERSION_NUMBER=$( parse_version_data 'main' )
1478 SCRIPT_PATCH_NUMBER=$( parse_version_data 'patch' )
1479 print_screen_output "Successfully updated to $2 version: $SCRIPT_VERSION_NUMBER"
1480 print_screen_output "New $2 version patch number: $SCRIPT_PATCH_NUMBER"
1481 print_screen_output "To run the new version, just start $SCRIPT_NAME again."
1482 print_screen_output "----------------------------------------"
1483 print_screen_output "Starting download of man page file now."
1484 if [[ ! -d $MAN_FILE_LOCATION ]];then
1485 print_screen_output "The required man directory was not detected on your system, unable to continue: $MAN_FILE_LOCATION"
1487 if [[ $B_ROOT == 'true' ]];then
1488 print_screen_output "Checking Man page download URL..."
1489 if [[ -f /usr/share/man/man8/inxi.8.gz ]];then
1490 print_screen_output "Updating man page location to man1."
1491 mv -f /usr/share/man/man8/inxi.8.gz /usr/share/man/man1/inxi.1.gz
1492 if [[ -n $( type -p mandb ) ]];then
1493 exec $( type -p mandb ) -q
1496 wget -q --spider $MAN_FILE_DOWNLOAD || wget_man_error=$?
1497 if [[ $wget_man_error -eq 0 ]];then
1498 print_screen_output "Man file download URL verified: $MAN_FILE_DOWNLOAD"
1499 print_screen_output "Downloading Man page file now."
1500 wget -q -O $man_file_path $MAN_FILE_DOWNLOAD || wget_man_error=$?
1501 if [[ $wget_man_error -gt 0 ]];then
1502 print_screen_output "Oh no! Something went wrong downloading the Man gz file at: $MAN_FILE_DOWNLOAD"
1503 print_screen_output "Check the error messages for what happened. Error: $wget_man_error"
1505 print_screen_output "Download/install of man page successful. Check to make sure it works: man inxi"
1508 print_screen_output "Man file download URL failed, unable to continue: $MAN_FILE_DOWNLOAD"
1511 print_screen_output "Updating / Installing the Man page requires root user, writing to: $MAN_FILE_LOCATION"
1512 print_screen_output "If you want the man page, you'll have to run $SCRIPT_NAME -$3 as root."
1519 # now run the error handlers on any wget failure
1521 if [[ $2 == 'svn server' ]];then
1522 error_handler 8 "$wget_error"
1523 elif [[ $2 == 'alt server' ]];then
1524 error_handler 10 "$1"
1526 error_handler 12 "$1"
1532 # args: $1 - debug data type: sys|xorg|disk
1533 debug_data_collector()
1535 local xiin_app='' xiin_data_file='' xiin_download='' error='' b_run_xiin='false'
1536 local debug_data_dir='' bsd_string=''
1537 local completed_gz_file='' xiin_file='xiin.py' ftp_upload='ftp.techpatterns.com/incoming'
1538 local Line='-------------------------'
1539 local start_directory=$( pwd )
1541 if [[ -n $BSD_TYPE ]];then
1542 bsd_string="$BSD_TYPE-"
1545 debug_data_dir="inxi-$bsd_string$(tr ' ' '-' <<< $HOSTNAME | tr '[A-Z]' '[a-z]' )-$1-$(date +%Y%m%d)"
1547 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1548 if [[ -n $ALTERNATE_FTP ]];then
1549 ftp_upload=$ALTERNATE_FTP
1551 echo "Starting debugging data collection type: $1"
1552 echo -n "Checking/creating required directories... "
1553 if [[ ! -d $SCRIPT_DATA_DIR ]];then
1554 mkdir $SCRIPT_DATA_DIR
1558 if [[ -d $SCRIPT_DATA_DIR/$debug_data_dir ]];then
1559 echo 'Deleting previous xiin data directory...'
1560 rm -rf $SCRIPT_DATA_DIR/$debug_data_dir
1562 mkdir $SCRIPT_DATA_DIR/$debug_data_dir
1563 if [[ -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz ]];then
1564 echo 'Deleting previous tar.gz file...'
1565 rm -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz
1568 echo 'Collecting system info: sensors, lsusb, lspci, lspci -v data, plus /proc data'
1569 echo 'also checking for dmidecode data: note, you must be root to have dmidecode work.'
1570 echo "Data going into: $SCRIPT_DATA_DIR/$debug_data_dir"
1572 pciconf -vl &> $debug_data_dir/bsd-pciconf-vl.txt
1573 sysctl -a &> $debug_data_dir/bsd-sysctl-a.txt
1575 dmidecode &> $debug_data_dir/dmidecode.txt
1577 lscpu &> $debug_data_dir/lscpu.txt
1578 lspci &> $debug_data_dir/lspci.txt
1579 lspci -n &> $debug_data_dir/lspci-n.txt
1580 lspci -v &> $debug_data_dir/lspci-v.txt
1581 lsusb &> $debug_data_dir/lsusb.txt
1582 ps aux &> $debug_data_dir/ps-aux.txt
1583 runlevel &> $debug_data_dir/runlevel.txt
1584 systemctl list-units &> $debug_data_dir/systemctl-list-units.txt
1585 systemctl list-units --type=target &> $debug_data_dir/systemctl-list-units-target.txt
1586 initctl list &> $debug_data_dir/initctl-list.txt
1587 sensors &> $debug_data_dir/sensors.txt
1588 strings --version &> $debug_data_dir/strings.txt
1589 nvidia-smi -q &> $debug_data_dir/nvidia-smi-q.txt
1590 nvidia-smi -q -x &> $debug_data_dir/nvidia-smi-xq.txt
1592 ls /usr/bin/gcc* &> $debug_data_dir/gcc-sys-versions.txt
1593 gcc --version &> $debug_data_dir/gcc-version.txt
1594 cat /etc/issue &> $debug_data_dir/etc-issue.txt
1595 cat $FILE_LSB_RELEASE &> $debug_data_dir/lsb-release.txt
1596 cat $FILE_OS_RELEASE &> $debug_data_dir/os-release.txt
1597 cat $FILE_ASOUND_DEVICE &> $debug_data_dir/proc-asound-device.txt
1598 cat $FILE_ASOUND_VERSION &> $debug_data_dir/proc-asound-version.txt
1599 cat $FILE_CPUINFO &> $debug_data_dir/proc-cpu-info.txt
1600 cat $FILE_MEMINFO &> $debug_data_dir/proc-meminfo.txt
1601 cat $FILE_MODULES &> $debug_data_dir/proc-modules.txt
1602 cat /proc/net/arp &> $debug_data_dir/proc-net-arp.txt
1604 cat /var/run/dmesg.boot &> $debug_data_dir/bsd-var-run-dmesg.boot.txt
1606 check_recommends_user_output &> $debug_data_dir/check-recommends-user-output.txt
1607 # first download and verify xiin
1608 if [[ $B_UPLOAD_DEBUG_DATA == 'true' || $1 == 'disk' || $1 == 'sys' || $1 == 'all' ]];then
1609 touch $SCRIPT_DATA_DIR/$debug_data_dir/xiin-error.txt
1610 echo "Downloading required tree traverse tool $xiin_file..."
1611 if [[ -f xiin && ! -f $xiin_file ]];then
1612 mv -f xiin $xiin_file
1614 # -Nc is creating really weird download anomolies, so using -O instead
1615 xiin_download="$( wget -q -O - http://inxi.googlecode.com/svn/branches/xiin/$xiin_file )"
1616 # if nothing got downloaded kick out error, otherwise we'll use an older version
1617 if [[ $? -gt 0 && ! -f $xiin_file ]];then
1618 echo -e "ERROR: Failed to download required file: $xiin_file\nMaybe the remote site is down or your networking is broken?"
1619 echo "Continuing with incomplete data collection."
1620 echo "$xiin_file download failed and no existing $xiin_file" >> $debug_data_dir/xiin-error.txt
1621 elif [[ -n $( grep -s '# EOF' <<< "$xiin_download" ) || -f $xiin_file ]];then
1622 if [[ -n $( grep -s '# EOF' <<< "$xiin_download" ) ]];then
1623 echo "Updating $xiin_file from remote location"
1624 echo "$xiin_download" > $xiin_file
1626 echo "Using local $xiin_file due to download failure"
1630 echo -e "ERROR: $xiin_file downloaded but the program file data is corrupted.\nContinuing with incomplete data collection."
1631 echo "$xiin_file downloaded but the program file data is corrupted." >> $debug_data_dir/xiin-error.txt
1634 # note, only bash 4> supports ;;& for case, so using if/then here
1635 if [[ $1 == 'disk' || $1 == 'sys' || $1 == 'all' ]];then
1636 xiin_data_file=$SCRIPT_DATA_DIR/$debug_data_dir/xiin-sys.txt
1637 echo 'Collecting networking data...'
1638 ifconfig &> $debug_data_dir/ifconfig.txt
1639 ip addr &> $debug_data_dir/ip-addr.txt
1640 if [[ $b_run_xiin == 'true' && -z $BSD_TYPE ]];then
1642 echo "Running $xiin_file tool now on /sys..."
1643 echo "Using Python version:" && python --version
1644 python --version &> $debug_data_dir/python-version.txt
1645 python ./$xiin_file -d /sys -f $xiin_data_file
1646 if [[ $? -ne 0 ]];then
1648 echo -e "ERROR: $xiin_file exited with error $error - removing data file.\nContinuing with incomplete data collection."
1649 echo "Continuing with incomplete data collection."
1650 rm -f $xiin_data_file
1651 echo "$xiin_file data generation failed with python error $error" >> $debug_data_dir/xiin-error.txt
1656 if [[ $1 == 'xorg' || $1 == 'all' ]];then
1657 if [[ $B_RUNNING_IN_DISPLAY != 'true' ]];then
1658 echo 'Warning: only some of the data collection can occur if you are not in X'
1659 touch $debug_data_dir/warning-user-not-in-x
1661 if [[ $B_ROOT == 'true' ]];then
1662 echo 'Warning: only some of the data collection can occur if you are running as Root user'
1663 touch $debug_data_dir/warning-root-user
1665 echo 'Collecting Xorg log and xorg.conf files'
1666 if [[ -e $FILE_XORG_LOG ]];then
1667 cat $FILE_XORG_LOG &> $debug_data_dir/xorg-log-file.txt
1669 touch $debug_data_dir/no-xorg-log-file
1671 if [[ -e /etc/X11/xorg.conf ]];then
1672 cp /etc/X11/xorg.conf $SCRIPT_DATA_DIR/$debug_data_dir
1674 touch $debug_data_dir/no-xorg-conf-file
1676 if [[ -n $( ls /etc/X11/xorg.conf.d/ 2>/dev/null ) ]];then
1677 ls /etc/X11/xorg.conf.d &> $debug_data_dir/ls-etc-x11-xorg-conf-d.txt
1678 cp /etc/X11/xorg.conf.d $SCRIPT_DATA_DIR/$debug_data_dir
1680 touch $debug_data_dir/no-xorg-conf-d-files
1682 echo 'Collecting X, xprop, glxinfo, xrandr, xdpyinfo data...'
1683 xprop -root &> $debug_data_dir/xprop_root.txt
1684 glxinfo &> $debug_data_dir/glxinfo.txt
1685 xdpyinfo &> $debug_data_dir/xdpyinfo.txt
1686 xrandr &> $debug_data_dir/xrandr.txt
1687 X -version &> $debug_data_dir/x-version.txt
1688 Xorg -version &> $debug_data_dir/xorg-version.txt
1689 echo $GNOME_DESKTOP_SESSION_ID &> $debug_data_dir/gnome-desktop-session-id.txt
1691 echo $KDE_FULL_SESSION &> $debug_data_dir/kde3-ful-session.txt
1692 echo $KDE_SESSION_VERSION &> $debug_data_dir/kde456-session-version.txt
1693 echo "$(kded$KDE_SESSION_VERSION --version )" &> $debug_data_dir/kde-version-data.txt
1694 echo $XDG_CURRENT_DESKTOP &> $debug_data_dir/xdg-current-desktop.txt
1696 if [[ $1 == 'disk' || $1 == 'all' ]];then
1697 echo 'Collecting dev, label, disk, uuid data, df...'
1698 ls -l /dev &> $debug_data_dir/dev-data.txt
1699 ls -l /dev/disk &> $debug_data_dir/dev-disk-data.txt
1700 ls -l /dev/disk/by-id &> $debug_data_dir/dev-disk-id-data.txt
1701 ls -l /dev/disk/by-label &> $debug_data_dir/dev-disk-label-data.txt
1702 ls -l /dev/disk/by-uuid &> $debug_data_dir/dev-disk-uuid-data.txt
1703 ls -l /dev/disk/by-path &> $debug_data_dir/dev-disk-path-data.txt
1704 ls -l /dev/mapper &> $debug_data_dir/dev-disk-mapper-data.txt
1705 readlink /dev/root &> $debug_data_dir/dev-root.txt
1706 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
1707 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
1708 df -H -T &> $debug_data_dir/bsd-df-H-T-no-excludes.txt
1709 df -H &> $debug_data_dir/bsd-df-H-no-excludes.txt
1711 mount &> $debug_data_dir/mount.txt
1712 gpart list &> $debug_data_dir/bsd-gpart-list.txt
1713 gpart show &> $debug_data_dir/bsd-gpart-show.txt
1714 gpart status &> $debug_data_dir/bsd-gpart-status.txt
1715 swapctl -l &> $debug_data_dir/bsd-swapctl-l.txt
1716 swapon -s &> $debug_data_dir/swapon-s.txt
1717 sysctl -b kern.geom.conftxt &> $debug_data_dir/bsd-sysctl-b-kern.geom.conftxt.txt
1718 sysctl -b kern.geom.confxml &> $debug_data_dir/bsd-sysctl-b-kern.geom.confxml.txt
1719 zfs list &> $debug_data_dir/bsd-zfs-list.txt
1720 zpool list &> $debug_data_dir/bsd-zpool-list.txt
1721 zpool list -v &> $debug_data_dir/bsd-zpool-list-v.txt
1722 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
1723 df -P &> $debug_data_dir/bsd-df-P-no-excludes.txt
1724 cat /proc/mdstat &> $debug_data_dir/proc-mdstat.txt
1725 cat $FILE_PARTITIONS &> $debug_data_dir/proc-partitions.txt
1726 cat $FILE_SCSI &> $debug_data_dir/proc-scsi.txt
1727 cat $FILE_MOUNTS &> $debug_data_dir/proc-mounts.txt
1728 cat /proc/sys/dev/cdrom/info &> $debug_data_dir/proc-cdrom-info.txt
1729 ls /proc/ide/ &> $debug_data_dir/proc-ide.txt
1730 cat /proc/ide/*/* &> $debug_data_dir/proc-ide-hdx-cat.txt
1731 cat /etc/fstab &> $debug_data_dir/etc-fstab.txt
1732 cat /etc/mtab &> $debug_data_dir/etc-mtab.txt
1734 echo 'Creating inxi output file now. This can take a few seconds...'
1735 echo "Starting $SCRIPT_NAME from: $start_directory"
1737 $SCRIPT_PATH/$SCRIPT_NAME -FRploudxxx -c 0 -@ 8 > $SCRIPT_DATA_DIR/$debug_data_dir/inxi-FRploudxxx.txt
1738 cp $LOG_FILE $SCRIPT_DATA_DIR/$debug_data_dir
1739 if [[ -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz ]];then
1740 echo "Found and removing previous tar.gz data file: $debug_data_dir.tar.gz"
1741 rm -f $SCRIPT_DATA_DIR/$debug_data_dir.tar.gz
1744 echo 'Creating tar.gz compressed file of this material now. Contents:'
1746 tar -cvzf $debug_data_dir.tar.gz $debug_data_dir
1748 echo 'Cleaning up leftovers...'
1749 rm -rf $debug_data_dir
1750 echo 'Testing gzip file integrity...'
1751 gzip -t $debug_data_dir.tar.gz
1752 if [[ $? -gt 0 ]];then
1753 echo 'Data in gz is corrupted, removing gzip file, try running data collector again.'
1754 rm -f $debug_data_dir.tar.gz
1755 echo "Data in gz is corrupted, removed gzip file" >> $debug_data_dir/gzip-error.txt
1757 echo 'All done, you can find your data gzipped directory here:'
1758 completed_gz_file=$SCRIPT_DATA_DIR/$debug_data_dir.tar.gz
1759 echo $completed_gz_file
1760 if [[ $B_UPLOAD_DEBUG_DATA == 'true' ]];then
1762 if [[ $b_run_xiin == 'true' ]];then
1763 echo "Running automatic upload of data to remote server $ftp_upload now..."
1764 python ./$xiin_file --version
1765 python ./$xiin_file -u $completed_gz_file $ftp_upload
1766 if [[ $? -gt 0 ]];then
1768 echo "Error: looks like the ftp upload failed. Error number: $?"
1769 echo "The ftp upload failed. Error number: $?" >> $debug_data_dir/xiin-error.txt
1772 echo 'Unable to run the automoatic ftp upload because of an error with the xiin download.'
1773 echo "Unable to run the automoatic ftp upload because of an error with the xiin download" >> $debug_data_dir/xiin-error.txt
1776 echo 'You can upload this here using most file managers: ftp.techpatterns.com/incoming'
1777 echo 'then let a maintainer know it is uploaded.'
1781 echo 'This feature only available in console or shell client! Exiting now.'
1786 check_recommends_user_output()
1788 local Line='-----------------------------------------------------------------------------------------'
1789 local gawk_version='N/A' sed_version='N/A' sudo_version='N/A' python_version='N/A'
1791 if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
1792 print_screen_output "Sorry, you can't run this option in an IRC client."
1798 echo "$SCRIPT_NAME will now begin checking for the programs it needs to operate. First a check of"
1799 echo "the main languages and tools $SCRIPT_NAME uses. Python is only for debugging data collection."
1801 echo "Bash version: $( bash --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^GNU bash/ {print $4}' )"
1802 if [[ -n $( type -p gawk ) ]];then
1803 gawk_version=$( gawk --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^GNU Awk/ {print $3}' )
1805 if [[ -n $( type -p sed ) ]];then
1806 sed_version=$( sed --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^GNU sed version/ {print $4}' )
1807 if [[ -z $sed_version ]];then
1808 # note: bsd sed shows error with --version flag
1809 sed_version=$( sed --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^sed: illegal option/ {print "BSD sed"}' )
1812 if [[ -n $( type -p sudo ) ]];then
1813 sudo_version=$( sudo -V 2>&1 | awk 'BEGIN {IGNORECASE=1} /^Sudo version/ {print $3}' )
1815 if [[ -n $( type -p python ) ]];then
1816 python_version=$( python --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^Python/ {print $2}' )
1818 echo "Gawk version: $gawk_version"
1819 echo "Sed version: $sed_version"
1820 echo "Sudo version: $sudo_version"
1821 echo "Python version: $python_version"
1823 echo "Test One: Required System Directories."
1824 echo "If one of these system directories is missing, $SCRIPT_NAME cannot operate:"
1826 check_recommends_items 'required-dirs'
1827 echo "Test Two: Required Core Applications."
1828 echo "If one of these applications is missing, $SCRIPT_NAME cannot operate:"
1830 check_recommends_items 'required-apps'
1831 echo 'Test Three: Script Recommends for Graphics Features. If you do not use X these do not matter.'
1832 echo "If one of these applications is missing, $SCRIPT_NAME will have incomplete output:"
1834 check_recommends_items 'recommended-x-apps'
1835 echo 'Test Four: Script Recommends for Remaining Features.'
1836 echo "If one of these applications is missing, $SCRIPT_NAME will have incomplete output:"
1838 check_recommends_items 'recommended-apps'
1839 echo 'Test Five: System Directories for Various Information.'
1840 echo "If one of these directories is missing, $SCRIPT_NAME will have incomplete output:"
1842 check_recommends_items 'system-dirs'
1843 echo 'All tests completed.'
1845 # args: $1 - check item
1846 check_recommends_items()
1848 local item='' item_list='' item_string='' missing_items='' missing_string=''
1849 local package='' application='' feature='' type='' starter='' finisher=''
1850 local package_deb='' package_pacman='' package_rpm=''
1851 local print_string='' separator=''
1852 local required_dirs='/proc /sys'
1853 # package-owner: 1 - debian/ubuntu; 2 - arch; 3 - yum/rpm
1854 # pardus: pisi sf -q /usr/bin/package
1855 local required_apps='
1856 df:coreutils~coreutils~coreutils~:partition_data
1857 gawk:gawk~gawk~gawk~:core_tool
1858 grep:grep~grep~grep~:string_search
1859 lspci:pciutils~pciutils~pciutils~:hardware_data
1860 ps:procps~procps~procps~:process_data
1861 readlink:coreutils~coreutils~coreutils~:
1862 sed:sed~sed~sed~:string_replace
1863 tr:coreutils~coreutils~coreutils~:character_replace
1864 uname:uname~coreutils~coreutils~:kernel_data
1865 uptime:procps~procps~procps~:
1866 wc:coreutils~coreutils~coreutils~:word_character_count
1868 local x_recommends='
1869 glxinfo:mesa-utils~mesa-demos~glx-utils_(openSUSE_12.3_and_later_Mesa-demo-x)~:-G_glx_info
1870 xdpyinfo:X11-utils~xorg-xdpyinfo~xorg-x11-utils~:-G_multi_screen_resolution
1871 xprop:X11-utils~xorg-xprop~x11-utils~:-S_desktop_data
1872 xrandr:x11-xserver-utils~xrandr~x11-server-utils~:-G_single_screen_resolution
1874 local recommended_apps='
1875 dmidecode:dmidecode~dmidecode~dmidecode~:-M_if_no_sys_machine_data
1876 file:file~file~file~:-o_unmounted_file_system
1877 hddtemp:hddtemp~hddtemp~hddtemp~:-Dx_show_hdd_temp
1878 ifconfig:net-tools~net-tools~net-tools~:-i_ip_lan-deprecated
1879 ip:iproute~iproute2~iproute~:-i_ip_lan
1880 sensors:lm-sensors~lm_sensors~lm-sensors~:-s_sensors_output
1881 strings:binutils~~~:-I_sysvinit_version
1882 lsusb:usbutils~usbutils~usbutils~:-A_usb_audio;-N_usb_networking
1883 modinfo:module-init-tools~module-init-tools~module-init-tools~:-Ax,-Nx_module_version
1884 runlevel:sysvinit~sysvinit~systemd~:-I_runlevel
1885 sudo:sudo~sudo~sudo~:-Dx_hddtemp-user;-o_file-user
1887 local recommended_dirs='
1888 /sys/class/dmi/id:-M_system,_motherboard,_bios
1889 /dev:-l,-u,-o,-p,-P,-D_disk_partition_data
1890 /dev/disk/by-label:-l,-o,-p,-P_partition_labels
1891 /dev/disk/by-uuid:-u,-o,-p,-P_partition_uuid
1892 /var/run/dmesg.boot:-C,-f_(BSD_only)
1897 item_list=$required_dirs
1898 item_string='Required file system'
1899 missing_string='system directories'
1903 item_list=$required_apps
1904 item_string='Required application'
1905 missing_string='applications, and their corresponding packages,'
1909 item_list=$x_recommends
1910 item_string='Recommended X application'
1911 missing_string='applications, and their corresponding packages,'
1915 item_list=$recommended_apps
1916 item_string='Recommended application'
1917 missing_string='applications, and their corresponding packages,'
1921 item_list=$recommended_dirs
1922 item_string='System directory'
1923 missing_string='system directories'
1927 # great trick from: http://ideatrash.net/2011/01/bash-string-padding-with-sed.html
1928 # left pad: sed -e :a -e 's/^.\{1,80\}$/& /;ta'
1929 # right pad: sed -e :a -e 's/^.\{1,80\}$/ &/;ta'
1930 # center pad: sed -e :a -e 's/^.\{1,80\}$/ & /;ta'
1932 for item in $item_list
1934 if [[ $( awk -F ":" '{print NF-1}' <<< $item ) -eq 0 ]];then
1939 elif [[ $( awk -F ":" '{print NF-1}' <<< $item ) -eq 1 ]];then
1940 application=$( cut -d ':' -f 1 <<< $item )
1942 feature=$( cut -d ':' -f 2 <<< $item )
1945 application=$( cut -d ':' -f 1 <<< $item )
1946 package=$( cut -d ':' -f 2 <<< $item )
1947 location=$( type -p $application )
1948 if [[ $( awk -F ":" '{print NF-1}' <<< $item ) -eq 2 ]];then
1949 feature=$( cut -d ':' -f 3 <<< $item )
1954 if [[ -n $feature ]];then
1955 print_string="$item_string: $application (info: $( sed 's/_/ /g' <<< $feature ))"
1957 print_string="$item_string: $application"
1960 starter="$( sed -e :a -e 's/^.\{1,75\}$/&./;ta' <<< $print_string )"
1961 if [[ -z $( grep '^/' <<< $application ) && -n $location ]] || [[ -d $application ]];then
1962 if [[ -n $location ]];then
1963 finisher=" $location"
1969 missing_items="$missing_items$separator$application:$package"
1973 echo "$starter$finisher"
1976 if [[ -n $missing_items ]];then
1977 echo "The following $type are missing from your system:"
1978 for item in $missing_items
1980 application=$( cut -d ':' -f 1 <<< $item )
1981 if [[ $type == 'applications' ]];then
1982 # echo '--------------------------------------------------------'
1984 package=$( cut -d ':' -f 2 <<< $item )
1985 package_deb=$( cut -d '~' -f 1 <<< $package )
1986 package_pacman=$( cut -d '~' -f 2 <<< $package )
1987 package_rpm=$( cut -d '~' -f 3 <<< $package )
1988 echo "Application: $application"
1989 echo "To add to your system, install the proper distribution package for your system:"
1990 echo "Debian/Ubuntu: $package_deb :: Arch Linux: $package_pacman :: Redhat/Fedora/Suse: $package_rpm"
1992 echo "Directory: $application"
1995 if [[ $item_string == 'System directory' ]];then
1996 echo "These directories are created by the kernel, so don't worry if they are not present."
1999 echo "All the $( cut -d ' ' -f 1 <<< $item_string | sed -e 's/Re/re/' -e 's/Sy/sy/' ) $type are present."
2004 #### -------------------------------------------------------------------
2005 #### print / output cleaners
2006 #### -------------------------------------------------------------------
2008 # inxi speaks through here. When run by Konversation script alias mode, uses DCOP
2009 # for dcop to work, must use 'say' operator, AND colors must be evaluated by echo -e
2010 # note: dcop does not seem able to handle \n so that's being stripped out and replaced with space.
2011 print_screen_output()
2014 # the double quotes are needed to avoid losing whitespace in data when certain output types are used
2015 # trim off whitespace at end
2016 local print_data="$( echo -e "$1" )"
2018 # just using basic debugger stuff so you can tell which thing is printing out the data. This
2019 # should help debug kde 4 konvi issues when that is released into sid, we'll see. Turning off
2020 # the redundant debugger output which as far as I can tell does exactly nothing to help debugging.
2021 if [[ $DEBUG -gt 5 ]];then
2022 if [[ $KONVI -eq 1 ]];then
2023 # konvi doesn't seem to like \n characters, it just prints them literally
2024 # print_data="$( tr '\n' ' ' <<< "$print_data" )"
2025 # dcop "$DCPORT" "$DCOPOBJ" say "$DCSERVER" "$DCTARGET" "konvi='$KONVI' saying : '$print_data'"
2026 print_data="KP-$KONVI: $print_data"
2027 elif [[ $KONVI -eq 2 ]];then
2028 # echo "konvi='$KONVI' saying : '$print_data'"
2029 print_data="KP-$KONVI: $print_data"
2031 # echo "printing out: '$print_data'"
2032 print_data="P: $print_data"
2036 if [[ $KONVI -eq 1 && $B_DCOP == 'true' ]]; then ## dcop Konversation (<= 1.1 (qt3))
2037 # konvi doesn't seem to like \n characters, it just prints them literally
2038 $print_data="$( tr '\n' ' ' <<< "$print_data" )"
2039 dcop "$DCPORT" "$DCOPOBJ" say "$DCSERVER" "$DCTARGET" "$print_data"
2041 elif [[ $KONVI -eq 3 && $B_QDBUS == 'true' ]]; then ## dbus Konversation (> 1.2 (qt4))
2042 qdbus org.kde.konversation /irc say "$DCSERVER" "$DCTARGET" "$print_data"
2044 # elif [[ $IRC_CLIENT == 'X-Chat' ]]; then
2045 # qdbus org.xchat.service print "$print_data\n"
2048 # the -n is needed to avoid double spacing of output in terminal
2049 echo -ne "$print_data\n"
2054 ## this handles all verbose line construction with indentation/line starter
2055 ## args: $1 - null (, actually: " ") or line starter; $2 - line content
2060 printf "${C1}%-${INDENT}s${C2} %s" "$1" "$line"
2064 # this removes newline and pipes.
2065 # args: $1 - string to clean
2066 remove_erroneous_chars()
2069 ## RS is input record separator
2070 ## gsub is substitute;
2076 gsub(/\n$/,"") ## (newline; end of string) with (nothing)
2077 gsub(/\n/," "); ## (newline) with (space)
2078 gsub(/^ *| *$/, "") ## (pipe char) with (nothing)
2079 gsub(/ +/, " ") ## ( +) with (space)
2080 gsub(/ [ ]+/, " ") ## ([ ]+) with (space)
2081 gsub(/^ +| +$/, "") ## (pipe char) with (nothing)
2083 }' "$1" ## prints (returns) cleaned input
2087 #### -------------------------------------------------------------------
2088 #### parameter handling, print usage functions.
2089 #### -------------------------------------------------------------------
2091 # Get the parameters. Note: standard options should be lower case, advanced or testing, upper
2092 # args: $1 - full script startup args: $@
2096 local opt='' wget_test='' debug_data_type='' weather_flag='wW:'
2097 local use_short='true' # this is needed to trigger short output, every v/d/F/line trigger sets this false
2099 # if distro maintainers don't want the weather feature disable it
2100 if [[ $B_ALLOW_WEATHER == 'false' ]];then
2104 if [[ $1 == '--version' ]];then
2107 elif [[ $1 == '--help' ]];then
2110 elif [[ $1 == '--recommends' ]];then
2111 check_recommends_user_output
2113 # the short form only runs if no args output args are used
2114 # no need to run through these if there are no args
2115 # reserved for future use: -g for extra Graphics; -m for extra Machine; -d for extra Disk
2116 elif [[ -n $1 ]];then
2117 while getopts Abc:CdDfFGhHiIlMnNopPrRsSt:uUv:V${weather_flag}xzZ%@:!: opt
2120 A) B_SHOW_AUDIO='true'
2123 b) use_short='false'
2124 B_SHOW_BASIC_CPU='true'
2125 B_SHOW_BASIC_RAID='true'
2126 B_SHOW_DISK_TOTAL='true'
2127 B_SHOW_GRAPHICS='true'
2129 B_SHOW_MACHINE='true'
2130 B_SHOW_NETWORK='true'
2131 B_SHOW_SYSTEM='true'
2133 c) if [[ -n $( grep -E '^[0-9][0-9]?$' <<< $OPTARG ) ]];then
2136 B_RUN_COLOR_SELECTOR='true'
2137 COLOR_SELECTION='global'
2140 B_RUN_COLOR_SELECTOR='true'
2141 COLOR_SELECTION='irc-console'
2144 B_RUN_COLOR_SELECTOR='true'
2145 COLOR_SELECTION='irc-virtual-terminal'
2148 B_RUN_COLOR_SELECTOR='true'
2149 COLOR_SELECTION='irc'
2152 B_RUN_COLOR_SELECTOR='true'
2153 COLOR_SELECTION='virtual-terminal'
2156 B_RUN_COLOR_SELECTOR='true'
2157 COLOR_SELECTION='console'
2160 B_COLOR_SCHEME_SET='true'
2161 ## note: not sure about this, you'd think user values should be overridden, but
2162 ## we'll leave this for now
2163 if [[ -z $COLOR_SCHEME ]];then
2164 set_color_scheme "$OPTARG"
2169 error_handler 3 "$OPTARG"
2172 C) B_SHOW_CPU='true'
2175 d) B_SHOW_DISK='true'
2176 B_SHOW_FULL_OPTICAL='true'
2178 # error_handler 20 "-d has been replaced by -b"
2180 D) B_SHOW_DISK='true'
2183 f) B_SHOW_CPU='true'
2184 B_CPU_FLAGS_FULL='true'
2187 F) # B_EXTRA_DATA='true'
2188 B_SHOW_ADVANCED_NETWORK='true'
2190 # B_SHOW_BASIC_OPTICAL='true'
2193 B_SHOW_GRAPHICS='true'
2195 B_SHOW_MACHINE='true'
2196 B_SHOW_NETWORK='true'
2197 B_SHOW_PARTITIONS='true'
2199 B_SHOW_SENSORS='true'
2200 B_SHOW_SYSTEM='true'
2203 G) B_SHOW_GRAPHICS='true'
2207 B_SHOW_NETWORK='true'
2208 B_SHOW_ADVANCED_NETWORK='true'
2211 I) B_SHOW_INFO='true'
2214 l) B_SHOW_LABELS='true'
2215 B_SHOW_PARTITIONS='true'
2218 M) B_SHOW_MACHINE='true'
2221 n) B_SHOW_ADVANCED_NETWORK='true'
2222 B_SHOW_NETWORK='true'
2225 N) B_SHOW_NETWORK='true'
2228 o) B_SHOW_UNMOUNTED_PARTITIONS='true'
2231 p) B_SHOW_PARTITIONS_FULL='true'
2232 B_SHOW_PARTITIONS='true'
2235 P) B_SHOW_PARTITIONS='true'
2238 r) B_SHOW_REPOS='true'
2241 R) B_SHOW_RAID='true'
2242 # it turns out only users with mdraid software installed will have raid,
2243 # so unless -R is explicitly called, blank -b/-F/-v6 and less output will not show
2244 # error if file is missing.
2245 B_SHOW_RAID_R='true'
2248 s) B_SHOW_SENSORS='true'
2251 S) B_SHOW_SYSTEM='true'
2254 t) if [[ -n $( grep -E '^(c|m|cm|mc)([1-9]|1[0-9]|20)?$' <<< $OPTARG ) ]];then
2256 if [[ -n $( grep -E '[0-9]+' <<< $OPTARG ) ]];then
2257 PS_COUNT=$( sed 's/[^0-9]//g' <<< $OPTARG )
2259 if [[ -n $( grep 'c' <<< $OPTARG ) ]];then
2260 B_SHOW_PS_CPU_DATA='true'
2262 if [[ -n $( grep 'm' <<< $OPTARG ) ]];then
2263 B_SHOW_PS_MEM_DATA='true'
2266 error_handler 13 "$OPTARG"
2269 u) B_SHOW_UUIDS='true'
2270 B_SHOW_PARTITIONS='true'
2273 v) if [[ -n $( grep -E "^[0-9][0-9]?$" <<< $OPTARG ) && $OPTARG -le $VERBOSITY_LEVELS ]];then
2274 if [[ $OPTARG -ge 1 ]];then
2276 B_SHOW_BASIC_CPU='true'
2277 B_SHOW_DISK_TOTAL='true'
2278 B_SHOW_GRAPHICS='true'
2280 B_SHOW_SYSTEM='true'
2282 if [[ $OPTARG -ge 2 ]];then
2283 B_SHOW_BASIC_DISK='true'
2284 B_SHOW_BASIC_RAID='true'
2285 B_SHOW_MACHINE='true'
2286 B_SHOW_NETWORK='true'
2288 if [[ $OPTARG -ge 3 ]];then
2289 B_SHOW_ADVANCED_NETWORK='true'
2293 if [[ $OPTARG -ge 4 ]];then
2295 B_SHOW_PARTITIONS='true'
2297 if [[ $OPTARG -ge 5 ]];then
2299 B_SHOW_BASIC_OPTICAL='true'
2300 B_SHOW_SENSORS='true'
2301 B_SHOW_LABELS='true'
2305 if [[ $OPTARG -ge 6 ]];then
2306 B_SHOW_FULL_OPTICAL='true'
2307 B_SHOW_PARTITIONS_FULL='true'
2308 B_SHOW_UNMOUNTED_PARTITIONS='true'
2309 B_EXTRA_EXTRA_DATA='true'
2311 if [[ $OPTARG -ge 7 ]];then
2312 B_EXTRA_EXTRA_EXTRA_DATA='true'
2314 B_SHOW_RAID_R='true'
2317 error_handler 4 "$OPTARG"
2320 U) if [[ $B_ALLOW_UPDATE == 'true' ]];then
2321 script_self_updater "$SCRIPT_DOWNLOAD" 'svn server' "$opt"
2323 error_handler 17 "-$opt"
2326 V) print_version_info
2329 w) B_SHOW_WEATHER=true
2332 W) ALTERNATE_WEATHER_LOCATION=$( sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' <<< $OPTARG )
2333 if [[ -n $( grep -Esi '([^,]+,.+|[0-9-]+)' <<< $ALTERNATE_WEATHER_LOCATION ) ]];then
2337 error_handler 18 "-$opt: '$OPTARG'" "city,state OR latitude,longitude OR postal/zip code."
2340 # this will trigger either with x, xx, xxx or with Fx but not with xF
2341 x) if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
2342 B_EXTRA_EXTRA_EXTRA_DATA='true'
2343 elif [[ $B_EXTRA_DATA == 'true' ]];then
2344 B_EXTRA_EXTRA_DATA='true'
2349 z) B_OUTPUT_FILTER='true'
2351 Z) B_OVERRIDE_FILTER='true'
2356 H) show_options 'full'
2359 ## debuggers and testing tools
2360 %) B_HANDLE_CORRUPT_DATA='true'
2362 @) if [[ -n $( grep -E "^([1-9]|1[0-4])$" <<< $OPTARG ) ]];then
2364 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
2365 B_UPLOAD_DEBUG_DATA='true'
2368 # switch on logging only for -@ 8-10
2371 if [[ $OPTARG -eq 10 ]];then
2373 elif [[ $OPTARG -eq 9 ]];then
2374 B_LOG_FULL_DATA='true'
2376 B_USE_LOGGING='true'
2377 # pack the logging data for evals function start/end
2380 create_rotate_logfiles # create/rotate logfiles before we do anything else
2385 debug_data_type='sys'
2388 debug_data_type='xorg'
2391 debug_data_type='disk'
2394 debug_data_type='all'
2398 debug_data_collector $debug_data_type
2402 error_handler 9 "$OPTARG"
2405 !) # test for various supported methods
2407 1) B_TESTING_1='true'
2409 2) B_TESTING_2='true'
2411 3) B_TESTING_1='true'
2415 if [[ $B_ALLOW_UPDATE == 'true' ]];then
2418 script_self_updater "$SCRIPT_DOWNLOAD_DEV" 'dev server' "$opt $OPTARG"
2421 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_1" 'svn: branch one server' "$opt $OPTARG"
2424 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_2" 'svn: branch two server' "$opt $OPTARG"
2427 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_3" 'svn: branch three server' "$opt $OPTARG"
2430 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_4" 'svn: branch four server' "$opt $OPTARG"
2433 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_BSD" 'svn: branch bsd server' "$opt $OPTARG"
2436 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_GNUBSD" 'svn: branch gnubsd server' "$opt $OPTARG"
2439 script_self_updater "$OPTARG" 'alt server' "$opt <http...>"
2443 error_handler 17 "-$opt $OPTARG"
2447 B_RUNNING_IN_SHELL='true'
2456 ALTERNATE_FTP="$OPTARG"
2458 # for weather function, allows user to set an alternate weather location
2460 error_handler 19 "-$opt location=" "-W"
2462 *) error_handler 11 "$OPTARG"
2466 *) error_handler 7 "$1"
2471 ## this must occur here so you can use the debugging flag to show errors
2472 ## Reroute all error messages to the bitbucket (if not debugging)
2473 if [[ $DEBUG -eq 0 ]];then
2476 #((DEBUG)) && exec 2>&1 # This is for debugging konversation
2478 # after all the args have been processed, if no long output args used, run short output
2479 if [[ $use_short == 'true' ]];then
2480 B_SHOW_SHORT_OUTPUT='true'
2482 # just in case someone insists on using -zZ
2483 if [[ $B_OVERRIDE_FILTER == 'true' ]];then
2484 B_OUTPUT_FILTER='false'
2486 # change basic to full if user requested it or if arg overrides it
2487 if [[ $B_SHOW_RAID == 'true' && $B_SHOW_BASIC_RAID == 'true' ]];then
2488 B_SHOW_BASIC_RAID='false'
2495 ## print out help menu, not including Testing or Debugger stuff because it's not needed
2498 local color_scheme_count=$(( ${#A_COLOR_SCHEMES[@]} - 1 ))
2499 local partition_string='partition' partition_string_u='Partition'
2501 if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
2502 print_screen_output "Sorry, you can't run the help option in an IRC client."
2505 if [[ -n $BSD_TYPE ]];then
2506 partition_string='slice'
2507 partition_string_u='Slice'
2509 # print_lines_basic "0" "" ""
2510 # print_lines_basic "1" "" ""
2511 # print_lines_basic "2" "" ""
2512 # print_screen_output " "
2513 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."
2514 print_screen_output " "
2515 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."
2517 print_screen_output "- - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
2518 print_screen_output "Output Control Options:"
2519 print_lines_basic "1" "-A" "Audio/sound card information."
2520 print_lines_basic "1" "-b" "Basic output, short form. Like $SCRIPT_NAME^-v^2, only minus hard disk names."
2521 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."
2522 print_lines_basic "1" "" "Supported color schemes: 0-$color_scheme_count Example: $SCRIPT_NAME^-c^11"
2523 print_lines_basic "1" "" "Color selectors for each type display (NOTE: irc and global only show safe color set):"
2524 # print_screen_output " Supported color schemes: 0-$color_scheme_count Example: $SCRIPT_NAME -c 11"
2525 # print_screen_output " Color selectors for each type display (NOTE: irc and global only show safe color set):"
2526 print_lines_basic "2" "94" "Console, out of X"
2527 print_lines_basic "2" "95" "Terminal, running in X - like xTerm"
2528 print_lines_basic "2" "96" "Gui IRC, running in X - like Xchat, Quassel, Konversation etc."
2529 print_lines_basic "2" "97" "Console IRC running in X - like irssi in xTerm"
2530 print_lines_basic "2" "98" "Console IRC not in X"
2531 print_lines_basic "2" "99" "Global - Overrides/removes all settings. Setting specific removes global."
2532 print_lines_basic "1" "-C" "CPU output, including per CPU clockspeed (if available)."
2533 print_lines_basic "1" "-d" "Optical drive data. Same as -Dd. See also -x and -xx."
2534 print_lines_basic "1" "-D" "Full hard Disk info, not only model, ie: /dev/sda ST380817AS 80.0GB. See also -x and -xx."
2535 print_lines_basic "1" "-f" "All cpu flags, triggers -C. Not shown with -F to avoid spamming. ARM cpus show 'features'."
2536 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"
2537 print_lines_basic "1" "-G" "Graphic card information (card, display server type/version, resolution, glx renderer, version)."
2538 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."
2539 print_lines_basic "1" "-I" "Information: processes, uptime, memory, irc client (or shell type), $SCRIPT_NAME version."
2540 print_lines_basic "1" "-l" "${partition_string_u} labels. Default: short ${partition_string} -P. For full -p output, use: -pl (or -plu)."
2541 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."
2542 print_lines_basic "1" "-n" "Advanced Network card information. Same as -Nn. Shows interface, speed, mac id, state, etc."
2543 print_lines_basic "1" "-N" "Network card information. With -x, shows PCI BusID, Port number."
2544 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^"
2545 print_lines_basic "1" "-p" "Full ${partition_string} information (-P plus all other detected ${partition_string}s)."
2546 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."
2547 print_lines_basic "1" "-r" "Distro repository data. Supported repo types: APT; PACMAN; PISI; YUM; URPMQ; Ports."
2548 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."
2549 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."
2550 print_lines_basic "1" "-S" "System information: host name, kernel, desktop environment (if in X), distro"
2551 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"
2552 print_lines_basic "1" "" "Make sure to have no space between letters and numbers (-t^cm10 - right, -t^cm^10 - wrong)."
2553 print_lines_basic "1" "-u" "${partition_string_u} UUIDs. Default: short ${partition_string} -P. For full -p output, use: -pu (or -plu)."
2554 print_lines_basic "1" "-v" "Script verbosity levels. Verbosity level number is required. Should not be used with -b or -F"
2555 print_lines_basic "1" "" "Supported levels: 0-${VERBOSITY_LEVELS} Example: $SCRIPT_NAME^-v^4"
2556 print_lines_basic "2" "0" "Short output, same as: $SCRIPT_NAME"
2557 print_lines_basic "2" "1" "Basic verbose, -S + basic CPU + -G + basic Disk + -I."
2558 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"
2559 print_lines_basic "2" "3" "Advanced CPU (-C), network (-n) data, and switches on -x advanced data option."
2560 print_lines_basic "2" "4" "${partition_string_u} size/filled data (-P) for (if present):/, /home, /var/, /boot. Shows full disk data (-D)."
2561 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)."
2562 print_lines_basic "2" "6" "Full ${partition_string} (-p), unmounted ${partition_string} (-o), optical drive (-d), full raid; triggers -xx."
2563 print_lines_basic "2" "7" "Network IP data (-i); triggers -xxx."
2565 # if distro maintainers don't want the weather feature disable it
2566 if [[ $B_ALLOW_WEATHER == 'true' ]];then
2567 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."
2568 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"
2570 print_lines_basic "1" "-x" "Adds the following extra data (only works with verbose or line output, not short form):"
2571 print_lines_basic "2" "-C" "CPU Flags, Bogomips on Cpu;"
2572 print_lines_basic "2" "-d" "Extra optical drive data; adds rev version to optical drive."
2573 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"
2574 print_lines_basic "2" "-G" "Direct rendering status for Graphics (in X)."
2575 print_lines_basic "2" "-G" "(for single gpu, nvidia driver) screen number gpu is running on."
2576 print_lines_basic "2" "-i" "IPv6 as well for LAN interface (IF) devices."
2577 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)."
2578 print_lines_basic "2" "-N -A" "Version/port(s)/driver version (if available) for Network/Audio;"
2579 print_lines_basic "2" "-N -A -G" "Network, audio, graphics, shows PCI Bus ID/Usb ID number of card."
2580 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"
2581 print_lines_basic "2" "-S" "Desktop toolkit if avaliable (GNOME/XFCE/KDE only); Kernel gcc version"
2582 print_lines_basic "2" "-t" "Memory use output to cpu (-xt c), and cpu use to memory (-xt m)."
2583 if [[ $B_ALLOW_WEATHER == 'true' ]];then
2584 print_lines_basic "2" "-w -W" "Wind speed and time zone (-w only)."
2586 print_lines_basic "1" "-xx" "Show extra, extra data (only works with verbose or line output, not short form):"
2587 print_lines_basic "2" "-A" "Chip vendor:product ID for each audio device."
2588 print_lines_basic "2" "-D" "Disk serial number."
2589 print_lines_basic "2" "-G" "Chip vendor:product ID for each video card."
2590 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."
2591 print_lines_basic "2" "-M" "Chassis information, bios rom size (dmidecode only), if data for either is available."
2592 print_lines_basic "2" "-N" "Chip vendor:product ID for each nic."
2593 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."
2594 print_lines_basic "2" "-S" "Display manager (dm) in desktop output, if in X (like kdm, gdm3, lightdm)."
2595 if [[ $B_ALLOW_WEATHER == 'true' ]];then
2596 print_lines_basic "2" "-w -W" "Humidity, barometric pressure."
2598 print_lines_basic "2" "-@ 11-14" "Automatically uploads debugger data tar.gz file to ftp.techpatterns.com. EG: $SCRIPT_NAME^-xx@14"
2599 print_lines_basic "1" "-xxx" "Show extra, extra, extra data (only works with verbose or line output, not short form):"
2600 print_lines_basic "2" "-S" "Panel/shell information in desktop output, if in X (like gnome-shell, cinnamon, mate-panel)."
2601 if [[ $B_ALLOW_WEATHER == 'true' ]];then
2602 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)."
2604 print_lines_basic "1" "-z" "Security filters for IP/Mac addresses, location, user home directory name. Default on for irc clients."
2605 print_lines_basic "1" "-Z" "Absolute override for output filters. Useful for debugging networking issues in irc for example."
2606 print_screen_output " "
2607 print_screen_output "Additional Options:"
2608 print_lines_basic "4" "-h --help" "This help menu."
2609 print_lines_basic "4" "-H" "This help menu, plus developer options. Do not use dev options in normal operation!"
2610 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. "
2611 if [[ $B_ALLOW_UPDATE == 'true' ]];then
2612 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."
2614 print_lines_basic "4" "-V --version" "$SCRIPT_NAME version information. Prints information then exits."
2615 print_screen_output " "
2616 print_screen_output "Debugging Options:"
2617 print_lines_basic "1" "-%" "Overrides defective or corrupted data."
2618 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."
2619 print_lines_basic "2" "1-7" "On screen debugger output"
2620 print_lines_basic "2" "8" "Basic logging"
2621 print_lines_basic "2" "9" "Full file/sys info logging"
2622 print_lines_basic "2" "10" "Color logging."
2623 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>"
2624 print_lines_basic "1" "" "For alternate ftp upload locations: Example: inxi^-!^ftp.yourserver.com/incoming^-xx@^14"
2625 print_lines_basic "2" "11" "With data file of xiin read of /sys."
2626 print_lines_basic "2" "12" "With xorg conf and log data, xrandr, xprop, xdpyinfo, glxinfo etc."
2627 print_lines_basic "2" "13" "With data from dev, disks, ${partition_string}s, etc., plus xiin data file."
2628 print_lines_basic "2" "14" "Everything, full data collection."
2629 print_screen_output " "
2630 print_screen_output "Advanced Options:"
2631 print_lines_basic "1" "-! 31" "Turns off hostname in output. Useful if showing output from servers etc."
2632 print_lines_basic "1" "-! 32" "Turns on hostname in output. Overrides global B_SHOW_HOST='false'"
2634 if [[ $1 == 'full' ]];then
2635 print_screen_output " "
2636 print_screen_output "Developer and Testing Options (Advanced):"
2637 print_lines_basic "1" "-! 1" "Sets testing flag B_TESTING_1='true' to trigger testing condition 1."
2638 print_lines_basic "1" "-! 2" "Sets testing flag B_TESTING_2='true' to trigger testing condition 2."
2639 print_lines_basic "1" "-! 3" "Sets flags B_TESTING_1='true' and B_TESTING_2='true'."
2640 if [[ $B_ALLOW_UPDATE == 'true' ]];then
2641 print_lines_basic "1" "-! 10" "Triggers an update from the primary dev download server instead of svn."
2642 print_lines_basic "1" "-! 11" "Triggers an update from svn branch one - if present, of course."
2643 print_lines_basic "1" "-! 12" "Triggers an update from svn branch two - if present, of course."
2644 print_lines_basic "1" "-! 13" "Triggers an update from svn branch three - if present, of course."
2645 print_lines_basic "1" "-! 14" "Triggers an update from svn branch four - if present, of course."
2646 print_lines_basic "1" "-! 15" "Triggers an update from svn branch BSD - if present, of course."
2647 print_lines_basic "1" "-! 16" "Triggers an update from svn branch GNUBSD - if present, of course."
2648 print_lines_basic "1" "-! <http://......>" "Triggers an update from whatever server you list."
2650 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. "
2651 print_lines_basic "1" "" "Example: inxi^-!^ftp.yourserver.com/incoming^-xx@^14"
2653 print_screen_output " "
2656 # uses $TERM_COLUMNS to set width using $COLS_MAX as max width
2657 # IMPORTANT: minimize use of subshells here or the output is too slow
2658 # args: $1 - 0 1 2 3 4 for indentation level; $2 -line starter, like -m; $3 - content of block.
2661 local line_width=$COLS_MAX
2662 local print_string='' indent_inner='' indent_full='' indent_x=''
2663 local indent_working='' indent_working_full=''
2664 local line_starter='' line_1_starter='' line_x_starter=''
2665 # note: to create a padded string below
2666 local fake_string=' ' temp_count='' line_count='' spacer=''
2667 local indent_main=6 indent_x='' b_indent_x='true'
2670 # for no options, start at left edge
2676 1) indent_full=$indent_main
2678 if [[ $temp_count -le $indent_full ]];then
2679 indent_working=$indent_full
2681 indent_working=$temp_count #$(( $temp_count + 1 ))
2683 line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_working\}$/& /;ta" <<< $2 )"
2685 # first left pad 2 and 3, then right pad them
2686 2) indent_full=$(( $indent_main + 6 ))
2689 if [[ $temp_count -le $indent_inner ]];then
2690 indent_working=$indent_inner
2691 #indent_working_full=$indent_full
2693 indent_working=$(( $temp_count + 1 ))
2694 #indent_working_full=$(( $indent_full - $indent_inner - 1 ))
2696 line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_working\}$/& /;ta" <<< $2 )"
2697 line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_full\}$/ &/;ta" <<< "$line_1_starter" )"
2699 3) indent_full=$(( $indent_main + 8 ))
2702 if [[ $temp_count -le $indent_inner ]];then
2703 indent_working=$indent_inner
2705 indent_working=$(( $temp_count + 1 ))
2707 line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_working\}$/& /;ta" <<< $2 )"
2708 line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_full\}$/ &/;ta" <<< "$line_1_starter" )"
2711 4) indent_full=$(( $indent_main + 8 ))
2713 if [[ $temp_count -lt $indent_full ]];then
2714 indent_working=$indent_full
2716 indent_working=$temp_count #$(( $temp_count + 1 ))
2718 line_1_starter="$( sed -e :a -e "s/^.\{1,$indent_working\}$/& /;ta" <<< $2 )"
2722 if [[ $b_indent_x == 'true' ]];then
2723 indent_x=$(( $indent_full + 1 ))
2724 line_x_starter="$(printf "%${indent_x}s" '')"
2727 line_count=$(( $line_width - $indent_full ))
2729 # bash loop is slow, only run this if required
2730 if [[ ${#3} -gt $line_count ]];then
2733 temp_string="$print_string$spacer$word"
2735 if [[ ${#temp_string} -lt $line_count ]];then
2736 print_string=$temp_string # lose any white space start/end
2737 # echo -n $(( $line_width - $indent_full ))
2739 if [[ -n $line_1_starter ]];then
2740 line_starter="$line_1_starter"
2743 line_starter="$line_x_starter"
2745 # clean up forced connections, ie, stuff we don't want wrapping
2746 print_string=${print_string//\^/ }
2747 print_screen_output "$line_starter$print_string"
2748 print_string="$word$spacer" # needed to handle second word on new line
2757 # print anything left over
2758 if [[ -n $print_string ]];then
2759 if [[ -n $line_1_starter ]];then
2760 line_starter="$line_1_starter"
2763 line_starter="$line_x_starter"
2765 print_string=${print_string//\^/ }
2766 print_screen_output "$line_starter$print_string"
2769 # 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'
2770 # 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'
2771 # print_lines_basic '2' '12' 'and its sss substring'
2772 # 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'
2775 ## print out version information for -V/--version
2776 print_version_info()
2778 # if not in PATH could be either . or directory name, no slash starting
2779 local script_path=$SCRIPT_PATH script_symbolic_start=''
2780 if [[ $script_path == '.' ]];then
2781 script_path=$( pwd )
2782 elif [[ -z $( grep '^/' <<< "$script_path" ) ]];then
2783 script_path="$( pwd )/$script_path"
2785 # handle if it's a symbolic link, rare, but can happen with script directories in irc clients
2786 # which would only matter if user starts inxi with -! 30 override in irc client
2787 if [[ -L $script_path/$SCRIPT_NAME ]];then
2788 script_symbolic_start=$script_path/$SCRIPT_NAME
2789 script_path=$( readlink $script_path/$SCRIPT_NAME )
2790 script_path=$( dirname $script_path )
2792 local last_modified=$( parse_version_data 'date' )
2793 local year_modified=$( gawk '{print $NF}' <<< "$last_modified" )
2795 print_screen_output "$SCRIPT_NAME $SCRIPT_VERSION_NUMBER-$SCRIPT_PATCH_NUMBER ($last_modified)"
2796 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
2797 print_screen_output "Program Location: $script_path"
2798 if [[ -n $script_symbolic_start ]];then
2799 print_screen_output "Started via symbolic link: $script_symbolic_start"
2801 print_lines_basic "0" "" "Website:^http://inxi.goooglecode.com"
2802 print_lines_basic "0" "" "IRC:^irc.oftc.net channel:^#smxi"
2803 print_lines_basic "0" "" "Forums:^http://techpatterns.com/forums/forum-33.html"
2804 print_screen_output " "
2805 print_lines_basic "0" "" "$SCRIPT_NAME - the universal, portable, system information tool for console and irc."
2806 print_screen_output " "
2807 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."
2808 print_lines_basic "0" "" "Subsequent changes and modifications (after Infobash 3.02): Copyright (C) 2008-$year_modified Scott Rogers, Harald Hope, aka trash80 & h2"
2809 print_screen_output " "
2810 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)"
2814 ########################################################################
2816 ########################################################################
2818 #### -------------------------------------------------------------------
2819 #### initial startup stuff
2820 #### -------------------------------------------------------------------
2822 # Determine where inxi was run from, set IRC_CLIENT and IRC_CLIENT_VERSION
2826 local Irc_Client_Path='' irc_client_path_lower='' non_native_konvi='' i=''
2827 local B_Non_Native_App='false' pppid='' App_Working_Name=''
2828 local b_qt4_konvi='false' ps_parent=''
2830 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
2832 unset IRC_CLIENT_VERSION
2833 # elif [[ -n $PPID ]];then
2834 elif [[ -n $PPID && -f /proc/$PPID/exe ]];then
2835 if [[ $B_OVERRIDE_FILTER != 'true' ]];then
2836 B_OUTPUT_FILTER='true'
2838 Irc_Client_Path=$( readlink /proc/$PPID/exe )
2839 # Irc_Client_Path=$( ps -p $PPID | gawk '!/[[:space:]]*PID/ {print $5}' )
2840 # echo $( ps -p $PPID )
2841 irc_client_path_lower=$( tr '[:upper:]' '[:lower:]' <<< $Irc_Client_Path )
2842 App_Working_Name=$( basename $irc_client_path_lower )
2843 # handles the xchat/sh/bash/dash cases, and the konversation/perl cases, where clients
2844 # report themselves as perl or unknown shell. IE: when konversation starts inxi
2845 # from inside itself, as a script, the parent is konversation/xchat, not perl/bash etc
2846 # note: perl can report as: perl5.10.0, so it needs wildcard handling
2847 case $App_Working_Name in
2848 # bsd will never use this section
2849 bash|dash|sh|python*|perl*) # We want to know who wrapped it into the shell or perl.
2850 pppid="$( ps -p $PPID -o ppid --no-headers | sed 's/[[:space:]]//g' )"
2851 if [[ -n $pppid && -f /proc/$pppid/exe ]];then
2852 Irc_Client_Path="$( readlink /proc/$pppid/exe )"
2853 irc_client_path_lower="$( tr '[:upper:]' '[:lower:]' <<< $Irc_Client_Path )"
2854 App_Working_Name=$( basename $irc_client_path_lower )
2855 B_Non_Native_App='true'
2859 # sets version number if it can find it
2860 get_irc_client_version
2862 ## lets look to see if qt4_konvi is the parent. There is no direct way to tell, so lets infer it.
2863 ## because $PPID does not work with qt4_konvi, the above case does not work
2864 if [[ $B_OVERRIDE_FILTER != 'true' ]];then
2865 B_OUTPUT_FILTER='true'
2867 b_qt4_konvi=$( is_this_qt4_konvi )
2868 if [[ $b_qt4_konvi == 'true' ]];then
2870 IRC_CLIENT='Konversation'
2871 IRC_CLIENT_VERSION=" $( konversation -v | gawk '
2873 for ( i=2; i<=NF; i++ ) {
2884 # this should handle certain cases where it's ssh or some other startup tool
2885 # that falls through all the other tests
2886 if [[ $BSD_TYPE != 'bsd' ]];then
2887 App_Working_Name=$(ps -p $PPID --no-headers 2>/dev/null | gawk '{print $NF}' )
2889 # without --no-headers we need the second line
2890 App_Working_Name=$(ps -p $PPID 2>/dev/null | gawk '/^[0-9]+/ {print $5}' )
2893 if [[ -n $App_Working_Name ]];then
2894 Irc_Client_Path=$App_Working_Name
2895 B_Non_Native_App='false'
2896 get_irc_client_version
2897 if [[ -z $IRC_CLIENT ]];then
2898 IRC_CLIENT=$App_Working_Name
2901 IRC_CLIENT="PPID=\"$PPID\" - empty?"
2902 unset IRC_CLIENT_VERSION
2907 log_function_data "IRC_CLIENT: $IRC_CLIENT :: IRC_CLIENT_VERSION: $IRC_CLIENT_VERSION :: PPID: $PPID"
2910 # note: all variables set in caller so no need to pass
2911 get_irc_client_version()
2914 # replacing loose detection with tight detection, bugs will be handled with app names
2916 case $App_Working_Name in
2917 # check for shell first
2919 unset IRC_CLIENT_VERSION
2920 IRC_CLIENT="Shell wrapper"
2922 # now start on irc clients, alphabetically
2924 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk '
2927 gsub(/[()]|bitchx-/,"",a)
2937 B_CONSOLE_IRC='true'
2941 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
2944 B_CONSOLE_IRC='true'
2948 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
2954 # the hexchat author decided to make --version/-v return a gtk dialogue box, lol...
2955 # so we need to read the actual config file for hexchat. Note that older hexchats
2956 # used xchat config file, so test first for default, then legacy. Because it's possible
2957 # for this file to be use edited, doing some extra checks here.
2958 if [[ -f ~/.config/hexchat/hexchat.conf ]];then
2959 file_data="$( cat ~/.config/hexchat/hexchat.conf )"
2960 elif [[ -f ~/.config/hexchat/xchat.conf ]];then
2961 file_data="$( cat ~/.config/hexchat/xchat.conf )"
2963 if [[ -n $file_data ]];then
2964 IRC_CLIENT_VERSION=$( gawk '
2969 /^[[:space:]]*version/ {
2970 # get rid of the space if present
2971 gsub(/[[:space:]]*/, "", $2 )
2973 exit # usually this is the first line, no point in continuing
2974 }' <<< "$file_data" )
2976 IRC_CLIENT_VERSION=" $IRC_CLIENT_VERSION"
2978 IRC_CLIENT_VERSION=' N/A'
2980 IRC_CLIENT="HexChat"
2983 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
2986 B_CONSOLE_IRC='true'
2990 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
2993 B_CONSOLE_IRC='true'
2996 konversation) ## konvi < 1.2 (qt4)
2997 # this is necessary to avoid the dcop errors from starting inxi as a /cmd started script
2998 if [[ $B_Non_Native_App == 'true' ]];then ## true negative is confusing
3000 else # if native app
3003 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk '
3005 for ( i=2; i<=NF; i++ ) {
3016 T=($IRC_CLIENT_VERSION)
3017 if [[ ${T[0]} == *+* ]];then
3018 # < Sho_> locsmif: The version numbers of SVN versions look like this:
3019 # "<version number of last release>+ #<build number", i.e. "1.0+ #3177" ...
3020 # for releases we remove the + and build number, i.e. "1.0" or soon "1.0.1"
3021 IRC_CLIENT_VERSION=" CVS $IRC_CLIENT_VERSION"
3024 IRC_CLIENT_VERSION=" ${T[0]}"
3027 # Remove any dots except the first, and make sure there are no trailing zeroes,
3028 T2=$( echo "$T2" | gawk '{
3034 # Since Konversation 1.0, the DCOP interface has changed a bit: dcop "$DCPORT" Konversation ..etc
3035 # becomes : dcop "$DCPORT" default ... or dcop "$DCPORT" irc ..etc. So we check for versions smaller
3036 # than 1 and change the DCOP parameter/object accordingly.
3037 if [[ ${T2} -lt 1 ]];then
3038 DCOPOBJ="Konversation"
3040 IRC_CLIENT="Konversation"
3043 IRC_CLIENT_VERSION=" $( kopete -v | gawk '
3051 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v 2>&1 | gawk '{
3052 for ( i=2; i<=NF; i++) {
3065 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
3071 # sample: quassel -v
3073 # KDE: 4.2.65 (KDE 4.2.65 (KDE 4.3 >= 20090226))
3074 # Quassel IRC: v0.4.0 [+60] (git-22effe5)
3075 # note: early < 0.4.1 quassels do not have -v
3076 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v 2>/dev/null | gawk -F ': ' '
3085 # this handles pre 0.4.1 cases with no -v
3086 if ( clientVersion == "" ) {
3087 clientVersion = "(pre v0.4.1)"
3091 # now handle primary, client, and core. quasselcore doesn't actually
3092 # handle scripts with exec, but it's here just to be complete
3093 case $App_Working_Name in
3095 IRC_CLIENT="Quassel [M]"
3098 IRC_CLIENT="Quassel"
3101 IRC_CLIENT="Quassel (core)"
3106 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v ) "
3107 B_CONSOLE_IRC='true'
3108 IRC_CLIENT="Weechat"
3111 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
3114 IRC_CLIENT="X-Chat-Gnome"
3117 IRC_CLIENT_VERSION=" $( $Irc_Client_Path -v | gawk 'NR == 1 {
3122 # then do some perl type searches, do this last since it's a wildcard search
3124 unset IRC_CLIENT_VERSION
3125 # KSirc is one of the possibilities now. KSirc is a wrapper around dsirc, a perl client
3127 for (( i=0; i <= $CMDL_MAX; i++ ))
3129 case ${A_CMDL[i]} in
3132 # Dynamic runpath detection is too complex with KSirc, because KSirc is started from
3133 # kdeinit. /proc/<pid of the grandparent of this process>/exe is a link to /usr/bin/kdeinit
3134 # with one parameter which contains parameters separated by spaces(??), first param being KSirc.
3135 # Then, KSirc runs dsirc as the perl irc script and wraps around it. When /exec is executed,
3136 # dsirc is the program that runs inxi, therefore that is the parent process that we see.
3137 # You can imagine how hosed I am if I try to make inxi find out dynamically with which path
3138 # KSirc was run by browsing up the process tree in /proc. That alone is straightjacket material.
3139 # (KSirc sucks anyway ;)
3140 IRC_CLIENT_VERSION=" $( ksirc -v | gawk '
3149 B_CONSOLE_IRC='true'
3150 set_perl_python_konvi "$App_Working_Name"
3153 # B_CONSOLE_IRC='true' # are there even any python type console irc clients? check.
3154 set_perl_python_konvi "$App_Working_Name"
3156 # then unset, set unknown data
3158 IRC_CLIENT="Unknown : ${Irc_Client_Path##*/}"
3159 unset IRC_CLIENT_VERSION
3162 if [[ $SHOW_IRC -lt 2 ]];then
3163 unset IRC_CLIENT_VERSION
3167 # args: $1 - App_Working_Name
3168 set_perl_python_konvi()
3170 if [[ -z $IRC_CLIENT_VERSION ]];then
3171 # this is a hack to try to show konversation if inxi is running but started via /cmd
3172 if [[ -n $( grep -i 'konversation' <<< "$Ps_aux_Data" | grep -v 'grep' ) && $B_RUNNING_IN_DISPLAY == 'true' ]];then
3173 IRC_CLIENT='Konversation'
3174 IRC_CLIENT_VERSION=" $( konversation --version 2>/dev/null | gawk '/^Konversation/ {print $2}' )"
3175 B_CONSOLE_IRC='false'
3177 IRC_CLIENT="Unknown $1 client"
3182 ## try to infer the use of Konversation >= 1.2, which shows $PPID improperly
3183 ## no known method of finding Kovni >= 1.2 as parent process, so we look to see if it is running,
3184 ## and all other irc clients are not running.
3187 local konvi_qt4_client='' konvi_dbus_exist='' konvi_pid='' konvi_home_dir=''
3188 local konvi='' konvi_qt4_ver='' b_is_qt4=''
3190 # fringe cases can throw error, always if untested app, use 2>/dev/null after testing if present
3191 if [[ $B_QDBUS == 'true' ]];then
3192 konvi_dbus_exist=$( qdbus 2>/dev/null | grep "org.kde.konversation" )
3194 # sabayon uses /usr/share/apps/konversation as path
3195 if [[ -n $konvi_dbus_exist ]] && [[ -e /usr/share/kde4/apps/konversation || -e /usr/share/apps/konversation ]]; then
3196 konvi_pid=$( ps -A | gawk 'BEGIN{IGNORECASE=1} /konversation/ { print $1 }' )
3197 konvi_home_dir=$( readlink /proc/$konvi_pid/exe )
3198 konvi=$( echo $konvi_home_dir | sed "s/\// /g" )
3201 if [[ ${konvi[2]} == 'konversation' ]];then
3202 konvi_qt4_ver=$( konversation -v | grep -i 'konversation' )
3203 # note: we need to change this back to a single dot number, like 1.3, not 1.3.2
3204 konvi_qt4_client=$( echo "$konvi_qt4_ver" | gawk '{ print $2 }' | cut -d '.' -f 1,2 )
3206 if [[ $konvi_qt4_client > 1.1 ]]; then
3214 log_function_data "b_is_qt4: $b_is_qt4"
3216 ## for testing this module
3217 #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]}"
3220 # This needs some cleanup and comments, not quite understanding what is happening, although generally output is known
3221 # Parse the null separated commandline under /proc/<pid passed in $1>/cmdline
3228 if [[ ! -e /proc/$ppid/cmdline ]];then
3232 ##print_screen_output "Marker"
3233 ##print_screen_output "\$ppid='$ppid' -=- $(< /proc/$ppid/cmdline)"
3235 ## note: need to figure this one out, and ideally clean it up and make it readable
3236 while read -d $'\0' L && [[ $i -lt 32 ]]
3238 A_CMDL[i++]="$L" ## note: make sure this is valid - What does L mean? ##
3239 done < /proc/$ppid/cmdline
3240 ##print_screen_output "\$i='$i'"
3241 if [[ $i -eq 0 ]];then
3242 A_CMDL[0]=$(< /proc/$ppid/cmdline)
3243 if [[ -n ${A_CMDL[0]} ]];then
3248 log_function_data "CMDL_MAX: $CMDL_MAX"
3252 #### -------------------------------------------------------------------
3254 #### -------------------------------------------------------------------
3255 ## create array of sound cards installed on system, and if found, use asound data as well
3259 local i='' alsa_data='' audio_driver='' device_count='' temp_array=''
3262 # this first step handles the drivers for cases where the second step fails to find one
3263 device_count=$( echo "$Lspci_v_Data" | grep -iEc '(multimedia audio controller|audio device)' )
3264 if [[ $device_count -eq 1 ]] && [[ $B_ASOUND_DEVICE_FILE == 'true' ]];then
3265 audio_driver=$( gawk -F ']: ' '
3269 # filtering out modems and usb devices like webcams, this might get a
3270 # usb audio card as well, this will take some trial and error
3271 $0 !~ /modem|usb|webcam/ {
3272 driver=gensub( /^(.+)( - )(.+)$/, "\\1", 1, $2 )
3273 gsub(/^ +| +$/,"",driver)
3274 if ( driver != "" ){
3277 }' $FILE_ASOUND_DEVICE )
3278 log_function_data 'cat' "$FILE_ASOUND_DEVICE"
3281 # this is to safeguard against line breaks from results > 1, which if inserted into following
3282 # array will create a false array entry. This is a hack, not a permanent solution.
3283 audio_driver=$( echo $audio_driver )
3284 # now we'll build the main audio data, card name, driver, and port. If no driver is found,
3285 # and if the first method above is not null, and one card is found, it will use that instead.
3286 A_AUDIO_DATA=( $( echo "$Lspci_v_Data" | gawk -F ': ' -v audioDriver="$audio_driver" '
3290 /multimedia audio controller|audio device/ {
3291 audioCard=gensub(/^[0-9a-f:\.]+ [^:]+: (.+)$/,"\\1","g",$0)
3292 # The doublequotes are necessary because of the pipes in the variable.
3293 gsub(/'"$BAN_LIST_NORMAL"'/, "", audioCard)
3294 gsub(/,/, " ", audioCard)
3295 gsub(/^ +| +$/, "", audioCard)
3296 gsub(/ [ \t]+/, " ", audioCard)
3297 aPciBusId[audioCard] = gensub(/(^[0-9a-f:\.]+) [^:]+: .+$/,"\\1","g",$0)
3300 # loop until you get to the end of the data block
3301 while (getline && !/^$/) {
3303 if (/driver in use/) {
3304 drivers[audioCard] = drivers[audioCard] gensub( /(.*): (.*)/ ,"\\2", "g" ,$0 ) ""
3306 else if (/kernel modules:/) {
3307 modules[audioCard] = modules[audioCard] gensub( /(.*): (.*)/ ,"\\2" ,"g" ,$0 ) ""
3310 portsTemp = gensub(/\t*I\/O ports at (.*) \[.*\]/,"\\1","g",$0)
3311 ports[audioCard] = ports[audioCard] portsTemp " "
3326 if (drivers[i] != "") {
3327 useDrivers=drivers[i]
3332 # little trick here to try to catch the driver if there is
3333 # only one card and it was null, from the first test of asound/cards
3334 if (drivers[i] != "") {
3335 useDrivers=drivers[i]
3337 else if ( audioDriver != "" ) {
3338 useDrivers=audioDriver
3341 if (ports[i] != "") {
3344 if (modules[i] != "" ) {
3345 useModules = modules[i]
3347 if ( aPciBusId[i] != "" ) {
3348 usePciBusId = aPciBusId[i]
3350 # create array primary item for master array
3351 sub( / $/, "", usePorts ) # clean off trailing whitespace
3352 print a[j] "," useDrivers "," usePorts "," useModules "," usePciBusId
3357 # in case of failure of first check do this instead
3358 if [[ ${#A_AUDIO_DATA[@]} -eq 0 ]] && [[ $B_ASOUND_DEVICE_FILE == 'true' ]];then
3359 A_AUDIO_DATA=( $( gawk -F ']: ' '
3363 $1 !~ /modem/ && $2 !~ /modem/ {
3364 card=gensub( /^(.+)( - )(.+)$/, "\\3", 1, $2 )
3365 driver=gensub( /^(.+)( - )(.+)$/, "\\1", 1, $2 )
3369 }' $FILE_ASOUND_DEVICE ) )
3373 # handle cases where card detection fails, like in PS3, where lspci gives no output, or headless boxes..
3374 if [[ ${#A_AUDIO_DATA[@]} -eq 0 ]];then
3375 A_AUDIO_DATA[0]='Failed to Detect Sound Card!'
3377 temp_array=${A_AUDIO_DATA[@]}
3378 log_function_data "A_AUDIO_DATA: $temp_array"
3382 # alsa usb detection by damentz
3384 get_audio_usb_data()
3387 local usb_proc_file='' array_count='' usb_data='' usb_id='' lsusb_path='' lsusb_data=''
3391 lsusb_path=$( type -p lsusb )
3392 if [[ -n $lsusb_path ]];then
3393 lsusb_data=$( $lsusb_path 2>/dev/null )
3395 log_function_data 'raw' "usb_data:\n$lsusb_data"
3396 if [[ -n $lsusb_data ]];then
3397 # for every sound card symlink in /proc/asound - display information about it
3398 for usb_proc_file in /proc/asound/*
3400 # If the file is a symlink, and contains an important usb exclusive file: continue
3401 if [[ -L $usb_proc_file && -e $usb_proc_file/usbid ]]; then
3402 # find the contents of usbid in lsusb and print everything after the 7th word on the
3403 # corresponding line. Finally, strip out commas as they will change the driver :)
3404 usb_id=$( cat $usb_proc_file/usbid )
3405 usb_data=$( grep "$usb_id" <<< "$lsusb_data" )
3406 if [[ -n $usb_data && -n $usb_id ]];then
3414 gsub( /,/, " ", $0 )
3415 gsub(/'"$BAN_LIST_NORMAL"'/, "", $0)
3416 gsub(/ [ \t]+/, " ", $0)
3417 for ( i=7; i<= NF; i++ ) {
3418 string = string separator $i
3423 print string ",USB Audio,,," $2 "-" $4 "," $6
3425 }' <<< "$usb_data" )
3427 # this method is interesting, it shouldn't work but it does
3428 #A_AUDIO_DATA=( "${A_AUDIO_DATA[@]}" "$usb_data,USB Audio,," )
3429 # but until we learn why the above worked, I'm using this one, which is safer
3430 if [[ -n $usb_data ]];then
3431 array_count=${#A_AUDIO_DATA[@]}
3432 A_AUDIO_DATA[$array_count]="$usb_data"
3438 temp_array=${A_AUDIO_DATA[@]}
3439 log_function_data "A_AUDIO_DATA: $temp_array"
3444 get_audio_alsa_data()
3447 local alsa_data='' temp_array=''
3449 # now we'll get the alsa data if the file exists
3450 if [[ $B_ASOUND_VERSION_FILE == 'true' ]];then
3459 # some alsa strings have the build date in (...)
3460 # remove trailing . and remove possible second line if compiled by user
3462 gsub( /Driver | [(].*[)]|\.$/,"",$0 )
3464 gsub(/^ +| +$/, "", $0)
3465 gsub(/ [ \t]+/, " ", $0)
3466 sub(/Advanced Linux Sound Architecture/, "ALSA", $0)
3467 if ( $1 == "ALSA" ){
3471 print alsa "," version
3472 }' $FILE_ASOUND_VERSION ) )
3474 log_function_data 'cat' "$FILE_ASOUND_VERSION"
3476 temp_array=${A_ALSA_DATA[@]}
3477 log_function_data "A_ALSA_DATA: $temp_array"
3481 ## create A_CPU_CORE_DATA, currently with two values: integer core count; core string text
3482 ## return value cpu core count string, this helps resolve the multi redundant lines of old style output
3483 get_cpu_core_count()
3486 local cpu_physical_count='' cpu_core_count='' cpu_type='' cpu_alpha_count=''
3487 if [[ $B_CPUINFO_FILE == 'true' ]]; then
3488 # load the A_CPU_TYPE_PCNT_CCNT core data array
3489 get_cpu_ht_multicore_smp_data
3490 ## Because of the upcoming release of cpus with core counts over 6, a count of cores is given after Deca (10)
3491 # count the number of processors given
3492 cpu_physical_count=${A_CPU_TYPE_PCNT_CCNT[1]}
3493 cpu_core_count=${A_CPU_TYPE_PCNT_CCNT[2]}
3494 cpu_type=${A_CPU_TYPE_PCNT_CCNT[0]}
3496 # match the numberic value to an alpha value
3497 cpu_alpha_count=$( get_cpu_core_count_alpha "$cpu_core_count" )
3499 # create array, core count integer; core count string
3500 # A_CPU_CORE_DATA=( "$cpu_core_count" "$cpu_alpha_count Core$cpu_type" )
3501 A_CPU_CORE_DATA=( "$cpu_physical_count" "$cpu_alpha_count" "$cpu_type" "$cpu_core_count" )
3502 elif [[ -n $BSD_TYPE ]];then
3505 if [[ $BSD_VERSION == 'openbsd' ]];then
3508 cpu_core_count=$( gawk -F "$gawk_fs" '
3509 # note: on openbsd can also be hw.ncpufound so exit after first
3513 }' <<< "$Sysctl_a_Data" )
3514 if [[ -n $( grep -E '^[0-9]+$' <<< "$cpu_core_count" ) ]];then
3515 cpu_alpha_count=$( get_cpu_core_count_alpha "$cpu_core_count" )
3516 if [[ $cpu_core_count -gt 1 ]];then
3520 cpu_physical_count=1
3521 A_CPU_CORE_DATA=( "$cpu_physical_count" "$cpu_alpha_count" "$cpu_type" "$cpu_core_count" )
3523 temp_array=${A_CPU_CORE_DATA[@]}
3524 log_function_data "A_CPU_CORE_DATA: $temp_array"
3528 # args: $1 - integer core count
3529 get_cpu_core_count_alpha()
3532 local cpu_alpha_count=''
3535 1) cpu_alpha_count='Single';;
3536 2) cpu_alpha_count='Dual';;
3537 3) cpu_alpha_count='Triple';;
3538 4) cpu_alpha_count='Quad';;
3539 5) cpu_alpha_count='Penta';;
3540 6) cpu_alpha_count='Hexa';;
3541 7) cpu_alpha_count='Hepta';;
3542 8) cpu_alpha_count='Octa';;
3543 9) cpu_alpha_count='Ennea';;
3544 10) cpu_alpha_count='Deca';;
3545 *) cpu_alpha_count='Multi';;
3548 echo $cpu_alpha_count
3553 ## main cpu data collector
3557 local i='' j='' cpu_array_nu='' a_cpu_working='' multi_cpu='' bits='' temp_array=''
3558 local bsd_cpu_flags=''
3560 if [[ $B_CPUINFO_FILE == 'true' ]];then
3561 # stop script for a bit to let cpu slow down before parsing cpu /proc file
3568 # need to prime nr for arm cpus, which do not have processor number output in some cases
3573 # TAKE STRONGER NOTE: \t+ does NOT always work, MUST be [ \t]+
3574 # TAKE NOTE: \t+ will work for $FILE_CPUINFO, but SOME ARBITRARY FILE used for TESTING might contain SPACES!
3575 # Therefore PATCH to use [ \t]+ when TESTING!
3576 /^processor[ \t]+:/ {
3578 gsub(/^ +| +$/, "", $NF)
3579 if ( $NF ~ "^[0-9]+$" ) {
3583 if ( $NF ~ "^ARM" ) {
3588 cpu[nr, "model"] = $NF
3592 /^model name|^cpu\t+:/ {
3593 gsub(/'"$BAN_LIST_NORMAL"'/, "", $NF )
3594 gsub(/'"$BAN_LIST_CPU"'/, "", $NF )
3596 gsub(/^ +| +$/, "", $NF)
3597 gsub(/ [ \t]+/, " ", $NF)
3598 cpu[nr, "model"] = $NF
3599 if ( $NF ~ "^ARM" ) {
3604 /^cpu MHz|^clock\t+:/ {
3617 gsub(/MHZ/,"",$NF) ## clears out for cell cpu
3618 gsub(/.00[0]+$/,".00",$NF) ## clears out excessive zeros
3619 cpu[nr, "speed"] = $NF
3623 cpu[nr, "cache"] = $NF
3626 /^flags|^features/ {
3627 cpu[nr, "flags"] = $NF
3628 # not all ARM cpus show ARM in model name
3629 if ( $1 ~ /^features/ ) {
3635 cpu[nr, "bogomips"] = $NF
3639 gsub(/genuine|authentic/,"",$NF)
3640 cpu[nr, "vendor"] = tolower( $NF )
3644 #if (!nr) { print ",,,"; exit } # <- should this be necessary or should bash handle that
3645 for ( i = 0; i <= nr; i++ ) {
3646 # note: assuming bogomips for arm at 1 x clock
3647 # http://en.wikipedia.org/wiki/BogoMips ARM could change so watch this
3648 # maybe add: && bArm == "true" but I think most of the bogomips roughly equal cpu speed if not amd/intel
3649 if ( cpu[i, "bogomips"] != "" && cpu[i, "speed"] == "" ) {
3650 cpu[i, "speed"] = cpu[i, "bogomips"]
3652 print cpu[i, "model"] "," cpu[i, "speed"] "," cpu[i, "cache"] "," cpu[i, "flags"] "," cpu[i, "bogomips"] "," cpu[nr, "vendor"] "," bArm
3654 # this is / was used in inxi short output only, but when it is N/A, need to use the previous array
3655 # value, from above, the actual speed that is, for short output, key 0.
3662 printf("Min:%s%s Max:%s%s\n", min, "Mhz", max, "Mhz")
3665 printf("%s %s\n", max, "Mhz")
3671 log_function_data 'cat' "$FILE_CPUINFO"
3672 elif [[ -n $BSD_TYPE ]];then
3676 temp_array=${A_CPU_DATA[@]}
3677 log_function_data "A_CPU_DATA: $temp_array"
3678 # echo ta: ${temp_array[@]}
3680 # echo getMainCpu: ${[@]}
3687 local bsd_cpu_flags=$( get_cpu_flags_bsd )
3690 if [[ $BSD_VERSION == 'openbsd' ]];then
3696 gawk -F "$gawk_fs" -v cpuFlags="$bsd_cpu_flags" '
3706 gsub(/'"$BAN_LIST_NORMAL"'/, "", $NF )
3707 gsub(/'"$BAN_LIST_CPU"'/, "", $NF )
3709 sub(/[a-z]+-core/, "", $NF )
3710 gsub(/^ +| +$|\"/, "", $NF)
3711 gsub(/ [ \t]+/, " ", $NF)
3713 if ( cpuClock != "" ) {
3717 /^hw.(clock|cpuspeed)/ {
3719 if ( cpuModel != "" ) {
3724 print cpuModel "," cpuClock "," cpuCache "," cpuFlags "," cpuBogomips "," cpuVendor
3726 }' <<< "$Sysctl_a_Data" ) )
3736 local cpu_flags=$( gawk -F '=' '
3742 while ( getline && !/memory/ ) {
3743 if ( $1 ~ /Features/ ) {
3744 # clean up odd stuff like <b23>
3745 gsub(/<[a-z0-9]+>/,"", $2)
3746 # all the flags are contained within < ... > on freebsd at least
3747 gsub(/.*<|>.*/,"", $2)
3749 cpuFlags = cpuFlags " " $2
3752 cpuFlags=tolower(cpuFlags)
3755 }' <<< "$Dmesg_Boot_Data" )
3758 log_function_data "$cpu_flags"
3762 ## this is for counting processors and finding HT types
3763 get_cpu_ht_multicore_smp_data()
3769 # note: known bug with xeon intel, they show a_core_id/physical_id as 0 for ht 4 core
3770 if [[ $B_CPUINFO_FILE == 'true' ]]; then
3771 A_CPU_TYPE_PCNT_CCNT=( $(
3777 num_of_processors = 0
3778 num_of_physical_cpus = 0
3781 # these 3 arrays cannot be declared because that sets the first element
3782 # but leaving this here so that we avoid doing that in the future
3784 # a_processor_id = ""
3785 # a_physical_id = ""
3787 # note: we need separate iterators because some cpuinfo data has only
3788 # processor, no core id or phys id
3790 core_iter = "" # set from actual NF data
3791 phys_iter = "" # set from actual NF data
3792 # needed to handle arm cpu, no processor number cases
3798 # hack to handle xeons which can have buggy /proc/cpuinfo files
3799 /^model name/ && ( $0 ~ /Xeon/ ) {
3802 # only do this once since sibling count does not change.
3803 /^siblings/ && ( bXeon == "true" ) && ( siblings == 0 ) {
3804 gsub(/[^0-9]/,"",$NF)
3809 # array of logical processors, both HT and physical
3813 gsub(/^ +| +$/, "", $NF)
3814 if ( $NF ~ "^[0-9]+$" ) {
3815 a_processor_id[proc_iter] = $NF
3819 # note, for dual core, this can be off by one because the first
3820 # line says: Processor : Arm.. but subsequent say: processor : 0 and so on as usual
3821 if ( $NF ~ "^ARM" ) {
3826 # note: do not iterate because new ARM syntax puts cpu in processsor : 0 syntax
3827 a_processor_id[proc_iter] = nr
3831 # array of physical cpu ids, note, this will be unset for vm cpus in many cases
3832 # because they have no physical cpu, so we cannot assume this will be here.
3835 a_physical_id[phys_iter] = $NF
3837 # array of core ids, again, here we may have HT, so we need to create an array of the
3838 # actual core ids. As With physical, we cannot assume this will be here in a vm
3841 a_core_id[core_iter] = $NF
3843 # this will be used to fix an intel glitch if needed, cause, intel
3844 # sometimes reports core id as the same number for each core,
3845 # so if cpu cores shows greater value than number of cores, use this.
3847 cpu_core_count = $NF
3850 ## Look thru the array and filter same numbers.
3851 ## only unique numbers required
3852 ## this is to get an accurate count
3853 ## we are only concerned with array length
3855 ## count unique processors ##
3856 # note, this fails for intel cpus at times
3857 for ( i in a_processor_id ) {
3861 ## count unique physical cpus ##
3862 for ( i in a_physical_id ) {
3863 num_of_physical_cpus++
3867 ## count unique cores ##
3868 for ( i in a_core_id ) {
3871 # xeon may show wrong core / physical id count, if it does, fix it. A xeon
3872 # may show a repeated core id : 0 which gives a fake num_of_cores=1
3873 if ( bXeon == "true" && num_of_cores == 1 && siblings > 1 ) {
3874 num_of_cores = siblings/2
3876 # final check, override the num of cores value if it clearly is wrong
3877 # and use the raw core count and synthesize the total instead of real count
3878 if ( ( num_of_cores == 0 ) && ( cpu_core_count * num_of_physical_cpus > 1 ) ) {
3879 num_of_cores = cpu_core_count * num_of_physical_cpus
3881 # last check, seeing some intel cpus and vms with intel cpus that do not show any
3882 # core id data at all, or siblings.
3883 if ( num_of_cores == 0 && num_of_processors > 0 ) {
3884 num_of_cores = num_of_processors
3886 # ARM/vm cpu fix, if no physical or core found, use count of 1 instead
3887 if ( num_of_physical_cpus == 0 ) {
3888 num_of_physical_cpus = 1
3890 # print "NoCpu: " num_of_physical_cpus
3891 # print "NoCores: " num_of_cores
3892 # print "NoProc:" num_of_processors
3893 # print "CpuCoreCount:" cpu_core_count
3894 ####################################################################
3896 # if > 1 processor && processor id (physical id) == core id then Hyperthreaded (HT)
3897 # if > 1 processor && processor id (physical id) != core id then Multi-Core Processors (MCP)
3898 # if > 1 processor && processor ids (physical id) > 1 then Multiple Processors (SMP)
3899 # if = 1 processor then single core/processor Uni-Processor (UP)
3900 if ( num_of_processors > 1 || ( bXeon == "true" && siblings > 0 ) ) {
3902 if ( num_of_processors == (num_of_cores * 2) ) {
3903 cpu_type = cpu_type "HT-"
3905 else if ( bXeon == "true" && siblings > 1 ) {
3906 cpu_type = cpu_type "HT-"
3908 # non-HT multi-core or HT multi-core
3909 if (( num_of_processors == num_of_cores) || ( num_of_physical_cpus < num_of_cores)) {
3910 cpu_type = cpu_type "MCP-"
3912 # >1 cpu sockets active
3913 if ( num_of_physical_cpus > 1 ) {
3914 cpu_type = cpu_type "SMP-"
3918 cpu_type = cpu_type "UP-"
3921 print cpu_type " " num_of_physical_cpus " " num_of_cores
3925 temp_array=${A_CPU_TYPE_PCNT_CCNT[@]}
3926 log_function_data "A_CPU_TYPE_PCNT_CCNT: $temp_array"
3930 # Detect desktop environment in use, initial rough logic from: compiz-check
3931 # http://forlong.blogage.de/entries/pages/Compiz-Check
3932 # NOTE $XDG_CURRENT_DESKTOP envvar is not reliable, but it shows certain desktops better.
3933 # most desktops are not using it as of 2014-01-13 (KDE, UNITY, LXDE. Not Gnome)
3934 get_desktop_environment()
3938 # set the default, this function only runs in X, if null, don't print data out
3939 local desktop_environment='' xprop_root=''
3940 local version='' version_data='' toolkit=''
3942 # works on 4, assume 5 will id the same, why not, no need to update in future
3943 # KDE_SESSION_VERSION is the integer version of the desktop
3944 if [[ $XDG_CURRENT_DESKTOP == 'KDE' || -n $KDE_SESSION_VERSION ]]; then
3945 # note the command is actually like, kded4 --version, so we construct it
3946 version_data=$( kded$KDE_SESSION_VERSION --version 2>/dev/null )
3947 version=$( grep -si '^KDE Development Platform:' <<< "$version_data" | gawk '{print $4}' )
3948 if [[ -z $version ]];then
3949 version=$KDE_SESSION_VERSION
3951 if [[ $B_EXTRA_DATA == 'true' ]];then
3952 toolkit=$( grep -si '^Qt:' <<< "$version_data" | gawk '{print $2}' )
3953 if [[ -n $toolkit ]];then
3954 version="$version (Qt $toolkit)"
3957 desktop_environment="KDE"
3958 # KDE_FULL_SESSION property is only available since KDE 3.5.5.
3959 # src: http://humanreadable.nfshost.com/files/startkde
3960 elif [[ $KDE_FULL_SESSION == 'true' ]]; then
3961 version_data=$( kded --version 2>/dev/null )
3962 version=$( grep -si '^KDE:' <<< "$version_data" | gawk '{print $2}' )
3963 # version=$( get_de_app_version 'kded' '^KDE:' '2' )
3964 if [[ -z $version ]];then
3967 if [[ $B_EXTRA_DATA == 'true' ]];then
3968 toolkit=$( grep -si '^Qt:' <<< "$version_data" | gawk '{print $2}' )
3969 if [[ -n $toolkit ]];then
3970 version="$version (Qt $toolkit)"
3973 desktop_environment="KDE"
3974 elif [[ $XDG_CURRENT_DESKTOP == 'Unity' ]];then
3975 version=$( get_de_app_version 'unity' '^unity' '2' )
3976 # not certain cinn will always have version, so keep output right if not
3977 if [[ -n $version ]];then
3980 if [[ $B_EXTRA_DATA == 'true' ]];then
3981 toolkit=$( get_de_gtk_data )
3982 if [[ -n $toolkit ]];then
3983 version="${version}(Gtk ${toolkit})"
3986 desktop_environment="Unity"
3988 # did we find it? If not, start the xprop tests
3989 if [[ -z $desktop_environment ]];then
3990 if [[ -n $( type -p xprop ) ]];then
3991 xprop_root="$( xprop -root 2>/dev/null )"
3993 # note that cinnamon split from gnome, and and can now be id'ed via xprop,
3994 # but it will still trigger the next gnome true case, so this needs to go before gnome test
3995 # eventually this needs to be better organized so all the xprop tests are in the same
3996 # section, but this is good enough for now.
3997 if [[ -n $xprop_root && -n $( grep -is '^_MUFFIN' <<< "$xprop_root" ) ]];then
3998 version=$( get_de_app_version 'cinnamon' '^cinnamon' '2' )
3999 # not certain cinn will always have version, so keep output right if not
4000 if [[ -n $version ]];then
4003 if [[ $B_EXTRA_DATA == 'true' ]];then
4004 toolkit=$( get_de_gtk_data )
4005 if [[ -n $toolkit ]];then
4006 version="${version}(Gtk ${toolkit})"
4009 desktop_environment="Cinnamon"
4010 elif [[ -n $xprop_root && -n $( grep -is '^_MARCO' <<< "$xprop_root" ) ]];then
4011 version=$( get_de_app_version 'mate-about' '^MATE[[:space:]]DESKTOP' 'NF' )
4012 # not certain cinn/mate will always have version, so keep output right if not
4013 if [[ -n $version ]];then
4016 if [[ $B_EXTRA_DATA == 'true' ]];then
4017 toolkit=$( get_de_gtk_data )
4018 if [[ -n $toolkit ]];then
4019 version="${version}(Gtk ${toolkit})"
4022 desktop_environment="MATE"
4023 # note, GNOME_DESKTOP_SESSION_ID is deprecated so we'll see how that works out
4024 # https://bugzilla.gnome.org/show_bug.cgi?id=542880
4025 elif [[ -n $GNOME_DESKTOP_SESSION_ID ]]; then
4026 if [[ -n $( type -p gnome-shell ) ]];then
4027 version=$( get_de_app_version 'gnome-shell' 'gnome' '3' )
4028 elif [[ -n $( type -p gnome-about ) ]];then
4029 version=$( get_de_app_version 'gnome-about' 'gnome' '3' )
4031 if [[ $B_EXTRA_DATA == 'true' ]];then
4032 toolkit=$( get_de_gtk_data )
4033 if [[ -n $toolkit ]];then
4034 version="$version (Gtk $toolkit)"
4037 desktop_environment="Gnome"
4039 if [[ -z $desktop_environment ]];then
4040 # now that the primary ones have been handled, next is to find the ones with unique
4041 # xprop detections possible
4042 if [[ -n $xprop_root ]];then
4043 # String: "This is xfdesktop version 4.2.12"
4044 # alternate: xfce4-about --version > xfce4-about 4.10.0 (Xfce 4.10)
4045 if [[ -n $( grep -Eis '\"xfce4\"' <<< "$xprop_root" ) ]];then
4046 version=$( get_de_app_version 'xfdesktop' 'xfdesktop[[:space:]]version' '5' )
4047 # arch linux reports null, so use alternate if null
4048 if [[ -z $version ]];then
4049 version=$( get_de_app_version 'xfce4-panel' '^xfce4-panel' '2' )
4050 if [[ -z $version ]];then
4054 if [[ $B_EXTRA_DATA == 'true' ]];then
4055 toolkit=$( get_de_app_version 'xfdesktop' 'Built[[:space:]]with[[:space:]]GTK' '4' )
4056 if [[ -n $toolkit ]];then
4057 version="$version (Gtk $toolkit)"
4060 desktop_environment="Xfce"
4061 # when 5 is released, the string may need updating
4062 elif [[ -n $( grep -is '\"xfce5\"' <<< "$xprop_root" ) ]];then
4063 version=$( get_de_app_version 'xfdesktop' 'xfdesktop[[:space:]]version' '5' )
4064 # arch linux reports null, so use alternate if null
4065 if [[ -z $version ]];then
4066 version=$( get_de_app_version 'xfce5-panel' '^xfce5-panel' '2' )
4067 if [[ -z $version ]];then
4071 if [[ $B_EXTRA_DATA == 'true' ]];then
4072 toolkit=$( get_de_app_version 'xfdesktop' 'Built[[:space:]]with[[:space:]]GTK' '4' )
4073 if [[ -n $toolkit ]];then
4074 version="$version (Gtk $toolkit)"
4077 desktop_environment="Xfce"
4078 elif [[ -n $( grep -is 'BLACKBOX_PID' <<< "$xprop_root" ) ]];then
4079 if [[ -n $( grep -is 'fluxbox' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4080 version=$( get_de_app_version 'fluxbox' '^fluxbox' '2' )
4081 desktop_environment='Fluxbox'
4083 desktop_environment='Blackbox'
4085 elif [[ -n $( grep -is 'OPENBOX_PID' <<< "$xprop_root" ) ]];then
4086 # note: openbox-lxde --version may be present, but returns openbox data
4087 version=$( get_de_app_version 'openbox' '^openbox' '2' )
4088 if [[ $XDG_CURRENT_DESKTOP == 'LXDE' || \
4089 -n $( grep -is 'lxde' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4090 if [[ -n $version ]];then
4091 version="(Openbox $version)"
4093 desktop_environment='LXDE'
4094 elif [[ -n $( grep -is 'razor-desktop' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4095 if [[ -n $version ]];then
4096 version="(Openbox $version)"
4098 desktop_environment='Razor-QT'
4100 desktop_environment='Openbox'
4102 elif [[ -n $( grep -is 'ICEWM' <<< "$xprop_root" ) ]];then
4103 version=$( get_de_app_version 'icewm' '^icewm' '2' )
4104 desktop_environment='IceWM'
4105 elif [[ -n $( grep -is 'ENLIGHTENMENT' <<< "$xprop_root" ) ]];then
4106 # no -v or --version but version is in xprop -root
4107 # ENLIGHTENMENT_VERSION(STRING) = "Enlightenment 0.16.999.49898"
4108 version=$( grep -is 'ENLIGHTENMENT_VERSION' <<< "$xprop_root" | cut -d '"' -f 2 | gawk '{print $2}' )
4109 desktop_environment='Enlightenment'
4110 elif [[ -n $( grep -is '^I3_' <<< "$xprop_root" ) ]];then
4111 version=$( get_de_app_version 'i3' '^i3' '3' )
4112 desktop_environment='i3'
4113 elif [[ -n $( grep -is 'WINDOWMAKER' <<< "$xprop_root" ) ]];then
4114 version=$( get_de_app_version 'wmaker' '^Window[[:space:]]*Maker' 'NF' )
4115 if [[ -n $version ]];then
4118 desktop_environment="WindowMaker"
4119 elif [[ -n $( grep -is '^_WM2' <<< "$xprop_root" ) ]];then
4120 # note; there isn't actually a wm2 version available but error handling should cover it and return null
4121 # maybe one day they will add it?
4122 version=$( get_de_app_version 'wm2' '^wm2' 'NF' )
4123 # not certain will always have version, so keep output right if not
4124 if [[ -n $version ]];then
4127 desktop_environment="WM2"
4128 elif [[ -n $( grep -is 'herbstluftwm' <<< "$xprop_root" ) ]];then
4129 version=$( get_de_app_version 'herbstluftwm' '^herbstluftwm' 'NF' )
4130 if [[ -n $version ]];then
4133 desktop_environment="herbstluftwm"
4136 # a few manual hacks for things that don't id with xprop, these are just good guesses
4137 # note that gawk is going to exit after first occurance of search string, so no need for extra
4138 if [[ -z $desktop_environment ]];then
4139 if [[ -n $( grep -is 'fvwm-crystal' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4140 version=$( get_de_app_version 'fvwm' '^fvwm' '2' )
4141 desktop_environment='FVWM-Crystal'
4142 elif [[ -n $( grep -is 'fvwm' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4143 version=$( get_de_app_version 'fvwm' '^fvwm' '2' )
4144 desktop_environment='FVWM'
4145 elif [[ -n $( grep -is 'pekwm' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4146 version=$( get_de_app_version 'pekwm' '^pekwm' '3' )
4147 desktop_environment='pekwm'
4148 elif [[ -n $( grep -is 'awesome' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4149 version=$( get_de_app_version 'awesome' '^awesome' '2' )
4150 desktop_environment='Awesome'
4151 elif [[ -n $( grep -is 'scrotwm' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4152 version=$( get_de_app_version 'scrotwm' '^welcome.*scrotwm' '4' )
4153 desktop_environment='Scrotwm' # no --version for this one
4154 elif [[ -n $( grep -is 'spectrwm' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4155 version=$( get_de_app_version 'spectrwm' '^spectrwm.*welcome.*spectrwm' '5' )
4156 desktop_environment='Spectrwm' # no --version for this one
4157 elif [[ -n $( grep -Eis '([[:space:]]|/)twm' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4158 desktop_environment='Twm' # no --version for this one
4159 elif [[ -n $( grep -Eis '([[:space:]]|/)dwm' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4160 version=$( get_de_app_version 'dwm' '^dwm' '1' )
4161 desktop_environment='dwm'
4162 elif [[ -n $( grep -is 'wmii2' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4163 version=$( get_de_app_version 'wmii2' '^wmii2' '1' )
4164 desktop_environment='wmii2'
4165 # note: in debian at least, wmii is actuall wmii3
4166 elif [[ -n $( grep -is 'wmii' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4167 version=$( get_de_app_version 'wmii' '^wmii' '1' )
4168 desktop_environment='wmii'
4169 elif [[ -n $( grep -Eis '([[:space:]]|/)jwm' <<< "$Ps_aux_Data" | grep -v 'grep' ) ]];then
4170 version=$( get_de_app_version 'jwm' '^jwm' '2' )
4171 desktop_environment='JWM'
4176 if [[ -n $version ]];then
4179 echo "$desktop_environment${version}"
4183 # note: gawk doesn't support white spaces in search string, gave errors, so use [[:space:]] instead
4184 # args: $1 - desktop/app command for --version; $2 - search string; $3 - gawk print number
4185 get_de_app_version()
4187 local version_data='' version='' get_version='--version'
4189 # mate-about -v = MATE Desktop Environment 1.4.0
4191 dwm|jwm|mate-about|wmii|wmii2)
4195 get_version='version'
4200 # note, some wm/apps send version info to stderr instead of stdout
4201 dwm|ksh|scrotwm|spectrwm)
4202 version_data="$( $1 $get_version 2>&1 )"
4205 version_data="$( tcsh $get_version 2>/dev/null )"
4207 # quick debian/buntu hack until I find a universal way to get version for these
4209 if [[ -n $( type -p dpkg ) ]];then
4210 version_data="$( dpkg -l $1 2>/dev/null )"
4214 version_data="$( $1 $get_version 2>/dev/null )"
4218 if [[ -n $version_data ]];then
4224 # sample: dwm-5.8.2, ©.. etc, why no space? who knows. Also get rid of v in number string
4225 # xfce, and other, output has , in it, so dump all commas and parentheses
4226 gsub(/(,|dwm-|wmii2-|wmii-|v|V|\(|\))/, "",$'$3')
4228 exit # quit after first match prints
4229 }' <<< "$version_data" )
4234 get_desktop_extra_data()
4237 local de_data=$( ps -A | gawk '
4243 /(gnome-shell|gnome-panel|kicker|lxpanel|mate-panel|plasma-desktop|xfce4-panel)$/ {
4244 # only one entry per type, can be multiple
4245 if ( desktops !~ $NF ) {
4246 desktops = desktops separator $NF
4265 # this is a hack, and has to be changed with every toolkit version change, and only dev systems
4266 # have this installed, but it's a cross distro command so let's test it first
4267 if [[ -n $( type -p pkg-config ) ]];then
4268 toolkit=$( pkg-config --modversion gtk+-4.0 2>/dev/null )
4269 # note: opensuse gets null output here, we need the command to get version and output sample
4270 if [[ -z $toolkit ]];then
4271 toolkit=$( pkg-config --modversion gtk+-3.0 2>/dev/null )
4273 if [[ -z $toolkit ]];then
4274 toolkit=$( pkg-config --modversion gtk+-2.0 2>/dev/null )
4277 # now let's go to more specific version tests, this will never cover everything and that's fine.
4278 if [[ -z $toolkit ]];then
4279 # we'll try some known package managers next. dpkg will handle a lot of distros
4280 # this is the most likely order as of: 2014-01-13. Not going to try to support all package managers
4281 # too much work, just the very biggest ones.
4282 if [[ -n $( type -p dpkg ) ]];then
4283 toolkit=$( dpkg -s libgtk-3-0 2>/dev/null | gawk -F ':' '/^Version/ {print $2}' )
4284 if [[ -z $toolkit ]];then
4285 toolkit=$( dpkg -s libgtk2.0-0 2>/dev/null | gawk -F ':' '/^Version/ {print $2}' )
4287 # just guessing on gkt 4 package name
4288 if [[ -z $toolkit ]];then
4289 toolkit=$( dpkg -s libgtk-4-0 2>/dev/null | gawk -F ':' '/^Version/ {print $2}' )
4291 elif [[ -n $( type -p pacman ) ]];then
4292 toolkit=$( pacman -Qi gtk3 2>/dev/null | gawk -F ':' '/^Version/ {print $2}' )
4293 if [[ -z $toolkit ]];then
4294 toolkit=$( pacman -Qi gtk2 2>/dev/null | gawk -F ':' '/^Version/ {print $2}' )
4303 # see which dm has started if any
4304 get_display_manager()
4307 # ldm - LTSP display manager
4308 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'
4309 local dm_id='' dm='' separator=''
4310 # note we don't need to filter grep if we do it this way
4311 local x_is_running=$( grep '/usr.*/X' <<< "$Ps_aux_Data" | grep -iv '/Xprt' )
4313 for dm_id in $dm_id_list
4315 if [[ -e /var/run/$dm_id || -e /run/$dm_id ]];then
4316 # just on the off chance that two dms are running, good info to have in that case, if possible
4317 dm=$dm$separator$( basename $dm_id | cut -d '.' -f 1 )
4321 # might add this in, but the rate of new dm's makes it more likely it's an unknown dm, so
4322 # we'll keep output to N/A
4323 if [[ -n $x_is_running && -z $dm ]];then
4324 if [[ -n $( grep 'startx$' <<< "$Ps_aux_Data" ) ]];then
4330 log_function_data "display manager: $dm"
4335 # for more on distro id, please reference this python thread: http://bugs.python.org/issue1322
4336 ## return distro name/id if found
4340 local i='' j='' distro='' distro_file='' a_distro_glob='' temp_array=''
4342 # may need modification if archbsd / debian can be id'ed with /etc files
4343 if [[ -n $BSD_TYPE ]];then
4344 distro=$( uname -sr )
4346 log_function_data "distro: $distro"
4351 # get the wild carded array of release/version /etc files if present
4354 # note: always exceptions, so wild card after release/version: /etc/lsb-release-crunchbang
4355 # wait to handle since crunchbang file is one of the few in the world that uses this method
4356 a_distro_glob=(*[-_]{release,version})
4360 temp_array=${a_distro_glob[@]}
4361 log_function_data "A_GLX_DATA: $temp_array"
4363 if [[ ${#a_distro_glob[@]} -eq 1 ]];then
4364 distro_file="${a_distro_glob}"
4365 # use the file if it's in the known good lists
4366 elif [[ ${#a_distro_glob[@]} -gt 1 ]];then
4367 for i in $DISTROS_DERIVED $DISTROS_PRIMARY
4369 # Only echo works with ${var[@]}, not print_screen_output() or script_debugger()
4370 # This is a known bug, search for the word "strange" inside comments
4371 # echo "i='$i' a_distro_glob[@]='${a_distro_glob[@]}'"
4372 if [[ " ${a_distro_glob[@]} " == *" $i "* ]];then
4373 # Now lets see if the distro file is in the known-good working-lsb-list
4374 # if so, use lsb-release, if not, then just use the found file
4375 # this is for only those distro's with self named release/version files
4376 # because Mint does not use such, it must be done as below
4377 ## this if statement requires the spaces and * as it is, else it won't work
4379 if [[ " $DISTROS_LSB_GOOD " == *" ${i} "* ]] && [[ $B_LSB_FILE == 'true' ]];then
4380 distro_file='lsb-release'
4381 elif [[ " $DISTROS_OS_RELEASE_GOOD " == *" ${i} "* ]] && [[ $B_OS_RELEASE_FILE == 'true' ]];then
4382 distro_file='os-release'
4390 log_function_data "distro_file: $distro_file"
4391 # first test for the legacy antiX distro id file
4392 if [[ -e /etc/antiX ]];then
4393 distro="$( grep -Eoi 'antix.*\.iso' <<< $( remove_erroneous_chars '/etc/antiX' ) | sed 's/\.iso//' )"
4394 # this handles case where only one release/version file was found, and it's lsb-release. This would
4395 # never apply for ubuntu or debian, which will filter down to the following conditions. In general
4396 # if there's a specific distro release file available, that's to be preferred, but this is a good backup.
4397 elif [[ -n $distro_file && $B_LSB_FILE == 'true' && " $DISTROS_LSB_GOOD" == *" $distro_file "* ]];then
4398 distro=$( get_distro_lsb_os_release_data 'lsb-file' )
4399 elif [[ $distro_file == 'lsb-release' ]];then
4400 distro=$( get_distro_lsb_os_release_data 'lsb-file' )
4401 elif [[ $distro_file == 'os-release' ]];then
4402 distro=$( get_distro_lsb_os_release_data 'os-release-file' )
4403 # then if the distro id file was found and it's not in the exluded primary distro file list, read it
4404 elif [[ -n $distro_file && -s /etc/$distro_file && " $DISTROS_EXCLUDE_LIST " != *" $distro_file "* ]];then
4405 # new opensuse uses os-release, but older ones may have a similar syntax, so just use the first line
4406 if [[ $distro_file == 'SuSE-release' ]];then
4407 # leaving off extra data since all new suse have it, in os-release, this file has line breaks, like os-release
4408 # but in case we want it, it's: CODENAME = Mantis | VERSION = 12.2
4409 # for now, just take first occurance, which should be the first line, which does not use a variable type format
4410 distro=$( grep -i -m 1 'suse' /etc/$distro_file )
4412 distro=$( remove_erroneous_chars "/etc/$distro_file" )
4414 # otherwise try the default debian/ubuntu /etc/issue file
4415 elif [[ -f /etc/issue ]];then
4416 # lsb gives more manageable and accurate output than issue, but mint should use issue for now
4417 # some bashism, boolean must be in parenthesis to work correctly, ie [[ $(boolean) ]] not [[ $boolean ]]
4418 if [[ $B_LSB_FILE == 'true' ]] && [[ -z $( grep -i 'mint' /etc/issue ) ]];then
4419 distro=$( get_distro_lsb_os_release_data 'lsb-file' )
4429 gsub(/ [ \t]+/, " ")
4433 # this handles an arch bug where /etc/arch-release is empty and /etc/issue is corrupted
4434 # only older arch installs that have not been updated should have this fallback required, new ones use
4436 if [[ -n $( grep -i 'arch linux' <<< $distro ) ]];then
4442 if [[ ${#distro} -gt 80 ]] && [[ $B_HANDLE_CORRUPT_DATA != 'true' ]];then
4443 distro="${RED}/etc/${distro_file} corrupted, use -% to override${NORMAL}"
4445 ## note: would like to actually understand the method even if it's not used
4446 # : ${distro:=Unknown distro o_O}
4447 ## test for /etc/lsb-release as a backup in case of failure, in cases where > one version/release file
4448 ## were found but the above resulted in null distro value
4449 if [[ -z $distro ]] && [[ $B_LSB_FILE == 'true' ]];then
4450 distro=$( get_distro_lsb_os_release_data 'lsb-file' )
4452 if [[ -z $distro ]] && [[ $B_OS_RELEASE_FILE == 'true' ]];then
4453 distro=$( get_distro_lsb_os_release_data 'os-release-file' )
4455 # now some final null tries
4456 if [[ -z $distro ]];then
4457 # if the file was null but present, which can happen in some cases, then use the file name itself to
4458 # set the distro value. Why say unknown if we have a pretty good idea, after all?
4459 if [[ -n $distro_file ]] && [[ " $DISTROS_DERIVED $DISTROS_PRIMARY " == *" $distro_file "* ]];then
4460 distro=$( sed $SED_RX -e 's/[-_]//' -e 's/(release|version)//' <<< $distro_file | sed $SED_RX 's/^([a-z])/\u\1/' )
4462 ## finally, if all else has failed, give up
4463 if [[ -z $distro ]];then
4467 # final step cleanup of unwanted information
4468 # opensuse has the x86 etc type string in names, not needed as redundant since -S already shows that
4474 sub(/ *\(*(x86_64|i486|i586|i686|686|586|486)\)*/, "", $0)
4478 log_function_data "distro: $distro"
4482 # args: $1 - lsb-file/lsb-app/os-release-file
4483 get_distro_lsb_os_release_data()
4490 if [[ $B_LSB_FILE == 'true' ]];then
4491 distro=$( gawk -F '=' '
4495 # clean out unwanted characters
4497 gsub(/\\|\"|[:\47]/,"", $0 )
4498 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2 )
4499 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $1 )
4501 # note: adding the spacing directly to variable to make sure distro output is null if not found
4503 # this is needed because grep for "arch" is too loose to be safe
4504 if ( $2 == "arch" ) {
4505 distroId = "Arch Linux"
4507 else if ( $2 != "n/a" ) {
4511 /^DISTRIB_RELEASE/ {
4512 if ( $2 != "n/a" ) {
4513 distroRelease = $2 " "
4516 /^DISTRIB_CODENAME/ {
4517 if ( $2 != "n/a" ) {
4518 distroCodename = $2 " "
4521 # sometimes some distros cannot do their lsb-release files correctly, so here is
4522 # one last chance to get it right.
4523 /^DISTRIB_DESCRIPTION/ {
4524 if ( $2 != "n/a" ) {
4525 distroDescription = $2
4530 if ( distroId == "" && distroRelease == "" && distroCodename == "" && distroDescription != "" ){
4531 fullString = distroDescription
4534 fullString = distroId distroRelease distroCodename
4538 ' $FILE_LSB_RELEASE )
4539 log_function_data 'cat' "$FILE_LSB_RELEASE"
4543 # this is HORRIBLY slow, not using
4544 if [[ -n $( type -p lsb_release ) ]];then
4545 distro=$( echo "$( lsb_release -irc )" | gawk -F ':' '
4549 # clean out unwanted characters
4551 gsub(/\\|\"|[:\47]/,"", $0 )
4552 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2 )
4553 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $1 )
4565 print distroId " " distroRelease " (" distroCodename ")"
4570 if [[ $B_OS_RELEASE_FILE == 'true' ]];then
4571 distro=$( gawk -F '=' '
4580 # clean out unwanted characters
4582 gsub(/\\|\"|[:\47]/,"", $0 )
4583 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $2 )
4584 gsub(/^[[:space:]]+|[[:space:]]+$/, "", $1 )
4586 # note: adding the spacing directly to variable to make sure distro output is null if not found
4588 if ( $2 != "n/a" ) {
4593 if ( $2 != "n/a" ) {
4598 if ( $2 != "n/a" && $1 == "VERSION" ) {
4601 else if ( $2 != "n/a" && $1 == "VERSION_ID" ) {
4606 if ( prettyName != "" ) {
4607 distroName = prettyName
4609 else if ( regularName != "" ) {
4610 distroName = regularName
4611 if ( versionName != "" ) {
4612 distroName = distroName " " versionName
4614 else if ( versionId != "" ) {
4615 distroName = distroName " " versionId
4621 ' $FILE_OS_RELEASE )
4622 log_function_data 'cat' "$FILE_OS_RELEASE"
4627 log_function_data "distro: $distro"
4631 get_dmidecode_data()
4635 local dmidecodePath=''
4637 if [[ $B_DMIDECODE_SET != 'true' ]];then
4638 dmidecodePath=$( type -p dmidecode 2>/dev/null )
4639 if [[ -n $dmidecodePath ]];then
4640 # note stripping out these lines: Handle 0x0016, DMI type 17, 27 bytes
4641 # but NOT deleting them, in case the dmidecode data is missing empty lines which will be
4642 # used to separate results. Then we remove the doubled empty lines to keep it clean and
4643 # strip out all the stuff we don't want to see in the results.
4644 DMIDECODE_DATA="$( $dmidecodePath 2>/dev/null \
4653 # no idea why, but freebsd gawk does not do this right
4656 if ( twoData != "" ) {
4662 if ( $0 ~ /^\tDMI type/ ) {
4663 sub(/^\tDMI type.*/, "", $0)
4666 gsub(/'"$BAN_LIST_NORMAL"'/, "", twoData)
4668 # clean out Handle line
4669 sub(/^Handle.*/,"", $0)
4670 sub(/^[[:space:]]*Inactive.*/,"",$0)
4671 # yes, there is a typo in a user data set, unknow
4672 # Base Board Version|Base Board Serial Number
4673 # Chassis Manufacturer|Chassis Version|Chassis Serial Number
4674 # System manufacturer|System Product Name|System Version
4675 # To Be Filled By O.E.M.
4676 # strip out starting white space so that the following stuff will clear properly
4677 sub(/^[[:space:]]+/, "", twoData)
4678 sub(/^Base Board .*|^Chassis .*|.*O\.E\.M\..*|.*OEM.*|^Not .*|^System .*|.*unknow.*|.*N\/A.*|none|^To be filled.*/, "", twoData)
4679 gsub(/bios|acpi/, "", twoData)
4680 sub(/http:\/\/www.abit.com.tw\//, "Abit", twoData)
4682 # for double indented values replace with ~ so later can test for it, we are trusting that
4683 # indentation will be tabbed in this case
4684 # special case, dmidecode 2.2 has an extra tab and a DMI type line
4685 if ( cutExtraTab == "true" ) {
4686 sub(/^\t\t\t+/, "~", oneData)
4689 sub(/^\t\t+/, "~", oneData)
4692 gsub(/^[[:space:]]+|[[:space:]]+$/, "", twoData)
4693 gsub(/^[[:space:]]+|[[:space:]]+$/, "", oneData)
4694 gsub(/ [ \t]+/, " ", twoData)
4695 # reconstructing the line for processing so gawk can use -F : again
4696 if ( oneData != "" && twoHolder == "true" ) {
4697 print oneData ":" twoData
4709 B_DMIDECODE_SET='true'
4710 log_function_data "DMIDECODE_DATA: $DMIDECODE_DATA"
4715 # get_dmidecode_data;echo "$DMIDECODE_DATA";exit
4718 get_dmesg_boot_data()
4722 local dmsg_boot_data=''
4724 if [[ $B_DMESG_BOOT_FILE == 'true' ]];then
4725 # replace all indented items with ~ so we can id them easily while processing
4726 dmsg_boot_data="$( cat $FILE_DMESG_BOOT | sed $SED_RX 's/"//g' )"
4728 echo "$dmsg_boot_data"
4729 # log_function_data "$dmsg_boot_data"
4733 get_gcc_kernel_version()
4735 # note that we use gawk to get the last part because beta, alpha, git versions can be non-numeric
4738 if [[ -e /proc/version ]];then
4739 gccVersion=$( grep -Eio 'gcc[[:space:]]*version[[:space:]]*([^ \t]*)' /proc/version 2>/dev/null | gawk '{print $3}' )
4744 get_gcc_system_version()
4747 local separator='' gcc_installed='' gcc_list='' gcc_others='' temp_array=''
4748 local gcc_version=$(
4749 gcc --version 2>/dev/null | sed $SED_RX 's/\([^\)]*\)//g' | gawk '
4758 # can't use xargs -L basename because not all systems support thats
4759 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
4760 gcc_others=$( ls /usr/bin/gcc-* 2>/dev/null )
4761 if [[ -n $gcc_others ]];then
4762 for item in $gcc_others
4764 gcc_installed=$( basename $item | gawk -F '-' '
4768 if [[ -n $gcc_installed && -z $( grep "^$gcc_installed" <<< $gcc_version ) ]];then
4769 gcc_list=$gcc_list$separator$gcc_installed
4775 if [[ -n $gcc_version ]];then
4776 A_GCC_VERSIONS=( "$gcc_version" $gcc_list )
4778 temp_array=${A_GCC_VERSIONS[@]}
4779 log_function_data "A_GCC_VERSIONS: $temp_array"
4784 local gpu_temp='' gpu_fan='' screens='' screen_nu='' gpu_temp_looper=''
4786 # we'll try for nvidia/ati, then add if more are shown
4787 if [[ -n $( type -p nvidia-settings ) ]];then
4788 # first get the number of screens
4789 screens=$( nvidia-settings -q screens | gawk '
4791 screens=screens gensub(/(.*)(:[0-9]\.[0-9])(.*)/, "\\2", "1", $0) " "
4797 # now we'll get the gpu temp for each screen discovered. The print out function
4798 # will handle removing screen data for single gpu systems
4799 for screen_nu in $screens
4801 gpu_temp_looper=$( nvidia-settings -c $screen_nu -q GPUCoreTemp | gawk -F ': ' '
4807 /Attribute (.*)[0-9]+\.$/ {
4809 if ( $2 ~ /^[0-9]+$/ ) {
4810 gpuTemp=gpuTemp $2 "C "
4816 screen_nu=$( cut -d ':' -f 2 <<< $screen_nu )
4817 gpu_temp="$gpu_temp$screen_nu:$gpu_temp_looper "
4819 elif [[ -n $( type -p aticonfig ) ]];then
4820 # gpu_temp=$( aticonfig --adapter=0 --od-gettemperature | gawk -F ': ' '
4821 gpu_temp=$( aticonfig --adapter=all --od-gettemperature | gawk -F ': ' '
4827 /Sensor (.*)[0-9\.]+ / {
4828 gpuTempWorking=gensub(/(.*) ([0-9\.]+) (.*)/, "\\2", "1", $2)
4829 if ( gpuTempWorking ~ /^[0-9\.]+$/ ) {
4830 gpuTemp=gpuTemp gpuTempWorking "C "
4836 # this handles some newer cases of free driver temp readouts, will require modifications as
4837 # more user data appears.
4838 elif [[ -n $Sensors_Data ]];then
4846 /^('"$SENSORS_GPU_SEARCH"')-pci/ {
4847 while ( getline && !/^$/ ) {
4849 sub(/^[[:alnum:]]*.*:/, "", $0 ) # clear out everything to the :
4850 gsub(/[\+ \t°]/, "", $1) # ° is a special case, like a space for gawk
4851 gpuTemp=gpuTemp separator $1
4858 }' <<< "$Sensors_Data" )
4861 if [[ -n $gpu_temp ]];then
4866 ## for possible future data, not currently used
4867 get_graphics_agp_data()
4872 if [[ $B_MODULES_FILE == 'true' ]];then
4873 ## not used currently
4874 agp_module=$( gawk '
4875 /agp/ && !/agpgart/ && $3 > 0 {
4876 print(gensub(/(.*)_agp.*/,"\\1","g",$1))
4878 log_function_data 'cat' "$FILE_MODULES"
4880 log_function_data "agp_module: $agp_module"
4884 ## create array of gfx cards installed on system
4885 get_graphics_card_data()
4888 local i='' temp_array=''
4891 A_GRAPHICS_CARD_DATA=( $( gawk -F': ' '
4896 /vga compatible controller/ {
4897 gsub(/'"$BAN_LIST_NORMAL"'/, "", $NF)
4899 gsub(/^ +| +$/, "", $NF)
4900 gsub(/ [ \t]+/, " ", $NF)
4901 busId=gensub(/^([0-9a-f:\.]+) (.+)$/,"\\1","",$1)
4903 }' <<< "$Lspci_v_Data" ) )
4905 # for (( i=0; i < ${#A_GRAPHICS_CARD_DATA[@]}; i++ ))
4907 # A_GRAPHICS_CARD_DATA[i]=$( sanitize_characters BAN_LIST_NORMAL "${A_GRAPHICS_CARD_DATA[i]}" )
4910 # GFXMEM is UNUSED at the moment, because it shows AGP aperture size, which is not necessarily equal to GFX memory..
4911 # 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]"
4912 temp_array=${A_GRAPHICS_CARD_DATA[@]}
4913 log_function_data "A_GRAPHICS_CARD_DATA: $temp_array"
4917 get_graphics_driver()
4921 # list is from sgfxi plus non-free drivers
4922 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'
4923 local driver='' driver_string='' xorg_log_data='' status='' temp_array=''
4925 if [[ $B_XORG_LOG == 'true' ]];then
4926 A_GRAPHIC_DRIVERS=( $(
4933 # note that in file names, driver is always lower case
4934 /[[:space:]]Loading.*('"$driver_list"')_drv.so$/ {
4935 driver=gensub(/.*[[:space:]]Loading.*('"$driver_list"')_drv.so/, "\\1", 1, $0 )
4936 # we get all the actually loaded drivers first, we will use this to compare the
4937 # failed/unloaded, which have not always actually been truly loaded
4938 aDrivers[driver]="loaded"
4940 /Unloading[[:space:]].*('"$driver_list"')(|_drv.so)$/ {
4941 driver=gensub(/(.*)Unloading[[:space:]].*('"$driver_list"')(|_drv.so)$/, "\\2", 1, $0 )
4942 # we need to make sure that the driver has already been truly loaded, not just discussed
4943 if ( driver in aDrivers ) {
4944 aDrivers[driver]="unloaded"
4947 /Failed.*('"$driver_list"')_drv.so|Failed.*\"('"$driver_list"')\"/ {
4948 driver=gensub(/(.*)Failed.*('"$driver_list"')_drv.so/, "\\2", 1, $0 )
4949 if ( driver == $0 ) {
4950 driver=gensub(/(.*)Failed.*\"('"$driver_list"')\".*|fred/, "\\2", 1, $0 )
4952 # we need to make sure that the driver has already been truly loaded, not just discussed
4953 if ( driver != $0 && driver in aDrivers ) {
4954 aDrivers[driver]="failed"
4957 # verify that the driver actually started the desktop, even with false failed messages which can occur
4958 # this is the driver that is actually driving the display
4959 /.*\([0-9]+\):[[:space:]]Depth.*framebuffer/ {
4960 driver=gensub(/.*('"$driver_list"')\([0-9]+\):[[:space:]]Depth.*framebuffer.*/, "\\1", 1, $0 )
4961 # we need to make sure that the driver has already been truly loaded, not just discussed, also
4962 # set driver to lower case because sometimes it will show as RADEON or NVIDIA in the actual x start
4963 driver=tolower(driver)
4964 if ( driver != $0 && driver in aDrivers ) {
4965 aDrivers[driver]="loaded"
4969 for ( driver in aDrivers ) {
4970 print driver "," aDrivers[driver]
4972 }' < $FILE_XORG_LOG ) )
4974 temp_array=${A_GRAPHIC_DRIVERS[@]}
4975 log_function_data "A_GRAPHIC_DRIVERS: $temp_array"
4980 ## create array of glx data
4981 get_graphics_glx_data()
4985 if [[ $B_SHOW_DISPLAY_DATA == 'true' && $B_ROOT != 'true' ]];then
4987 A_GLX_DATA=( $( glxinfo | gawk -F ': ' '
4988 # note: function declarations go before BEGIN? It appears so, confirm.
4989 # the real question here though is why this function is even here, seems
4990 # just to be a complicated way to pack/print a variable, but maybe the
4991 # original idea was to handle > 1 cases of detections I guess
4992 function join( arr, sep ) {
5008 gsub(/'"$BAN_LIST_NORMAL"'/, "", $2)
5009 gsub(/ [ \t]+/, " ", $2) # get rid of the created white spaces
5010 gsub(/^ +| +$/, "", $2)
5011 if ( $2 ~ /mesa/ ) {
5013 # if ( $2 ~ / r[3-9][0-9][0-9] / ) {
5015 # this counter failed in one case, a bug, and is not needed now
5023 # dropping all conditions from this test to just show full mesa information
5024 # there is a user case where not f and mesa apply, atom mobo
5025 # /opengl version/ && ( f || $2 !~ /mesa/ ) {
5027 # fglrx started appearing with this extra string, does not appear to communicate anything of value
5028 sub(/Compatibility Profile Context/, "- CPC", $2 )
5029 gsub(/ [ \t]+/, " ", $2) # get rid of the created white spaces
5030 gsub(/^ +| +$/, "", $2)
5033 /direct rendering/ {
5037 printf( "%s\n%s\n%s\n", join( a, ", " ), join( b, ", " ), join( c, ", " ) )
5041 # GLXR=$(glxinfo | gawk -F ': ' 'BEGIN {IGNORECASE=1} /opengl renderer/ && $2 !~ /mesa/ {seen[$2]++} END {for (i in seen) {printf("%s ",i)}}')
5042 # GLXV=$(glxinfo | gawk -F ': ' 'BEGIN {IGNORECASE=1} /opengl version/ && $2 !~ /mesa/ {seen[$2]++} END {for (i in seen) {printf("%s ",i)}}')
5044 temp_array=${A_GLX_DATA[@]}
5045 log_function_data "A_GLX_DATA: $temp_array"
5049 ## return screen resolution / tty resolution
5050 get_graphics_res_data()
5053 local screen_resolution='' xdpy_data='' screens_count=0 tty_session=''
5055 if [[ $B_SHOW_DISPLAY_DATA == 'true' && $B_ROOT != 'true' ]];then
5056 # Added the two ?'s , because the resolution is now reported without spaces around the 'x', as in
5057 # 1400x1050 instead of 1400 x 1050. Change as of X.org version 1.3.0
5058 xdpy_data="$( xdpyinfo )"
5059 xdpy_count=$( grep -c 'dimensions' <<< "$xdpy_data" )
5060 # we get a bit more info from xrandr than xdpyinfo, but xrandr fails to handle
5061 # multiple screens from different video cards
5062 if [[ $xdpy_count -eq 1 ]];then
5063 screen_resolution=$( xrandr | gawk '
5065 res[++m] = gensub(/^.* ([0-9]+) ?x ?([0-9]+)[_ ].* ([0-9\.]+)\*.*$/,"\\1x\\2@\\3hz","g",$0)
5069 if (res[n] ~ /^[[:digit:]]+x[[:digit:]]+/) {
5070 line = line ? line ", " res[n] : res[n]
5078 if [[ -z $screen_resolution || $xdpy_count -gt 1 ]];then
5079 screen_resolution=$( gawk '
5086 screens = screens separator # first time, this is null, next, has comma last
5087 screens = screens $2 # then tack on the new value for nice comma list
5092 }' <<< "$xdpy_data" )
5095 if [[ $B_PROC_DIR == 'true' && -z $BSD_TYPE ]];then
5096 screen_resolution=$( stty -F $( readlink /proc/$PPID/fd/0 ) size | gawk '{
5099 # note: this works fine for all systems but keeping the above for now since
5100 # the above is probably more accurate for linux systems.
5102 if [[ $B_CONSOLE_IRC != 'true' ]];then
5103 screen_resolution=$( stty -a | gawk -F ';' '
5105 gsub(/[[:space:]]*(rows|columns)[[:space:]]*/,"",$0)
5106 gsub(/[[:space:]]*/,"",$2)
5107 gsub(/[[:space:]]*/,"",$3)
5111 if [[ -n $BSD_TYPE ]];then
5112 tty_session=$( get_tty_console_irc )
5113 # getting information for tty that owns the irc client
5114 screen_resolution="$( stty -f /dev/pts/$tty_session size | gawk '{print $2"x"$1}' )"
5119 echo "$screen_resolution"
5120 log_function_data "screen_resolution: $screen_resolution"
5124 ## create array of display server vendor/version data
5125 get_graphics_display_server_data()
5128 local vendor='' version='' temp_array='' xdpy_info='' a_display_vendor_working=''
5130 if [[ $B_SHOW_DISPLAY_DATA == 'true' && $B_ROOT != 'true' ]];then
5131 # X vendor and version detection.
5132 # new method added since radeon and X.org and the disappearance of <X server name> version : ...etc
5133 # Later on, the normal textual version string returned, e.g. like: X.Org version: 6.8.2
5134 # A failover mechanism is in place. (if $version is empty, the release number is parsed instead)
5135 # xdpy_info="$( xdpyinfo )"
5137 a_display_vendor_working=( $( xdpyinfo | gawk -F': +' '
5145 gsub(/the|inc|foundation|project|corporation/, "", $2)
5147 gsub(/^ +| +$/, "", $2)
5148 gsub(/ [ \t]+/, " ", $2)
5154 /vendor release number/ {
5160 print vendorString "," version "," vendorRelease
5162 vendor=${a_display_vendor_working[0]}
5163 version=${a_display_vendor_working[1]}
5165 # this gives better output than the failure last case, which would only show:
5166 # for example: X.org: 1.9 instead of: X.org: 1.9.0
5167 if [[ -z $version ]];then
5168 version=$( get_graphics_display_server_version )
5170 if [[ -z $version ]];then
5171 version=${a_display_vendor_working[2]}
5174 # some distros, like fedora, report themselves as the xorg vendor, so quick check
5175 # here to make sure the vendor string includes Xorg in string
5176 if [[ -z $( grep -E '(X|xorg|x\.org)' <<< $vendor ) ]];then
5177 vendor="$vendor X.org"
5180 A_DISPLAY_SERVER_DATA[0]="$vendor"
5181 A_DISPLAY_SERVER_DATA[1]="$version"
5183 version=$( get_graphics_display_server_version )
5184 if [[ -n $version ]];then
5186 A_DISPLAY_SERVER_DATA[0]="$vendor"
5187 A_DISPLAY_SERVER_DATA[1]="$version"
5190 temp_array=${A_DISPLAY_SERVER_DATA[@]}
5191 log_function_data "A_DISPLAY_SERVER_DATA: $temp_array"
5195 # if other tests fail, try this one, this works for root, out of X also
5196 get_graphics_display_server_version()
5199 local version='' x_data=''
5200 # note that some users can have /usr/bin/Xorg but not /usr/bin/X
5201 if [[ -n $( type -p X ) ]];then
5202 # note: MUST be this syntax: X -version 2>&1
5203 # otherwise X -version overrides everything and this comes out null.
5204 # two knowns id strings: X.Org X Server 1.7.5 AND X Window System Version 1.7.5
5205 #X -version 2>&1 | gawk '/^X Window System Version/ { print $5 }'
5206 x_data="$( X -version 2>&1 )"
5207 elif [[ -n $( type -p Xorg ) ]];then
5208 x_data="$( Xorg -version 2>&1)"
5210 if [[ -n $x_data ]];then
5220 /^X Window System Version/ {
5226 log_function_data " version: $version"
5230 # this gets just the raw data, total space/percent used and disk/name/per disk capacity
5231 get_hdd_data_basic()
5234 local hdd_used='' temp_array='' df_string=''
5235 local hdd_data='' df_test=''
5237 if [[ -z $BSD_TYPE ]];then
5238 df_string='df -P -T --exclude-type=aufs --exclude-type=devfs --exclude-type=devtmpfs
5239 --exclude-type=fdescfs --exclude-type=iso9660 --exclude-type=linprocfs --exclude-type=procfs
5240 --exclude-type=squashfs --exclude-type=sysfs --exclude-type=tmpfs --exclude-type=unionfs'
5242 # default size is 512, so use -k for 1024
5243 df_string='df -T -k'
5244 # default size is 512, -H only for size in human readable format
5245 # older bsds don't support -T, pain, so we'll use partial output there
5246 df_test=$( df -H -T 2>/dev/null )
5247 if [[ -n $df_test ]];then
5248 df_string='df -k -T'
5253 hdd_data="$( eval $df_string )"
5254 log_function_data 'raw' "hdd_data:\n$hdd_data"
5255 hdd_used=$( echo "$hdd_data" | gawk -v bsdType=$BSD_TYPE '
5257 # this is used for specific cases where bind, or incorrect multiple mounts to same partitions,
5258 # is present. The value is searched for an earlier appearance of that partition and if it is
5259 # present, the data is not added into the partition used size.
5261 # this handles a case where the same dev item is mounted twice to different points
5266 # using $1, not $2, because older bsd df do not have -T, filesystem type
5267 ( bsdType != "" ) && $1 ~ /^(aufs|devfs|devtmpfs|fdescfs|filesystem|iso9660|linprocfs|procfs|squashfs|sysfs|tmpfs|type|unionfs)$/ {
5268 # note use next, not getline or it does not work right
5271 # also handles odd dm-1 type, from lvm, and mdraid, and some other bsd partition syntax
5272 # note that linux 3.2.45-grsec-9th types kernels have this type of partition name: /dev/xvdc (no number, letter)
5273 /^\/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])/ {
5274 # this handles the case where the first item is too long
5275 # and makes df wrap output to next line, so here we advance
5276 # it to the next line for that single case. Using df -P should
5277 # make this unneeded but leave it in just in case
5278 if ( NF < 6 && $0 !~ /.*%/ ) {
5279 devSet = devSet "~" $1 "~"
5282 # if the first item caused a wrap, use one less than standard
5283 # testing for the field with % in it, ie: 34%, then go down from there
5284 # this also protects against cases where the mount point has a space in the
5285 # file name, thus breaking going down from $NF directly.
5286 # some bsds will also have only 6 items
5288 devWorking="~" $1 "~"
5289 mountWorking="~" $6 "~"
5290 if ( partitionsSet !~ mountWorking && devSet !~ devWorking ) {
5293 partitionsSet = partitionsSet mountWorking
5294 # make sure to only include bsd real lines here, ie, short df output
5295 if ( $1 ~ /^\/dev\// ) {
5296 devSet = devSet devWorking
5299 # otherwise use standard
5300 else if ( $6 ~ /.*%/ ) {
5301 devWorking="~" $1 "~"
5302 mountWorking="~" $7 "~"
5303 if ( partitionsSet !~ mountWorking && devSet !~ devWorking ) {
5306 partitionsSet = partitionsSet mountWorking
5307 devSet = devSet devWorking
5309 # and if this is not detected, give up, we need user data to debug
5318 if [[ -z $hdd_used ]];then
5321 log_function_data "hdd_used: $hdd_used"
5322 # create the initial array strings:
5323 # disk-dev, capacity, name, usb or not
5324 # final item is the total of the disk
5327 if [[ $B_PARTITIONS_FILE == 'true' ]];then
5329 gawk -v hddused="$hdd_used" '
5331 driveSize = $(NF - 1)*1024/1000**3
5332 gsub(/,/, " ", driveSize)
5333 gsub(/^ +| +$/, "", driveSize)
5334 printf( $NF",%.1fGB,,\n", driveSize )
5336 # See http://lanana.org/docs/device-list/devices-2.6+.txt for major numbers used below
5337 # $1 ~ /^(3|22|33|8)$/ && $2 % 16 == 0 {
5340 # special case from this data: 8 0 156290904 sda
5341 # note: vm has 252/253/254 known starter, grsec has 202
5342 $1 ~ /^(3|8|22|33|202|252|253|254)$/ && $NF ~ /[hsv]d[a-z]$/ && ( $2 % 16 == 0 || $2 % 16 == 8 ) {
5347 size = size*1024/1000**3 # calculate size in GB size
5348 workingUsed = hddused*1024/1000**3 # calculate workingUsed in GB used
5349 # this handles a special case with livecds where no hdd_used is detected
5350 if ( size > 0 && hddused == "na" ) {
5351 size = sprintf( "%.1f", size )
5354 else if ( size > 0 && workingUsed > 0 ) {
5355 diskUsed = workingUsed*100/size # calculate used percentage
5356 diskUsed = sprintf( "%.1f", diskUsed )
5357 size = sprintf( "%.1f", size )
5358 print size "GB," diskUsed "% used"
5361 print "NA,-" # print an empty array, this will be further handled in the print out function
5363 }' $FILE_PARTITIONS ) )
5364 log_function_data 'cat' "$FILE_PARTITIONS"
5367 temp_array=${A_HDD_DATA[@]}
5368 log_function_data "A_HDD_DATA: $temp_array"
5372 ## fills out the A_HDD_DATA array with disk names
5373 get_hard_drive_data_advanced()
5376 local a_temp_working='' a_temp_scsi='' temp_holder='' temp_name='' i='' j=''
5377 local sd_ls_by_id='' ls_disk_by_id='' usb_exists='' temp_array=''
5379 ## check for all ide type drives, non libata, only do it if hdx is in array
5380 ## this is now being updated for new /sys type paths, this may handle that ok too
5381 if [[ -n $( grep -E 'hd[a-z]' <<< ${A_HDD_DATA[@]} ) ]];then
5382 # remember, we're using the last array item to store the total size of disks
5383 for (( i=0; i < ${#A_HDD_DATA[@]} - 1; i++ ))
5386 a_temp_working=( ${A_HDD_DATA[i]} )
5388 if [[ -n $( grep -E '^hd[a-z]' <<< ${a_temp_working[0]} ) ]];then
5389 if [[ -e /proc/ide/${a_temp_working[0]}/model ]];then
5390 a_temp_working[2]="$( remove_erroneous_chars /proc/ide/${a_temp_working[0]}/model )"
5392 a_temp_working[2]="Name n/a"
5394 # these loops are to easily extend the cpu array created in the gawk script above with more fields per cpu.
5395 for (( j=0; j < ${#a_temp_working[@]}; j++ ))
5397 if [[ $j -gt 0 ]];then
5398 A_HDD_DATA[i]="${A_HDD_DATA[i]},${a_temp_working[$j]}"
5400 A_HDD_DATA[i]="${a_temp_working[$j]}"
5407 ## then handle libata names
5408 # first get the ata device names, put them into an array
5410 if [[ $B_SCSI_FILE == 'true' ]]; then
5411 a_temp_scsi=( $( gawk '
5421 if (b[i] ~ / *type: *direct-access.*/) {
5422 #c=gensub(/^ *vendor: (.+) +model: (.+) +rev: (.+)$/,"\\1 \\2 \\3","g",a[i])
5423 #c=gensub( /^ *vendor: (.+) +model: (.+) +rev:.*$/,"\\1 \\2","g",a[i] )
5424 # the vendor: string is useless, and is a bug, ATA is not a vendor for example
5425 c=gensub( /^ *vendor: (.+) +model: (.+) +rev:.*$/, "\\2", "g", a[i] )
5427 gsub(/^ +| +$/, "", c)
5428 gsub(/ [ \t]+/, " ", c)
5430 # we actually want this data, so leaving this off for now
5431 # if (c ~ /\<flash\>|\<pendrive\>|memory stick|memory card/) {
5438 log_function_data 'cat' "$FILE_SCSI"
5442 ## then we'll loop through that array looking for matches.
5443 if [[ -n $( grep -E 'sd[a-z]' <<< ${A_HDD_DATA[@]} ) ]];then
5444 # first pack the main ls variable so we don't have to keep using ls /dev...
5445 # not all systems have /dev/disk/by-id
5446 ls_disk_by_id="$( ls -l /dev/disk/by-id 2>/dev/null )"
5447 for (( i=0; i < ${#A_HDD_DATA[@]} - 1; i++ ))
5449 if [[ -n $( grep -E '^sd[a-z]' <<< ${A_HDD_DATA[$i]} ) ]];then
5451 a_temp_working=( ${A_HDD_DATA[$i]} )
5453 # /sys/block/[sda,hda]/device/model
5454 # this is handles the new /sys data types first
5455 if [[ -e /sys/block/${a_temp_working[0]}/device/model ]];then
5456 temp_name="$( remove_erroneous_chars /sys/block/${a_temp_working[0]}/device/model )"
5457 temp_name=$( tr ' ' '_' <<< $temp_name | cut -d '-' -f 1 )
5458 elif [[ ${#a_temp_scsi[@]} -gt 0 ]];then
5459 for (( j=0; j < ${#a_temp_scsi[@]}; j++ ))
5461 ## ok, ok, it's incomprehensible, search /dev/disk/by-id for a line that contains the
5462 # discovered disk name AND ends with the correct identifier, sdx
5463 # get rid of whitespace for some drive names and ids, and extra data after - in name
5464 temp_name=$( tr ' ' '_' <<< ${a_temp_scsi[$j]} | cut -d '-' -f 1 )
5465 sd_ls_by_id=$( grep -Em1 ".*$temp_name.*${a_temp_working[0]}$" <<< "$ls_disk_by_id" )
5467 if [[ -n $sd_ls_by_id ]];then
5468 temp_name=${a_temp_scsi[$j]}
5471 # test to see if we can get a better name output when null
5472 if [[ -n $temp_name ]];then
5473 temp_name=$temp_name
5479 if [[ -z $temp_name ]];then
5480 temp_name="Name n/a"
5482 usb_exists=$( grep -Em1 "usb-.*$temp_name.*${a_temp_working[0]}$" <<< "$ls_disk_by_id" )
5483 if [[ -n $usb_exists ]];then
5484 a_temp_working[3]='USB'
5487 a_temp_working[2]=$temp_name
5488 # these loops are to easily extend the cpu array created in the gawk script above with more fields per cpu.
5489 for (( j=0; j < ${#a_temp_working[@]}; j++ ))
5491 if [[ $j -gt 0 ]];then
5492 A_HDD_DATA[i]="${A_HDD_DATA[i]},${a_temp_working[$j]}"
5494 A_HDD_DATA[i]="${a_temp_working[$j]}"
5499 unset ls_disk_by_id # and then let's dump the data we don't need
5501 temp_array=${A_HDD_DATA[@]}
5502 log_function_data "A_HDD_DATA: $temp_array"
5506 # args: $1 - which drive to get serial number of
5507 get_hdd_serial_number()
5513 get_partition_dev_data 'id'
5515 # lrwxrwxrwx 1 root root 9 Apr 26 09:32 scsi-SATA_ST3160827AS_5MT2HMH6 -> ../../sdc
5516 # exit on the first instance
5517 hdd_serial=$( gawk '
5519 serial=gensub( /^(.+)_([^_]+)$/, "\\2", 1, $9 )
5522 }' <<< "$DEV_DISK_ID" )
5525 log_function_data "hdd serial: $hdd_serial"
5529 # a few notes, normally hddtemp requires root, but you can set user rights in /etc/sudoers.
5530 # args: $1 - /dev/<disk> to be tested for
5534 local hdd_temp='' sudo_command=''
5536 if [[ $B_HDDTEMP_TESTED != 'true' ]];then
5537 B_HDDTEMP_TESTED='true'
5538 HDDTEMP_PATH=$( type -p hddtemp )
5540 if [[ $B_SUDO_TESTED != 'true' ]];then
5541 B_SUDO_TESTED='true'
5542 SUDO_PATH=$( type -p sudo )
5545 if [[ -n $HDDTEMP_PATH && -n $1 ]];then
5546 # only use sudo if not root, -n option requires sudo -V 1.7 or greater. sudo will just error out
5547 # which is the safest course here for now, otherwise that interactive sudo password thing is too annoying
5548 # important: -n makes it non interactive, no prompt for password
5549 if [[ $B_ROOT != 'true' && -n $SUDO_PATH ]];then
5550 sudo_command='sudo -n '
5552 # this will fail if regular user and no sudo present, but that's fine, it will just return null
5553 hdd_temp=$( eval $sudo_command $HDDTEMP_PATH -nq -u C $1 )
5554 if [[ -n $hdd_temp && -n $( grep -E '^([0-9\.]+)$' <<< $hdd_temp ) ]];then
5565 local init_type='' init_version='' rc_type='' rc_version='' temp_array=''
5566 local ls_run='' strings_init_version=''
5567 local runlevel=$( get_runlevel_data )
5568 local default_runlevel=$( get_runlevel_default )
5570 # this test is pretty solid, if pid 1 is owned by systemd, it is systemd
5571 # otherwise that is 'init', which covers the rest of the init systems, I think anyway.
5572 # more data may be needed for other init systems.
5573 if [[ -e /proc/1/comm && -n $( grep -s 'systemd' /proc/1/comm ) ]];then
5575 if [[ -n $( type -p systemd ) ]];then
5576 init_version=$( get_de_app_version 'systemd' '^systemd' '2' )
5578 if [[ -z $init_version && -n $( type -p systemctl ) ]];then
5579 init_version=$( get_de_app_version 'systemctl' '^systemd' '2' )
5583 # note: upstart-file-bridge.pid upstart-socket-bridge.pid upstart-udev-bridge.pid
5584 if [[ -n $( /sbin/init --version 2>/dev/null | grep 'upstart' ) ]];then
5586 # /sbin/init --version == init (upstart 1.12.1)
5587 init_version=$( get_de_app_version 'init' 'upstart' '3' )
5588 elif [[ -n $( type -p epoch ) ]];then
5590 # epoch version == Epoch Init System 1.0.1 "Sage"
5591 init_version=$( get_de_app_version 'epoch' '^Epoch' '4' )
5593 # http://smarden.org/runit/sv.8.html
5594 elif [[ -e /sbin/runit-init || -e /etc/runit || -n $( type -p sv ) ]];then
5595 init_type='runit' # lower case
5596 # no data on version yet
5597 elif [[ -f /etc/inittab ]];then
5598 init_type='SysVinit'
5599 if [[ -n $( type -p strings ) ]];then
5600 strings_init_version="$( strings /sbin/init | grep -E 'version[[:space:]]+[0-9]' )"
5602 if [[ -n $strings_init_version ]];then
5603 init_version=$( gawk '{print $2}' <<< "$strings_init_version" )
5606 elif [[ -f /etc/ttys ]];then
5607 init_type='init (bsd)'
5610 if [[ -n $( grep 'openrc' <<< "$ls_run" ) ]];then
5612 # /sbin/openrc --version == openrc (OpenRC) 0.13
5613 if [[ -n $( type -p openrc ) ]];then
5614 rc_version=$( get_de_app_version 'openrc' '^openrc' '3' )
5615 # /sbin/rc --version == rc (OpenRC) 0.11.8 (Gentoo Linux)
5616 elif [[ -n $( type -p rc ) ]];then
5617 rc_version=$( get_de_app_version 'rc' '^rc' '3' )
5619 ## assume sysvrc, but this data is too buggy and weird and inconsistent to have meaning
5620 # leaving this off for now
5621 # elif [[ -f /etc/inittab ]];then
5623 # # this is a guess that rc and init are same versions, may need updates / fixes
5624 # rc_version=$init_version
5636 "$default_runlevel" )
5640 temp_array=${A_INIT_DATA[@]}
5641 log_function_data "A_INIT_DATA: $temp_array"
5646 get_kernel_version()
5650 local kernel_version='' ksplice_kernel_version=''
5652 kernel_version=$( uname -rm )
5654 if [[ -n $( type -p uptrack-uname ) && -n $kernel_version ]];then
5655 ksplice_kernel_version=$( uptrack-uname -rm )
5656 if [[ $kernel_version != $ksplice_kernel_version ]];then
5657 kernel_version="$ksplice_kernel_version (ksplice)"
5660 log_function_data "kernel_version: $kernel_version - ksplice_kernel_version: $ksplice_kernel_version"
5662 echo $kernel_version
5673 if [[ $B_LSPCI == 'true' ]];then
5674 lspci_data="$( lspci -$1 | gawk '{
5675 gsub(/\(prog-if[^)]*\)/,"")
5676 sub(/^0000:/, "", $0) # seen case where the 0000: is prepended, rare, but happens
5682 log_function_data 'raw' "lspci_data $1:\n$lspci_data"
5698 }' <<< "$Lspci_n_Data" )
5708 local temp_array='' separator='' id_file='' file_data='' array_string=''
5709 local id_dir='/sys/class/dmi/id/' dmi_data=''
5710 local machine_files="
5711 sys_vendor product_name product_version product_serial product_uuid
5712 board_vendor board_name board_version board_serial
5713 bios_vendor bios_version bios_date
5716 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
5717 machine_files="$machine_files
5718 chassis_vendor chassis_type chassis_version chassis_serial
5721 if [[ -d $id_dir ]];then
5722 for id_file in $machine_files
5725 if [[ -r $id_dir$id_file ]];then
5731 gsub(/'"$BAN_LIST_NORMAL"'/, "", $0)
5733 # yes, there is a typo in a user data set, unknow
5734 # Base Board Version|Base Board Serial Number
5735 # Chassis Manufacturer|Chassis Version|Chassis Serial Number
5736 # System manufacturer|System Product Name|System Version
5737 # To Be Filled By O.E.M.
5738 sub(/^Base Board .*|^Chassis .*|.*O\.E\.M\..*|.*OEM.*|^Not .*|^System .*|.*unknow.*|.*N\/A.*|none|^To be filled.*/, "", $0)
5739 gsub(/bios|acpi/, "", $0)
5740 sub(/http:\/\/www.abit.com.tw\//, "Abit", $0)
5741 gsub(/^ +| +$/, "", $0)
5742 gsub(/ [ \t]+/, " ", $0)
5744 }' < $id_dir$id_file )
5746 array_string="$array_string$separator$file_data"
5751 if [[ -n $DMIDECODE_DATA ]];then
5752 if [[ $B_ROOT == 'true' ]];then
5753 # this handles very old systems, like Lenny 2.6.26, with dmidecode, but no data
5754 if [[ -n $( grep -i 'no smbios ' <<< "$DMIDECODE_DATA" ) ]];then
5755 array_string='dmidecode-no-smbios-dmi-data'
5756 # please note: only dmidecode version 2.11 or newer supports consistently the -s flag
5758 array_string=$( gawk -F ':' '
5761 baseboardManufacturer=""
5762 baseboardProductName=""
5763 baseboardSerialNumber=""
5766 biosRevision="" # only available from dmidecode
5767 biosRomSize="" # only available from dmidecode
5770 chassisManufacturer=""
5771 chassisSerialNumber=""
5774 systemManufacturer=""
5775 systemProductName=""
5777 systemSerialNumber=""
5779 bItemFound="" # we will only output if at least one item was found
5787 /^Bios Information/ {
5788 while ( getline && !/^$/ ) {
5789 if ( $1 ~ /^Release Date/ ) { biosReleaseDate=$2 }
5790 if ( $1 ~ /^BIOS Revision/ ) { biosRevision=$2 }
5791 if ( $1 ~ /^ROM Size/ ) { biosRomSize=$2 }
5792 if ( $1 ~ /^Vendor/ ) { biosVendor=$2 }
5793 if ( $1 ~ /^Version/ ) { biosVersion=$2 }
5795 testString=biosReleaseDate biosRevision biosRomSize biosVendor biosVersion
5796 if ( testString != "" ) {
5801 /^Base Board Information/ {
5802 while ( getline && !/^$/ ) {
5803 if ( $1 ~ /^Manufacturer/ ) { baseboardManufacturer=$2 }
5804 if ( $1 ~ /^Product Name/ ) { baseboardProductName=$2 }
5805 if ( $1 ~ /^Serial Number/ ) { baseboardSerialNumber=$2 }
5807 testString=baseboardManufacturer baseboardProductName baseboardSerialNumber
5808 if ( testString != "" ) {
5813 /^Chassis Information/ {
5814 while ( getline && !/^$/ ) {
5815 if ( $1 ~ /^Manufacturer/ ) { chassisManufacturer=$2 }
5816 if ( $1 ~ /^Serial Number/ ) { chassisSerialNumber=$2 }
5817 if ( $1 ~ /^Type/ ) { chassisType=$2 }
5818 if ( $1 ~ /^Version/ ) { chassisVersion=$2 }
5820 testString=chassisManufacturer chassisSerialNumber chassisType chassisVersion
5821 if ( testString != "" ) {
5826 /^System Information/ {
5827 while ( getline && !/^$/ ) {
5828 if ( $1 ~ /^Manufacturer/ ) { systemManufacturer=$2 }
5829 if ( $1 ~ /^Product Name/ ) { systemProductName=$2 }
5830 if ( $1 ~ /^Version/ ) { systemVersion=$2 }
5831 if ( $1 ~ /^Serial Number/ ) { systemSerialNumber=$2 }
5832 if ( $1 ~ /^UUID/ ) { systemUuid=$2 }
5834 testString=systemManufacturer systemProductName systemVersion systemSerialNumber systemUuid
5835 if ( testString != "" ) {
5840 ( bSys == "true" && bCha="true" && bBio == "true" && bBas == "true" ) {
5841 exit # stop the loop
5844 if ( bItemFound == "true" ) {
5845 fullString = systemManufacturer "," systemProductName "," systemVersion "," systemSerialNumber
5846 fullString = fullString "," systemUuid "," baseboardManufacturer "," baseboardProductName
5847 fullString = fullString "," baseboardVersion "," baseboardSerialNumber "," biosVendor
5848 fullString = fullString "," biosVersion "," biosReleaseDate "," chassisManufacturer
5849 fullString = fullString "," chassisType "," chassisVersion "," chassisSerialNumber
5850 fullString = fullString "," biosRevision "," biosRomSize
5854 }' <<< "$DMIDECODE_DATA" )
5857 array_string='dmidecode-non-root-user'
5862 A_MACHINE_DATA=( $array_string )
5864 temp_array=${A_MACHINE_DATA[@]}
5865 # echo ${temp_array[@]}
5866 log_function_data "A_MACHINE_DATA: $temp_array"
5869 # B_ROOT='true';get_machine_data;exit
5870 ## return memory used/installed
5874 local memory='' memory_full=''
5875 if [[ $B_MEMINFO_FILE == 'true' ]];then
5880 /^(MemFree|Buffers|Cached):/ {
5884 used = tot - notused
5885 printf("%.1f/%.1fMB\n", used/1024, tot/1024)
5887 log_function_data 'cat' "$FILE_MEMINFO"
5888 elif [[ $B_SYSCTL == 'true' && -n $Sysctl_a_Data ]];then
5891 if [[ $BSD_VERSION == 'openbsd' ]];then
5894 memory=$( grep -i 'mem' <<< "$Sysctl_a_Data" | gawk -F "$gawk_fs" '
5899 # freebsd seems to use bytes here
5901 gsub(/^[^0-9]+|[^0-9]+$/,"",$2)
5902 realMemory = $2/1024
5903 if ( freeMemory != "" ) {
5907 # But, it uses K here. Openbsd does not seem to have this item
5908 # this can be either: Free Memory OR Free Memory Pages
5909 $1 ~ /^Free Memory/ {
5910 gsub(/[^0-9]/,"",$NF)
5912 if ( realMemory != "" ) {
5917 # hack: temp fix for openbsd: in case no free mem was detected but we have physmem
5918 if ( freeMemory == "" && realMemory != "" ) {
5919 printf("NA/%.1fMB\n", realMemory/1024)
5921 else if ( freeMemory != "" && realMemory != "" ) {
5922 used = realMemory - freeMemory
5923 printf("%.1f/%.1fMB\n", used/1024, realMemory/1024)
5928 log_function_data "memory: $memory"
5932 # process and return module version data
5933 get_module_version_number()
5936 local module_version=''
5938 if [[ $B_MODINFO_TESTED != 'true' ]];then
5939 B_MODINFO_TESTED='true'
5940 MODINFO_PATH=$( type -p modinfo )
5943 if [[ -n $MODINFO_PATH ]];then
5944 module_version=$( $MODINFO_PATH $1 2>/dev/null | gawk '
5950 gsub(/^ +| +$/, "", $2)
5951 gsub(/ [ \t]+/, " ", $2)
5957 echo "$module_version"
5958 log_function_data "module_version: $module_version"
5962 ## create array of network cards
5963 get_networking_data()
5967 local B_USB_NETWORKING='false' temp_array=''
5971 echo "$Lspci_v_Data" | gawk '
5974 counter=0 # required to handle cases of > 1 instance of the same chipset
5976 /^[0-9a-f:\.]+ (ethernet|network) (controller|bridge)/ || /^[0-9a-f:\.]+ [^:]+: .*(ethernet|network).*$/ {
5977 nic=gensub(/^[0-9a-f:\.]+ [^:]+: (.+)$/,"\\1","g",$0)
5978 #gsub(/realtek semiconductor/, "Realtek", nic)
5979 #gsub(/davicom semiconductor/, "Davicom", nic)
5980 # The doublequotes are necessary because of the pipes in the variable.
5981 gsub(/'"$BAN_LIST_NORMAL"'/, "", nic)
5983 gsub(/^ +| +$/, "", nic)
5984 gsub(/ [ \t]+/, " ", nic)
5985 # construct a unique string ending for each chipset detected, this allows for
5986 # multiple instances of the same exact chipsets, ie, dual gigabit
5987 nic = nic "~~" counter++
5988 aPciBusId[nic] = gensub(/(^[0-9a-f:\.]+) [^:]+: .+$/,"\\1","g",$0)
5989 # I do not understand why incrementing a string index makes sense?
5991 while ( getline && !/^$/ ) {
5994 ports[nic] = ports[nic] $4 " "
5996 if ( /driver in use/ ) {
5997 drivers[nic] = drivers[nic] gensub( /(.*): (.*)/ ,"\\2" ,"g" ,$0 ) ""
5999 else if ( /kernel modules/ ) {
6000 modules[nic] = modules[nic] gensub( /(.*): (.*)/ ,"\\2" ,"g" ,$0 ) ""
6014 a[j] = eth[i] "x " i
6019 ## note: this loses the plural ports case, is it needed anyway?
6020 if ( ports[i] != "" ) {
6023 if ( drivers[i] != "" ) {
6024 useDrivers = drivers[i]
6026 if ( modules[i] != "" ) {
6027 useModules = modules[i]
6029 if ( aPciBusId[i] != "" ) {
6030 usePciBusId = aPciBusId[i]
6032 # create array primary item for master array
6033 # and strip out the counter again, this handled dual cards with same chipset
6034 sub( /~~[0-9]+$/, "", a[j] )
6035 sub( / $/, "", usePorts ) # clean off trailing whitespace
6036 print a[j] "," useDrivers "," usePorts "," useModules, "," usePciBusId
6041 get_networking_usb_data
6042 if [[ $B_SHOW_ADVANCED_NETWORK == 'true' || $B_USB_NETWORKING == 'true' ]];then
6043 get_network_advanced_data
6045 temp_array=${A_NETWORK_DATA[@]}
6046 log_function_data "A_NETWORK_DATA: $temp_array"
6051 get_network_advanced_data()
6054 local a_network_adv_working='' if_path='' working_path='' working_uevent_path='' dir_path=''
6055 local if_id='' speed='' duplex='' mac_id='' oper_state='' chip_id=''
6056 local usb_data='' usb_vendor='' usb_product='' product_path='' driver_test=''
6058 for (( i=0; i < ${#A_NETWORK_DATA[@]}; i++ ))
6061 a_network_adv_working=( ${A_NETWORK_DATA[i]} )
6062 # reset these every go round
6071 if [[ -z $( grep '^usb-' <<< ${a_network_adv_working[4]} ) ]];then
6072 # note although this may exist technically don't use it, it's a virtual path
6073 # and causes weird cat errors when there's a missing file as well as a virtual path
6074 # /sys/bus/pci/devices/0000:02:02.0/net/eth1
6075 # real paths are: /sys/devices/pci0000:00/0000:00:1e/0/0000:02:02.0/net/eth1/uevent
6076 # and on older debian kernels: /sys/devices/pci0000:00/0000:02:02.0/net:eth1/uevent
6077 # but broadcom shows this sometimes:
6078 # /sys/devices/pci0000:00/0000:00:03.0/0000:03:00.0/ssb0:0/uevent:['DRIVER=b43', 'MODALIAS=ssb:v4243id0812rev0D']:
6079 working_path="/sys/bus/pci/devices/0000:${a_network_adv_working[4]}"
6080 # now we want the real one, that xiin also displays, without symbolic links.
6081 if [[ -e $working_path ]];then
6082 working_path=$( readlink -f $working_path 2>/dev/null )
6083 # sometimes there is another directory between the path and /net
6084 if [[ ! -e $working_path/net ]];then
6085 # using find here, probably will need to also use it in usb part since the grep
6086 # method seems to not be working now. Slice off the rest, which leaves the basic path
6087 working_path=$( find $working_path/*/net/*/uevent 2>/dev/null | \
6091 # working_path=$( ls /sys/devices/pci*/*/0000:${a_network_adv_working[4]}/net/*/uevent )
6093 # now we'll use the actual vendor:product string instead
6094 usb_data=${a_network_adv_working[10]}
6095 usb_vendor=$( cut -d ':' -f 1 <<< $usb_data )
6096 usb_product=$( cut -d ':' -f 2 <<< $usb_data )
6097 # this grep returns the path plus the contents of the file, with a colon separator, so slice that off
6098 # /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/idVendor
6099 working_path=$( grep -s "$usb_vendor" /sys/devices/pci*/*/usb*/*/*/idVendor | \
6100 sed -e "s/idVendor:$usb_vendor//" -e '/driver/d' )
6101 # try an alternate path if first one doesn't work
6102 # /sys/devices/pci0000:00/0000:00:0b.1/usb1/1-1/idVendor
6103 if [[ -z $working_path ]];then
6104 working_path=$( grep -s "$usb_vendor" /sys/devices/pci*/*/usb*/*/idVendor | \
6105 sed -e "s/idVendor:$usb_vendor//" -e '/driver/d' )
6106 product_path=$( grep -s "$usb_product" /sys/devices/pci*/*/usb*/*/idProduct | \
6107 sed -e "s/idProduct:$usb_product//" -e '/driver/d' )
6109 product_path=$( grep -s "$usb_product" /sys/devices/pci*/*/usb*/*/*/idProduct | \
6110 sed -e "s/idProduct:$usb_product//" -e '/driver/d' )
6113 # make sure it's the right product/vendor match here, it will almost always be but let's be sure
6114 if [[ -n $working_path && -n $product_path ]] && [[ $working_path == $product_path ]];then
6115 #if [[ -n $working_path ]];then
6116 # now ls that directory and get the numeric starting sub directory and that should be the full path
6117 # to the /net directory part
6118 dir_path=$( ls ${working_path} 2>/dev/null | grep -sE '^[0-9]' )
6119 working_uevent_path="${working_path}${dir_path}"
6122 # /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/uevent grep for DRIVER=
6123 # /sys/devices/pci0000:00/0000:00:0b.1/usb1/1-1/1-1:1.0/uevent
6124 if [[ -n $usb_data ]];then
6125 driver_test=$( grep -si 'DRIVER=' $working_uevent_path/uevent | cut -d '=' -f 2 )
6126 if [[ -n $driver_test ]];then
6127 a_network_adv_working[1]=$driver_test
6130 log_function_data "PRE: working_path: $working_path\nworking_uevent_path: $working_uevent_path"
6132 # this applies in two different cases, one, default, standard, two, for usb, this is actually
6133 # the short path, minus the last longer numeric directory name, ie:
6134 # from debian squeeze 2.6.32-5-686:
6135 # /sys/devices/pci0000:00/0000:00:0b.1/usb1/1-1/net/wlan0/address
6136 if [[ -e $working_path/net ]];then
6137 if_path=$( ls $working_path/net 2>/dev/null )
6139 working_path=$working_path/net/$if_path
6140 # this is the normal usb detection if the first one didn't work
6141 elif [[ -n $usb_data && -e $working_uevent_path/net ]];then
6142 if_path=$( ls $working_uevent_path/net 2>/dev/null )
6144 working_path=$working_uevent_path/net/$if_path
6145 # 2.6.32 debian lenny kernel shows not: /net/eth0 but /net:eth0
6147 if_path=$( ls $working_path 2>/dev/null | grep 'net:' )
6148 if_id=$( cut -d ':' -f 2 <<< "$if_path" )
6149 working_path=$working_path/$if_path
6151 log_function_data "POST: working_path: $working_path\nif_path: $if_path - if_id: $if_id"
6153 if [[ -n $if_path ]];then
6154 if [[ -r $working_path/speed ]];then
6155 speed=$( cat $working_path/speed 2>/dev/null )
6157 if [[ -r $working_path/duplex ]];then
6158 duplex=$( cat $working_path/duplex 2>/dev/null )
6160 if [[ -r $working_path/address ]];then
6161 mac_id=$( cat $working_path/address 2>/dev/null )
6163 if [[ -r $working_path/operstate ]];then
6164 oper_state=$( cat $working_path/operstate 2>/dev/null )
6168 if [[ -n ${a_network_adv_working[10]} ]];then
6169 chip_id=${a_network_adv_working[10]}
6171 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
6178 get_networking_usb_data()
6181 local lsusb_path='' lsusb_data='' a_usb='' array_count=''
6183 # now we'll check for usb wifi, a work in progress
6184 # USB_NETWORK_SEARCH
6185 # alsa usb detection by damentz
6186 # for every sound card symlink in /proc/asound - display information about it
6187 lsusb_path=$( type -p lsusb )
6188 # if lsusb exists, the file is a symlink, and contains an important usb exclusive file: continue
6189 if [[ -n $lsusb_path ]]; then
6190 # send error messages of lsusb to /dev/null as it will display a bunch if not a super user
6191 lsusb_data="$( $lsusb_path 2>/dev/null )"
6192 # also, find the contents of usbid in lsusb and print everything after the 7th word on the
6193 # corresponding line. Finally, strip out commas as they will change the driver :)
6194 if [[ -n $lsusb_data ]];then
6203 /'"$USB_NETWORK_SEARCH"'/ && !/bluetooth| hub|keyboard|mouse|printer| ps2|reader|scan|storage/ {
6205 gsub( /,/, " ", $0 )
6206 gsub(/'"$BAN_LIST_NORMAL"'/, "", $0)
6207 gsub(/ [ \t]+/, " ", $0)
6208 #sub(/realtek semiconductor/, "Realtek", $0)
6209 #sub(/davicom semiconductor/, "Davicom", $0)
6210 #sub(/Belkin Components/, "Belkin", $0)
6212 for ( i=7; i<= NF; i++ ) {
6213 string = string separator $i
6218 print string ",,,,usb-" $2 "-" $4 ",,,,,," $6
6220 }' <<< "$lsusb_data" ) )
6222 if [[ ${#a_usb[@]} -gt 0 ]];then
6223 array_count=${#A_NETWORK_DATA[@]}
6224 for (( i=0; i < ${#a_usb[@]}; i++ ))
6226 A_NETWORK_DATA[$array_count]=${a_usb[i]}
6229 # need this to get the driver data for -N regular output, but no need
6230 # to run the advanced stuff unless required
6231 B_USB_NETWORKING='true'
6235 # echo $B_USB_NETWORKING
6239 get_networking_wan_ip_data()
6244 # get ip using wget redirect to stdout. This is a clean, text only IP output url,
6245 # single line only, ending in the ip address. May have to modify this in the future
6246 # to handle ipv4 and ipv6 addresses but should not be necessary.
6247 # awk has bad regex handling so checking it with grep -E instead
6248 # ip=$( echo 2001:0db8:85a3:0000:0000:8a2e:0370:7334 | gawk --re-interval '
6249 # ip=$( wget -q -O - $WAN_IP_URL | gawk --re-interval '
6250 ip=$( wget -t 1 -T $WGET_TIMEOUT -q -O - $WAN_IP_URL | gawk --re-interval '
6256 if [[ -z $ip ]];then
6258 elif [[ -z $( grep -Es \
6259 '^([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
6260 ip='IP Source Corrupt!'
6263 log_function_data "ip: $ip"
6267 get_networking_local_ip_data()
6271 local ip_tool_command=$( type -p ip )
6272 local temp_array='' ip_tool='ip' ip_tool_data=''
6273 # the chances for all new systems to have ip by default are far higher than
6274 # the deprecated ifconfig. Only try for ifconfig if ip is not present in system
6275 if [[ -z $ip_tool_command ]];then
6276 ip_tool_command=$( type -p ifconfig )
6279 ip_tool_command="$ip_tool_command addr"
6281 if [[ -n "$ip_tool_command" ]];then
6282 if [[ $ip_tool == 'ifconfig' ]];then
6283 ip_tool_data="$( $ip_tool_command | gawk '
6285 line=gensub(/^([a-z]+[0-9][:]?[[:space:]].*)/, "\n\\1", $0)
6288 # note, ip addr does not have proper record separation, so creating new lines explicitly here at start
6289 # of each IF record item. Also getting rid of the unneeded numeric line starters, now it can be parsed
6290 # like ifconfig more or less
6291 elif [[ $ip_tool == 'ip' ]];then
6292 ip_tool_data="$( eval ${ip_tool_command} | sed 's/^[0-9]\+:[[:space:]]\+/\n/' )"
6295 if [[ -z $ip_tool_command ]];then
6296 A_INTERFACES_DATA=( "Interfaces program 'ip' missing. Please check: $SCRIPT_NAME --recommends" )
6297 elif [[ -n "$ip_tool_data" ]];then
6298 IFS=$'\n' # $ip_tool_command
6299 A_INTERFACES_DATA=( $(
6300 gawk -v ipTool=$ip_tool -v bsdType=$BSD_TYPE '
6308 # skip past the lo item
6310 while (getline && !/^$/ ) {
6311 # do nothing, just get past this entry item
6315 # not clear on why inet is coming through, but this gets rid of it
6316 # as first line item.
6318 gsub(/^ +| +$/, "", $0)
6319 gsub(/ [ \t]+/, " ", $0)
6321 # prep this this for ip addr: eth0:
6322 sub(/:/, "", interface)
6326 aInterfaces[interface]++
6328 while (getline && !/^$/ ) {
6329 if ( ipTool == "ifconfig" ) {
6331 ifIp = gensub( /addr:([0-9\.]+)/, "\\1", "g", $2 )
6333 ifMask = gensub( /mask:([0-9\.]+)/, "\\1", "g", $NF )
6336 if (/inet6 addr:/) {
6339 if ( bsdType == "bsd" ) {
6340 if ( $1 == "inet" ) {
6342 if ( $3 == "netmask" ) {
6346 if ( $0 ~ /inet6.*%/ ) {
6352 else if ( ipTool == "ip" ) {
6353 if ( $1 == "inet" ) {
6356 if ( $1 == "inet6" ) {
6361 # slice off the digits that are sometimes tacked to the end of the address,
6363 sub(/\/[0-9]+/, "", ifIp)
6364 sub(/\/[0-9]+/, "", ifIpV6)
6365 ipAddresses[interface] = ifIp "," ifMask "," ifIpV6
6369 for (i in aInterfaces) {
6372 if (ipAddresses[i] != "") {
6373 ifData = ipAddresses[i]
6375 # create array primary item for master array
6376 # tested needed to avoid bad data from above, if null it is garbage
6377 # this is the easiest way to handle junk I found, improve if you want
6378 if ( ifData != "" ) {
6379 print a[j] "," ifData
6383 }' <<< "$ip_tool_data" ) )
6386 A_INTERFACES_DATA=( "Interfaces program $ip_tool present but created no data. " )
6388 temp_array=${A_INTERFACES_DATA[@]}
6389 log_function_data "A_INTERFACES_DATA: $temp_array"
6392 # get_networking_local_ip_data;exit
6394 # get_networking_local_ip_data;exit
6395 get_optical_drive_data()
6399 local temp_array='' sys_uevent_path='' proc_cdrom='' link_list=''
6400 local separator='' linked='' disk='' item_string='' proc_info_string=''
6401 local dev_disks_links="$( ls /dev/dvd* /dev/cd* /dev/scd* 2>/dev/null )"
6402 # get the actual disk dev location, first try default which is easier to run, need to preserve line breaks
6403 local dev_disks_real="$( echo "$dev_disks_links" | xargs -L 1 readlink 2>/dev/null | sort -u )"
6404 # Some systems don't support xargs -L so we need to do it manually
6405 if [[ -z $dev_disks_real ]];then
6406 for linked in $dev_disks_links
6408 disk=$( readlink $linked 2>/dev/null )
6409 if [[ -n $disk ]];then
6410 disk=$( basename $disk ) # puppy shows this as /dev/sr0, not sr0
6411 if [[ -z $dev_disks_real || -z $( grep $disk <<< $dev_disks_real ) ]];then
6412 # need line break IFS for below, no white space
6413 dev_disks_real="$dev_disks_real$separator$disk"
6418 dev_disks_real="$( sort -u <<< "$dev_disks_real" )"
6424 # A_OPTICAL_DRIVE_DATA indexes: not going to use all these, but it's just as easy to build the full
6425 # data array and use what we need from it as to update it later to add features or items
6426 # 0 - true dev path, ie, sr0, hdc
6427 # 1 - dev links to true path
6428 # 2 - device vendor - for hdx drives, vendor model are one string from proc
6430 # 4 - device rev version
6432 # 6 - multisession support
6442 if [[ -n $dev_disks_real ]];then
6443 if [[ $B_SHOW_FULL_OPTICAL == 'true' ]];then
6444 proc_cdrom="$( cat /proc/sys/dev/cdrom/info 2>/dev/null )"
6447 A_OPTICAL_DRIVE_DATA=( $(
6448 for disk in $dev_disks_real
6450 for linked in $dev_disks_links
6452 if [[ -n $( readlink $linked | grep $disk ) ]];then
6453 linked=$( basename $linked )
6454 link_list="$link_list$separator$linked"
6458 item_string="$disk,$link_list"
6468 # this is only for new sd type paths in /sys, otherwise we'll use /proc/ide
6469 if [[ -z $( grep '^hd' <<< $disk ) ]];then
6470 sys_path=$( ls /sys/devices/pci*/*/host*/target*/*/block/$disk/uevent 2>/dev/null | sed "s|/block/$disk/uevent||" )
6471 # no need to test for errors yet, probably other user systems will require some alternate paths though
6472 if [[ -n $sys_path ]];then
6473 vendor=$( cat $sys_path/vendor 2>/dev/null )
6474 model=$( cat $sys_path/model 2>/dev/null | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/,//g' )
6475 state=$( cat $sys_path/state 2>/dev/null | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/,//g' )
6476 rev_number=$( cat $sys_path/rev 2>/dev/null | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/,//g' )
6478 elif [[ -e /proc/ide/$disk/model ]];then
6479 vendor=$( cat /proc/ide/$disk/model 2>/dev/null )
6481 if [[ -n $vendor ]];then
6487 gsub(/'"$BAN_LIST_NORMAL"'/, "", $0)
6488 sub(/TSSTcorp/, "TSST ", $0) # seen more than one of these weird ones
6490 gsub(/^[[:space:]]*|[[:space:]]*$/, "", $0)
6491 gsub(/ [[:space:]]+/, " ", $0)
6495 # this needs to run no matter if there's proc data or not to create the array comma list
6496 if [[ $B_SHOW_FULL_OPTICAL == 'true' ]];then
6497 proc_info_string=$( gawk -v diskId=$disk '
6511 # first get the position of the device name from top field
6512 # we will use this to get all the other data for that column
6514 for ( position=3; position <= NF; position++ ) {
6515 if ( $position == diskId ) {
6523 /Can read multisession:/ {
6524 multisession=$( position + 1 )
6527 mcn=$( position + 1 )
6530 audio=$( position + 1 )
6533 cdr=$( position + 1 )
6535 /Can write CD-RW:/ {
6536 cdrw=$( position + 1 )
6539 dvd=$( position + 1 )
6541 /Can write DVD-R:/ {
6542 dvdr=$( position + 1 )
6544 /Can write DVD-RAM:/ {
6545 dvdram=$( position + 1 )
6548 print speed "," multisession "," mcn "," audio "," cdr "," cdrw "," dvd "," dvdr "," dvdram
6550 ' <<< "$proc_cdrom" )
6552 item_string="$item_string,$vendor,$model,$rev_number,$proc_info_string,$state"
6558 temp_array=${A_OPTICAL_DRIVE_DATA[@]}
6559 log_function_data "A_OPTICAL_DRIVE_DATA: $temp_array"
6563 get_partition_data()
6567 local a_partition_working='' dev_item='' temp_array='' dev_working_item=''
6568 local swap_data='' df_string='' main_partition_data='' df_test='' fs_type=''
6569 local mount_data='' dev_bsd_item=''
6570 #local excluded_file_types='--exclude-type=aufs --exclude-type=tmpfs --exclude-type=iso9660'
6571 # df doesn't seem to work in script with variables like at the command line
6572 # added devfs linprocfs sysfs fdescfs which show on debian kfreebsd kernel output
6573 if [[ -z $BSD_TYPE ]];then
6574 swap_data="$( swapon -s 2>/dev/null )"
6575 df_string='df -h -T -P --exclude-type=aufs --exclude-type=devfs --exclude-type=devtmpfs
6576 --exclude-type=fdescfs --exclude-type=iso9660 --exclude-type=linprocfs --exclude-type=procfs
6577 --exclude-type=squashfs --exclude-type=sysfs --exclude-type=tmpfs --exclude-type=unionfs'
6579 swap_data="$( swapctl -l 2>/dev/null )"
6580 # default size is 512, -H only for size in human readable format
6581 # older bsds don't support -T, pain, so we'll use partial output there
6582 df_test=$( df -H -T 2>/dev/null )
6583 if [[ -n $df_test ]];then
6584 df_string='df -H -T'
6589 main_partition_data="$( eval $df_string )"
6590 # set dev disk label/mapper/uuid data globals
6591 get_partition_dev_data 'label'
6592 get_partition_dev_data 'mapper'
6593 get_partition_dev_data 'uuid'
6595 log_function_data 'raw' "main_partition_data:\n$main_partition_data\n\nswap_data:\n$swap_data"
6597 # new kernels/df have rootfs and / repeated, creating two entries for the same partition
6598 # so check for two string endings of / then slice out the rootfs one, I could check for it
6599 # before slicing it out, but doing that would require the same action twice re code execution
6600 if [[ $( grep -cs '[[:space:]]/$' <<< "$main_partition_data" ) -gt 1 ]];then
6601 main_partition_data="$( grep -vs '^rootfs' <<< "$main_partition_data" )"
6603 log_function_data 'raw' "main_partition_data_post_rootfs:\n$main_partition_data\n\nswap_data:\n$swap_data"
6605 # sample line: /dev/sda2 ext3 15G 8.9G 4.9G 65% /home
6606 # $NF = partition name; $(NF - 4) = partition size; $(NF - 3) = used, in gB; $(NF - 1) = percent used
6607 ## note: by subtracting from the last field number NF, we avoid a subtle issue with LVM df output, where if
6608 ## the first field is too long, it will occupy its own line, this way we are getting only the needed data
6609 A_PARTITION_DATA=( $( echo "$main_partition_data" | gawk -v bsdType=$BSD_TYPE '
6614 # this has to be nulled for every iteration so it does not retain value from last iteration
6616 # skipping these file systems because bsds do not support df --exclude-type=<fstype>
6617 # note that using $1 to handle older bsd df, which do not support -T. This will not be reliable but we will see
6619 # skip if non disk/partition, or if raid primary id, which will not have a / in it
6620 if ( $1 ~ /^(aufs|devfs|devtmpfs|fdescfs|iso9660|linprocfs|procfs|squashfs|sysfs|tmpfs|type|unionfs)$/ ||
6621 $1 ~ /^([^\/]+)$/ ) {
6622 # note use next, not getline or it does not work right
6626 # this is required because below we are subtracting from NF, so it has to be > 5
6627 # the real issue is long file system names that force the wrap of df output: //fileserver/main
6628 # but we still need to handle more dynamically long space containing file names, but later.
6629 # Using df -P should fix this, ie, no wrapping of line lines, but leaving this for now
6630 ( NF < 6 ) && ( $0 !~ /[0-9]+%/ ) {
6631 # set the dev location here for cases of wrapped output
6633 devBase=gensub( /^(\/dev\/)(.+)$/, "\\2", 1, $1 )
6638 # next set devBase if it didn not get set above here
6639 ( devBase == "" ) && ( $1 ~ /^\/dev\/|:\/|\/\// ) {
6640 devBase=gensub( /^(\/dev\/)(.+)$/, "\\2", 1, $1 )
6642 # this handles zfs type devices/partitions, which do not start with / but contain /
6643 ( bsdType != "" && devBase == "" && $1 ~ /^[^\/]+\/.+/ ) {
6644 devBase=gensub( /^([^\/]+\/)([^\/]+)$/, "non-dev-\\1\\2", 1, $1 )
6646 # this handles yet another fredforfaen special case where a mounted drive
6647 # has the search string in its name
6648 $NF ~ /^\/$|^\/boot$|^\/var$|^\/home$|^\/tmp$|^\/usr$/ {
6649 # note, older df in bsd do not have file system column
6650 if ( NF == "7" && $(NF - 1) ~ /[0-9]+%/ ) {
6651 fileSystem=$(NF - 5)
6656 print $NF "," $(NF - 4) "," $(NF - 3) "," $(NF - 1) ",main," fileSystem "," devBase
6658 # skip all these, including the first, header line. Use the --exclude-type
6659 # to handle new filesystems types we do not want listed here
6660 $NF !~ /^\/$|^\/boot$|^\/var$|^\/home$|^\/tmp$|^\/usr$|^filesystem/ {
6661 # this is to avoid file systems with spaces in their names, that will make
6662 # the test show the wrong data in each of the fields, if no x%, then do not use
6663 # using 3 cases, first default, standard, 2nd, 3rd, handles one and two spaces in name
6664 if ( $(NF - 1) ~ /[0-9]+%/ ) {
6665 # note, older df in bsd do not have file system column
6667 fileSystem=$(NF - 5)
6672 print $NF "," $(NF - 4) "," $(NF - 3) "," $(NF - 1) ",secondary," fileSystem "," devBase
6674 # these two cases construct the space containing name
6675 else if ( $(NF - 2) ~ /[0-9]+%/ ) {
6676 # note, older df in bsd do not have file system column
6677 if ( NF == "8" && $(NF - 6) !~ /^[0-9]+/ ) {
6678 fileSystem=$(NF - 6)
6683 print $(NF - 1) " " $NF "," $(NF - 5) "," $(NF - 4) "," $(NF - 2) ",secondary," fileSystem "," devBase
6685 else if ( $(NF - 3) ~ /[0-9]+%/ ) {
6686 # note, older df in bsd do not have file system column
6687 if ( NF == "9" && $(NF - 7) !~ /^[0-9]+/ ) {
6688 fileSystem=$(NF - 7)
6693 print $(NF - 2) " " $(NF - 1) " " $NF "," $(NF - 6) "," $(NF - 5) "," $(NF - 3) ",secondary," fileSystem "," devBase
6697 # now add the swap partition data, don't want to show swap files, just partitions,
6698 # though this can include /dev/ramzswap0. Note: you can also use /proc/swaps for this
6699 # data, it's the same exact output as swapon -s
6700 $( echo "$swap_data" | gawk -v bsdType=$BSD_TYPE '
6707 if ( bsdType == "" ) {
6715 size = sprintf( "%.2f", sizeHolder*1024/1000**3 )
6716 devBase = gensub( /^(\/dev\/)(.+)$/, "\\2", 1, $1 )
6717 used = sprintf( "%.2f", usedHolder*1024/1000**3 )
6718 percentUsed = sprintf( "%.0f", ( usedHolder/sizeHolder )*100 )
6719 print "swap-" swapCounter "," size "GB," used "GB," percentUsed "%,main," "swap," devBase
6720 swapCounter = ++swapCounter
6724 temp_array=${A_PARTITION_DATA[@]}
6726 log_function_data "1: A_PARTITION_DATA:\n$temp_array"
6728 # we'll use this for older systems where no filesystem type is shown in df
6729 if [[ $BSD_TYPE == 'bsd' ]];then
6730 mount_data="$( mount )"
6732 # now we'll handle some fringe cases where irregular df -hT output shows /dev/disk/.. instead of
6733 # /dev/h|sdxy type data for column 1, . A_PARTITION_DATA[6]
6734 # Here we just search for the uuid/label and then grab the end of the line to get the right dev item.
6735 for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
6738 a_partition_working=( ${A_PARTITION_DATA[i]} )
6741 dev_item=${a_partition_working[6]} # reset each loop
6742 fs_type=${a_partition_working[5]}
6743 # older bsds have df minus -T so can't get fs type easily, try using mount instead
6744 if [[ $BSD_TYPE == 'bsd' && -z $fs_type && -n $dev_item ]];then
6745 dev_bsd_item=$( sed -e 's/non-dev-//' -e 's|/|\\/|g' <<< "$dev_item" )
6746 fs_type=$( gawk -F '(' '
6748 # slice out everything after / plus the first comma
6749 sub( /,.*/, "", $2 )
6752 }' <<< "$mount_data" )
6754 # note: for swap this will already be set
6755 if [[ -n $( grep -E '(by-uuid|by-label)' <<< $dev_item ) ]];then
6756 dev_working_item=$( basename $dev_item )
6757 if [[ -n $DEV_DISK_UUID ]];then
6758 dev_item=$( echo "$DEV_DISK_UUID" | gawk '
6759 $0 ~ /[ /t]'$dev_working_item'[ /t]/ {
6760 item=gensub( /..\/..\/(.+)/, "\\1", 1, $NF )
6765 # if we didn't find anything for uuid try label
6766 if [[ -z $dev_item && -n $DEV_DISK_LABEL ]];then
6767 dev_item=$( echo "$DEV_DISK_LABEL" | gawk '
6768 $0 ~ /[ /t]'$dev_working_item'[ /t]/ {
6769 item=gensub( /..\/..\/(.+)/, "\\1", 1, $NF )
6774 elif [[ -n $( grep 'mapper/' <<< $dev_item ) ]];then
6775 # get the mapper actual dev item
6776 dev_item=$( get_dev_processed_item "$dev_item" )
6779 if [[ -n $dev_item ]];then
6780 # assemble everything we could get for dev/h/dx, label, and uuid
6782 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
6786 temp_array=${A_PARTITION_DATA[@]}
6788 log_function_data "2: A_PARTITION_DATA:\n$temp_array"
6789 if [[ $B_SHOW_LABELS == 'true' || $B_SHOW_UUIDS == 'true' ]];then
6790 get_partition_data_advanced
6795 # first get the locations of the mount points for label/uuid detection
6796 get_partition_data_advanced()
6799 local a_partition_working='' dev_partition_data=''
6800 local dev_item='' dev_label='' dev_uuid='' temp_array=''
6801 local mount_point=''
6802 # set dev disk label/mapper/uuid data globals
6803 get_partition_dev_data 'label'
6804 get_partition_dev_data 'mapper'
6805 get_partition_dev_data 'uuid'
6807 if [[ $B_MOUNTS_FILE == 'true' ]];then
6808 for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
6811 a_partition_working=( ${A_PARTITION_DATA[i]} )
6814 # note: for swap this will already be set
6815 if [[ -z ${a_partition_working[6]} ]];then
6817 mount_point=$( sed 's|/|\\/|g' <<< ${a_partition_working[0]} )
6818 #echo mount_point $mount_point
6819 dev_partition_data=$( gawk '
6825 # trying to handle space in name
6826 # gsub( /\\040/, " ", $0 )
6827 /[ \t]'$mount_point'[ \t]/ && $1 != "rootfs" {
6828 # initialize the variables
6832 # slice out the /dev
6833 partition=gensub( /^(\/dev\/)(.+)$/, "\\2", 1, $1 )
6834 # label and uuid can occur for root, set partition to null now
6835 if ( partition ~ /by-label/ ) {
6836 label=gensub( /^(\/dev\/disk\/by-label\/)(.+)$/, "\\2", 1, $1 )
6839 if ( partition ~ /by-uuid/ ) {
6840 uuid=gensub( /^(\/dev\/disk\/by-uuid\/)(.+)$/, "\\2", 1, $1 )
6844 # handle /dev/root for / id
6845 if ( partition == "root" ) {
6846 # if this works, great, otherwise, just set this to null values
6847 partTemp="'$( readlink /dev/root 2>/dev/null )'"
6848 if ( partTemp != "" ) {
6849 if ( partTemp ~ /[hsv]d[a-z][0-9]{1,2}/ ) {
6850 partition=gensub( /^(\/dev\/)(.+)$/, "\\2", 1, partTemp )
6852 else if ( partTemp ~ /by-uuid/ ) {
6853 uuid=gensub( /^(\/dev\/disk\/by-uuid\/)(.+)$/, "\\2", 1, partTemp )
6854 partition="" # set null to let real location get discovered
6856 else if ( partTemp ~ /by-label/ ) {
6857 label=gensub( /^(\/dev\/disk\/by-label\/)(.+)$/, "\\2", 1, partTemp )
6858 partition="" # set null to let real location get discovered
6867 print partition "," label "," uuid
6871 # assemble everything we could get for dev/h/dx, label, and uuid
6873 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
6876 ## now we're ready to proceed filling in the data
6878 a_partition_working=( ${A_PARTITION_DATA[i]} )
6880 # get the mapper actual dev item first, in case it's mapped
6881 dev_item=$( get_dev_processed_item "${a_partition_working[6]}" )
6882 # make sure not to slice off rest if it's a network mounted file system
6883 if [[ -n $dev_item && -z $( grep -E '(^//|:/)' <<< $dev_item ) ]];then
6884 dev_item=$( basename $dev_item ) ## needed to avoid error in case name still has / in it
6886 dev_label=${a_partition_working[7]}
6887 dev_uuid=${a_partition_working[8]}
6888 # then if dev data/uuid is incomplete, try to get missing piece
6889 # it's more likely we'll get a uuid than a label. But this should get the
6890 # dev item set no matter what, so then we can get the rest of any missing data
6891 # first we'll get the dev_item if it's missing
6892 if [[ -z $dev_item ]];then
6893 if [[ -n $DEV_DISK_UUID && -n $dev_uuid ]];then
6894 dev_item=$( echo "$DEV_DISK_UUID" | gawk '
6895 $0 ~ /[ \t]'$dev_uuid'[ \t]/ {
6896 item=gensub( /..\/..\/(.+)/, "\\1", 1, $NF )
6900 elif [[ -n $DEV_DISK_LABEL && -n $dev_label ]];then
6901 dev_item=$( echo "$DEV_DISK_LABEL" | gawk '
6902 # first we need to change space x20 in by-label back to a real space
6903 #gsub( /x20/, " ", $0 )
6904 # then we can see if the string is there
6905 $0 ~ /[ \t]'$dev_label'[ \t]/ {
6906 item=gensub( /..\/..\/(.+)/, "\\1", 1, $NF )
6913 # this can trigger all kinds of weird errors if it is a non /dev path, like: remote:/machine/name
6914 if [[ -n $dev_item && -z $( grep -E '(^//|:/)' <<< $dev_item ) ]];then
6915 if [[ -n $DEV_DISK_UUID && -z $dev_uuid ]];then
6916 dev_uuid=$( echo "$DEV_DISK_UUID" | gawk '
6922 if [[ -n $DEV_DISK_LABEL && -z $dev_label ]];then
6923 dev_label=$( echo "$DEV_DISK_LABEL" | gawk '
6931 # assemble everything we could get for dev/h/dx, label, and uuid
6933 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
6936 log_function_data 'cat' "$FILE_MOUNTS"
6938 if [[ $BSD_TYPE == 'bsd' ]];then
6939 get_partition_data_advanced_bsd
6942 temp_array=${A_PARTITION_DATA[@]}
6944 log_function_data "3-advanced: A_PARTITION_DATA:\n$temp_array"
6948 get_partition_data_advanced_bsd()
6951 local gpart_data="$( gpart list 2>/dev/null )"
6952 local a_partition_working='' label_uuid='' dev_item=''
6954 if [[ -n $gpart_data ]];then
6955 for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
6958 a_partition_working=( ${A_PARTITION_DATA[i]} )
6960 # no need to use the rest of the name if it's not a straight /dev/item
6961 dev_item=$( basename ${a_partition_working[6]} )
6963 label_uuid=$( gawk -F ':' '
6969 /^[0-9]+\.[[:space:]]*Name.*'$dev_item'/ {
6970 while ( getline && $1 !~ /^[0-9]+\.[[:space:]]*Name/ ) {
6971 if ( $1 ~ /rawuuid/ ) {
6972 gsub(/^[[:space:]]+|[[:space:]]+$/,"",$2)
6975 if ( $1 ~ /label/ ) {
6976 gsub(/^[[:space:]]+|[[:space:]]+$|none|\(null\)/,"",$2)
6982 }' <<< "$gpart_data" )
6984 # assemble everything we could get for dev/h/dx, label, and uuid
6986 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
6993 # args: $1 - uuid/label/id/mapper
6994 get_partition_dev_data()
6998 # only run these tests once per directory to avoid excessive queries to fs
7001 if [[ $B_ID_SET != 'true' ]];then
7002 if [[ -d /dev/disk/by-id ]];then
7003 DEV_DISK_ID="$( ls -l /dev/disk/by-id )"
7009 if [[ $B_LABEL_SET != 'true' ]];then
7010 if [[ -d /dev/disk/by-label ]];then
7011 DEV_DISK_LABEL="$( ls -l /dev/disk/by-label )"
7017 if [[ $B_MAPPER_SET != 'true' ]];then
7018 if [[ -d /dev/mapper ]];then
7019 DEV_DISK_MAPPER="$( ls -l /dev/mapper )"
7025 if [[ $B_UUID_SET != 'true' ]];then
7026 if [[ -d /dev/disk/by-uuid ]];then
7027 DEV_DISK_UUID="$( ls -l /dev/disk/by-uuid )"
7034 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"
7035 # debugging section, uncomment to insert user data
7048 # args: $1 - dev item, check for mapper, then get actual dev item if mapped
7049 # eg: lrwxrwxrwx 1 root root 7 Sep 26 15:10 truecrypt1 -> ../dm-2
7050 get_dev_processed_item()
7054 local dev_item=$1 dev_return=''
7056 if [[ -n $DEV_DISK_MAPPER && -n $( grep -is 'mapper/' <<< $dev_item ) ]];then
7057 dev_return=$( echo "$DEV_DISK_MAPPER" | gawk '
7058 $( NF - 2 ) ~ /^'$( basename $dev_item )'$/ {
7059 item=gensub( /..\/(.+)/, "\\1", 1, $NF )
7063 if [[ -z $dev_return ]];then
7064 dev_return=$dev_item
7072 get_patch_version_string()
7074 local patch_version_number=$( sed 's/^[0]*//' <<< $SCRIPT_PATCH_NUMBER )
7076 if [[ -n $patch_version_number ]];then
7077 patch_version_number="-$patch_version_number"
7078 # for cases where it was for example: 00-bsd cleaned to --bsd trim out one -
7079 if [[ -n $( grep '\--' <<< $patch_version_number ) ]];then
7080 patch_version_number=$( sed 's/--/-/' <<< $patch_version_number )
7083 echo $patch_version_number
7090 local pciconf_data='' temp_array=''
7092 if [[ $B_PCICONF == 'true' ]];then
7093 pciconf_data="$( pciconf -lv 2>/dev/null )"
7094 if [[ -n $pciconf_data ]];then
7095 pciconf_data=$( gawk '
7100 gsub(/'"$BAN_LIST_NORMAL"'/, "", $0)
7101 gsub(/[[:space:]]+=[[:space:]]+/, "=",$0)
7102 gsub(/^[[:space:]]+|'"'"'|\"|,/, "", $0)
7104 # line=gensub(/.*[[:space:]]+(class=[^[:space:]]*|card=[^[:space:]]*)|chip=[^[:space:]]*|rev=[^[:space:]]*|hdr=[^[:space:]]*).*/,"\n\\1","g",$0)
7105 line=gensub(/(.*@.*)/,"\n\\1",$0)
7107 }' <<< "$pciconf_data" )
7108 # create empty last line with this spacing trick
7109 pciconf_data="$pciconf_data
7112 # echo "$pciconf_data"
7113 # now insert into arrays
7115 A_PCICONF_DATA=( $( gawk '
7136 driver=gensub(/^([^@]+)@.*/, "\\1", itemData )
7137 pciId=gensub(/^.*@pci([0-9\.:]+).*/, "\\1", itemData )
7138 sub(/:$/, "", pciId)
7140 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 )
7141 if ( $2 == "class=020000" ) {
7144 else if ( $2 == "class=030000" ) {
7147 else if ( $2 == "class=040300" ) {
7151 while ( getline && $1 !~ /^$/ ) {
7152 if ( $1 ~ /^vendor/ ) {
7153 sub(/^vendor=/, "", $1 )
7156 else if ( $1 ~ /^device/ ) {
7157 sub(/^device=/, "", $1 )
7160 else if ( $1 ~ /^class=/ && class == "" ) {
7161 sub(/^class=/, "", $1)
7165 if ( device == "" ) {
7169 fullLine=class "," device "," vendor "," driver "," pciId "," chipId
7172 }' <<< "$pciconf_data" ))
7176 A_PCICONF_DATA='pciconf-not-installed'
7178 B_PCICONF_SET='true'
7179 temp_array=${A_PCICONF_DATA[@]}
7180 log_function_data "$temp_array"
7181 log_function_data "$pciconf_data"
7185 # packs standard card arrays using the pciconf stuff
7186 # args: $1 - audio/network/display - matches first item in A_PCICONF_DATA arrays
7187 get_pciconf_card_data()
7190 local a_temp='' array_string='' j=0 device_string=''
7191 local ip_tool_command=$( type -p ifconfig )
7192 local mac='' state='' speed='' duplex='' network_string=''
7194 for (( i=0;i<${#A_PCICONF_DATA[@]};i++ ))
7197 a_temp=( ${A_PCICONF_DATA[i]} )
7200 if [[ ${a_temp[0]} == $1 ]];then
7201 # don't print the vendor if it's already in the device name
7202 if [[ -z $( grep -i "${a_temp[2]}" <<< "${a_temp[1]}" ) ]];then
7203 device_string="${a_temp[2]} ${a_temp[1]}"
7205 device_string=${a_temp[1]}
7209 array_string="$device_string,${a_temp[3]},,,${a_temp[4]},,${a_temp[5]}"
7210 A_AUDIO_DATA[j]=$array_string
7213 array_string="$device_string,${a_temp[4]},${a_temp[5]}"
7214 A_GRAPHICS_CARD_DATA[j]=$array_string
7217 if [[ -n $ip_tool_command && -n ${a_temp[3]} ]];then
7218 network_string=$( $ip_tool_command ${a_temp[3]} | gawk '
7226 /^[[:space:]]*ether/ {
7229 /^[[:space:]]*media/ {
7230 if ( $0 ~ /<.*>/ ) {
7231 duplex=gensub(/.*<([^>]+)>.*/,"\\1",$0)
7233 if ( $0 ~ /\(.*\)/ ) {
7234 speed=gensub(/.*\(([^<[:space:]]+).*\).*/,"\\1",$0)
7237 /^[[:space:]]*status/ {
7238 sub(/.*status[:]?[[:space:]]*/,"", $0)
7242 print state "~" speed "~" mac "~" duplex
7245 if [[ -n $network_string ]];then
7246 mac=$( cut -d '~' -f 3 <<< $network_string )
7247 state=$( cut -d '~' -f 1 <<< $network_string )
7248 speed=$( cut -d '~' -f 2 <<< $network_string )
7249 duplex=$( cut -d '~' -f 4 <<< $network_string )
7251 array_string="$device_string,${a_temp[3]},,,${a_temp[4]},${a_temp[3]},$state,$speed,$duplex,$mac,${a_temp[5]}"
7252 A_NETWORK_DATA[j]=$array_string
7262 # args: $1 - type cpu/mem
7266 local array_length='' reorder_temp='' i=0 head_tail='' sort_type='' ps_data=''
7268 # bummer, have to make it more complex here because of reverse sort
7269 # orders in output, pesky lack of support of +rss in old systems
7272 if [[ $BSD_TYPE != 'bsd' ]];then
7273 sort_type='ps aux --sort -rss'
7276 sort_type='ps aux -m'
7281 if [[ $BSD_TYPE != 'bsd' ]];then
7282 sort_type='ps aux --sort %cpu'
7285 sort_type='ps aux -r'
7291 # throttle potential irc abuse
7292 if [[ $B_RUNNING_IN_SHELL != 'true' && $PS_COUNT -gt 5 ]];then
7293 PS_THROTTLED=$PS_COUNT
7296 # use eval here to avoid glitches with -
7297 ps_data="$( eval $sort_type )"
7300 # note that inxi can use a lot of cpu, and can actually show up here as the script runs
7301 A_PS_DATA=( $( echo "$ps_data" | grep -Ev "($SCRIPT_NAME|%CPU|[[:space:]]ps[[:space:]])" | $head_tail -n $PS_COUNT | gawk '
7319 rss=sprintf( "%.2f", $6/1024 )
7320 # have to get rid of [,],(,) eg: [lockd] which break the printout function compare in bash
7321 gsub(/\[|\]|\(|\)/,"~", $0 )
7330 appStarterName=gensub( /(\/.*\/)(.*)/, "\\2", "1", appStarterPath )
7331 appName=gensub( /(\/.*\/)(.*)/, "\\2", "1", appPath )
7332 print appName "," appPath "," appStarterName "," appStarterPath "," cpu "," mem "," pid "," rss "," user
7335 # make the array ordered highest to lowest so output looks the way we expect it to
7336 # this isn't necessary for -rss, and we can't make %cpu ordered the other way, so
7337 # need to reverse it here. -rss is used because on older systems +rss is not supported
7338 if [[ $1 == 'cpu' && $BSD_TYPE != 'bsd' ]];then
7339 array_length=${#A_PS_DATA[@]};
7340 while (( $i < $array_length/2 ))
7342 reorder_temp=${A_PS_DATA[i]}f
7343 A_PS_DATA[i]=${A_PS_DATA[$array_length-$i-1]}
7344 A_PS_DATA[$array_length-$i-1]=$reorder_temp
7351 # echo ${A_PS_DATA[@]}
7355 # mdstat syntax information: http://www-01.ibm.com/support/docview.wss?uid=isg3T1011259
7356 # note that this does NOT use either Disk or Partition information for now, ie, there
7357 # is no connection between the data types, but the output should still be consistent
7364 if [[ $B_MDSTAT_FILE == 'true' ]];then
7365 mdstat="$( cat $FILE_MDSTAT 2>/dev/null )"
7368 if [[ -n $mdstat ]];then
7369 # need to make sure there's always a newline in front of each record type, and
7370 # also correct possible weird formats for the output from older kernels etc.
7371 mdstat="$( sed -e 's/^md/\nmd/' -e 's/^unused[[:space:]]/\nunused /' \
7372 -e 's/read_ahead/\nread_ahead/' -e 's/^resync=/\nresync=/' -e 's/^Event/\nEvent/' \
7373 -e 's/^[[:space:]]*$//' -e 's/[[:space:]]read_ahead/\nread_ahead/' <<< "$mdstat" )"
7374 # some fringe cases do not end as expected, so need to add newlines plus EOF to make sure while loop doesn't spin
7375 mdstat=$( echo -e "$mdstat\n\nEOF" )
7386 KernelRaidSupport = gensub(/personalities[[:space:]]*:[[:space:]]*(.*)/, "\\1", 1, $0)
7387 # clean off the brackets
7388 gsub(/[\[\]]/,"",KernelRaidSupport)
7389 print "KernelRaidSupport," KernelRaidSupport
7392 ReadAhead=gensub(/read_ahead (.*)/, "\\1", 1 )
7393 print "ReadAhead," ReadAhead
7396 print "raidEvent," $NF
7398 # print logic will search for this value and use it to print out the unused devices data
7400 unusedDevices = gensub(/^unused devices:[[:space:]][<]?([^>]*)[>]?.*/, "\\1", 1, $0)
7401 print "UnusedDevices," unusedDevices
7405 # reset for each record loop through
7415 recoveryProgressBar = ""
7416 recoveryPercent = ""
7418 sectorsRecovered = ""
7423 while ( !/^[[:space:]]*$/ ) {
7425 gsub(/[[:space:]]+/, " ", $0 )
7427 device = gensub(/(md.*)[[:space:]]?:/, "\\1", "1", $1 )
7429 if ( $0 ~ /mirror|raid[0-9]+/ ) {
7430 raidLevel = gensub(/(.*)raid([0-9]+)(.*)/, "\\2", "g", $0 )
7432 if ( $0 ~ /(active \(auto-read-only\)|active|inactive)/ ) {
7433 deviceState = gensub(/(.*) (active \(auto-read-only\)|active|inactive) (.*)/, "\\2", "1", $0 )
7435 # gawk will not return all the components using gensub, only last one
7437 for ( i=3; i<=NF; i++ ) {
7438 if ( $i ~ /[hs]d[a-z][0-9]*(\[[0-9]+\])?(\([SF]\))?/ ) {
7439 components = components separator $i
7443 if ( $0 ~ /blocks/ ) {
7444 blocks = gensub(/(.*[[:space:]]+)?([0-9]+)[[:space:]]blocks.*/, "\\2", "1", $0)
7446 if ( $0 ~ /super[[:space:]][0-9\.]+/ ) {
7447 superBlock = gensub(/.*[[:space:]]super[[:space:]]([0-9\.]+)[[:space:]].*/, "\\1", "1", $0)
7449 if ( $0 ~ /algorithm[[:space:]][0-9\.]+/ ) {
7450 algorithm = gensub(/.*[[:space:]]algorithm[[:space:]]([0-9\.]+)[[:space:]].*/, "\\1", "1", $0)
7452 if ( $0 ~ /\[[0-9]+\/[0-9]+\]/ ) {
7453 deviceReport = gensub(/.*[[:space:]]\[([0-9]+\/[0-9]+)\][[:space:]].*/, "\\1", "1", $0)
7454 uData = gensub(/.*[[:space:]]\[([U_]+)\]/, "\\1", "1", $0)
7456 # need to avoid this: bitmap: 0/10 pages [0KB], 16384KB chunk
7457 # while currently all the normal chunks are marked with k, not kb, this can change in the future
7458 if ( $0 ~ /[0-9]+[k] chunk/ && $0 !~ /bitmap/ ) {
7459 chunkSize = gensub(/(.*) ([0-9]+[k]) chunk.*/, "\\2", "1", $0)
7461 if ( $0 ~ /^resync=/ ) {
7463 print "resyncStatus," $0
7465 if ( $0 ~ /\[[=]*>[\.]*\].*(resync|recovery)/ ) {
7466 recoveryProgressBar = gensub(/.*(\[[=]*>[\.]*\]).*/, "\\1",1,$0)
7468 if ( $0 ~ / (resync|recovery)[[:space:]]*=/ ) {
7469 recoveryPercent = gensub(/.* (resync|recovery)[[:space:]]*=[[:space:]]*([0-9\.]+%).*/, "\\1~\\2", 1 )
7470 if ( $0 ~ /[[:space:]]\([0-9]+\/[0-9]+\)/ ) {
7471 sectorsRecovered = gensub(/.* \(([0-9]+\/[0-9]+)\).*/, "\\1", 1, $0 )
7473 if ( $0 ~ /finish[[:space:]]*=/ ) {
7474 finishTime = gensub(/.* finish[[:space:]]*=[[:space:]]*([[0-9\.]+)([a-z]+) .*/, "\\1 \\2", 1, $0 )
7476 if ( $0 ~ /speed[[:space:]]*=/ ) {
7477 recoverSpeed = gensub(/.* speed[[:space:]]*=[[:space:]]*([[0-9\.]+)([a-z]+\/[a-z]+)/, "\\1 \\2", 1, $0 )
7480 if ( $0 ~ /bitmap/ ) {
7481 bitmapValues = gensub(/(.*[[:space:]])?bitmap:(.*)/, "\\2", 1, $0 )
7486 raidString = device "," deviceState "," raidLevel "," components "," deviceReport "," uData
7487 raidString = raidString "," blocks "," superBlock "," algorithm "," chunkSize "," bitmapValues
7488 raidString = raidString "," recoveryProgressBar "," recoveryPercent "," sectorsRecovered "," finishTime "," recoverSpeed
7495 if [[ $BSD_TYPE == 'bsd' ]];then
7500 temp_array=${A_RAID_DATA[@]}
7501 log_function_data "A_RAID_DATA: $temp_array"
7502 # echo -e "A_RAID_DATA:\n${temp_array}"
7510 local zpool_path=$( type -p zpool 2>/dev/null )
7513 if [[ -n $zpool_path ]];then
7515 # bsd sed does not support inserting a true \n so use this trick
7516 zpool_data="$( $zpool_path list -v | sed $SED_RX 's/^([^[:space:]])/\
7518 # echo "$zpool_data"
7528 chunkRaidAllocated=""
7531 sub(/.*ALLOC.*/,"", $0)
7541 chunkRaidAllocated=$3
7543 # go to the next line now, this will probably need fixing later with weird data sets
7549 while ( getline && $1 !~ /^$/ ) {
7551 components = components separator $1
7556 raidString = device "," deviceState "," raidLevel "," components "," reportSize "," uData
7557 raidString = raidString "," blocksAvailable "," superBlock "," algorithm "," chunkRaidAllocated
7558 # none of these are used currently
7559 raidString = raidString "," bitmapValues "," recoveryProgressBar "," recoveryPercent
7560 raidString = raidString "," sectorsRecovered "," finishTime "," recoverSpeed
7561 gsub(/~/,"",raidString)
7563 }' <<< "$zpool_data" ) )
7565 get_raid_component_data_bsd
7570 # note, we've already tested for zpool so no further tests required
7571 get_raid_component_data_bsd()
7574 local a_raid_data='' array_string='' component='' component_string=''
7575 local zpool_status='' device='' separator='' component_status=''
7577 for (( i=0; i<${#A_RAID_DATA[@]}; i++))
7580 a_raid_data=( ${A_RAID_DATA[i]} )
7586 device=${a_raid_data[0]}
7587 zpool_status="$( zpool status $device )"
7588 # we will remove ONLINE for status and only use OFFLINE/DEGRADED as tests
7589 # for print output display of issues with components
7590 for component in ${a_raid_data[3]}
7592 component_status=$( gawk '
7596 $1 ~ /^'$component'$/ {
7597 sub( /ONLINE/, "", $2 )
7598 print "'$component'" $2
7600 }' <<< "$zpool_status" )
7601 component_string="$component_string$separator$component_status"
7604 array_string="$device,${a_raid_data[1]},${a_raid_data[2]},$component_string,${a_raid_data[4]}"
7605 array_string="$array_string,${a_raid_data[5]},${a_raid_data[6]},${a_raid_data[7]},${a_raid_data[8]}"
7606 array_string="$array_string,${a_raid_data[9]},${a_raid_data[10]},${a_raid_data[11]},${a_raid_data[12]},"
7607 array_string="$array_string${a_raid_data[13]},${a_raid_data[14]},${a_raid_data[15]}"
7609 A_RAID_DATA[i]=$array_string
7615 # get_raid_data_bsd;exit
7617 # Repos will be added as we get distro package manager data to create the repo data.
7618 # This method will output the file name also, which is useful to create output that's
7619 # neat and readable. Each line of the total number contains the following sections,
7620 # separated by a : for splitting in the print function
7621 # part one, repo type/string : part two, file name, if present, of info : part 3, repo data
7625 local repo_file='' repo_data_working='' repo_data_working2='' repo_line='' repo_files=''
7627 local apt_file='/etc/apt/sources.list' yum_repo_dir='/etc/yum.repos.d/' yum_conf='/etc/yum.conf'
7628 local pacman_conf='/etc/pacman.conf' pacman_repo_dir='/etc/pacman.d/' pisi_dir='/etc/pisi/'
7629 local zypp_repo_dir='/etc/zypp/repos.d/' freebsd_conf='/etc/portsnap.conf'
7631 # apt - debian, buntus, also sometimes some yum/rpm repos may create apt repos here as well
7632 if [[ -f $apt_file || -d $apt_file.d ]];then
7633 REPO_DATA="$( grep -Esv '(^[[:space:]]*$|^[[:space:]]*#)' $apt_file $apt_file.d/*.list | sed $SED_RX 's/^(.*)/apt sources:\1/' )"
7635 # yum - fedora, redhat, centos, etc. Note that rpmforge also may create apt sources
7636 # in /etc/apt/sources.list.d/. Therefore rather than trying to assume what package manager is
7637 # actually running, inxi will merely note the existence of each repo type for apt/yum.
7638 # Also, in rpm, you can install apt-rpm for the apt-get command, so it's not good to check for
7639 # only the commands in terms of selecting which repos to show.
7640 if [[ -d $yum_repo_dir || -f $yum_conf || -d $zypp_repo_dir ]];then
7641 if [[ -d $yum_repo_dir || -f $yum_conf ]];then
7642 # older redhats put their yum data in /etc/yum.conf
7643 repo_files=$( ls $yum_repo_dir*.repo $yum_conf 2>/dev/null )
7645 elif [[ -d $zypp_repo_dir ]];then
7646 repo_files=$( ls $zypp_repo_dir*.repo 2>/dev/null )
7649 if [[ -n $repo_files ]];then
7650 for repo_file in $repo_files
7652 repo_data_working="$( gawk -v repoFile=$repo_file '
7653 # construct the string for the print function to work with, file name: data
7654 function print_line( fileName, repoId, repoUrl ){
7655 print "'$repo_name' sources:" fileName ":" repoId repoUrl
7664 # this is a hack, assuming that each item has these fields listed, we collect the 3
7665 # items one by one, then when the url/enabled fields are set, we print it out and
7666 # reset the data. Not elegant but it works. Note that if enabled was not present
7667 # we assume it is enabled then, and print the line, reset the variables. This will
7668 # miss the last item, so it is printed if found in END
7670 if ( urlData != "" && repoTitle != "" ){
7671 print_line( repoFile, repoTitle, urlData )
7676 gsub( /\[|\]/, "", $1 ) # strip out the brackets
7677 repoTitle = $1 " ~ "
7679 /^(mirrorlist|baseurl)/ {
7680 sub( /(mirrorlist|baseurl)[[:space:]]*=[[:space:]]*/, "", $1 ) # strip out the field starter
7683 # note: enabled = 1. enabled = 0 means disabled
7684 /^enabled[[:space:]]*=/ {
7687 # print out the line if all 3 values are found, otherwise if a new
7688 # repoTitle is hit above, it will print out the line there instead
7690 if ( urlData != "" && enabledStatus != "" && repoTitle != "" ){
7691 if ( enabledStatus !~ /enabled[[:space:]]*=[[:space:]]*0/ ){
7692 print_line( repoFile, repoTitle, urlData )
7700 # print the last one if there is data for it
7701 if ( urlData != "" && repoTitle != "" ){
7702 print_line( repoFile, repoTitle, urlData )
7707 # then load the global for each file as it gets filled
7708 if [[ -n $repo_data_working ]];then
7709 if [[ -z $REPO_DATA ]];then
7710 REPO_DATA="$repo_data_working"
7712 REPO_DATA="$REPO_DATA
7715 repo_data_working=''
7719 # pacman - archlinux, going to assume that pisi and arch/pacman, etc don't have the above issue with apt/yum
7720 elif [[ -f $pacman_conf ]];then
7721 # get list of mirror include files, trim white space off ends
7722 repo_data_working="$( gawk '
7727 /^[[:space:]]*Include/ {
7728 sub(/^[[:space:]]+|[[:space:]]+$/,"",$2)
7732 # sort into unique paths only, to be used to search for server = data
7733 repo_data_working=$( sort -bu <<< "$repo_data_working" | uniq )
7734 repo_data_working="$repo_data_working $pacman_conf"
7735 for repo_file in $repo_data_working
7737 if [[ -f $repo_file ]];then
7738 # inserting a new line after each found / processed match
7739 repo_data_working2="$repo_data_working2$( gawk -v repoFile=$repo_file '
7744 /^[[:space:]]*Server/ {
7745 sub(/^[[:space:]]+|[[:space:]]+$/,"",$2)
7746 print "pacman repo servers:" repoFile ":" $2 "\\n"
7750 echo "Error: file listed in $pacman_conf does not exist - $repo_file"
7753 # execute line breaks
7754 REPO_DATA="$( echo -e $repo_data_working2 )"
7756 elif [[ -d $pisi_dir && -n $( type -p pisi ) ]];then
7757 REPO_DATA="$( pisi list-repo )"
7758 # now we need to create the structure: repo info: repo path
7759 # we do that by looping through the lines of the output and then
7760 # putting it back into the <data>:<url> format print repos expects to see
7761 # note this structure in the data, so store first line and make start of line
7762 # then when it's an http line, add it, and create the full line collection.
7763 # Pardus-2009.1 [Aktiv]
7764 # http://packages.pardus.org.tr/pardus-2009.1/pisi-index.xml.bz2
7766 # http://packages.pardus.org.tr/contrib-2009/pisi-index.xml.bz2
7767 while read repo_line
7771 # need to dump leading/trailing spaces and clear out color codes for irc output
7772 sub(/^[[:space:]]+|[[:space:]]+$/,"",$0)
7773 # gsub(/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]/,"",$0) # leaving this pattern in case need it
7774 gsub(/
\e\[([0-9];)?[0-9]+m/,"",$0)
7777 if [[ -n $( grep '://' <<< $repo_line ) ]];then
7778 repo_data_working="$repo_data_working:$repo_line\n"
7780 repo_data_working="${repo_data_working}pisi repo:$repo_line"
7782 done <<< "$REPO_DATA"
7783 # echo and execute the line breaks inserted
7784 REPO_DATA="$( echo -e $repo_data_working )"
7785 # Mandriva/Mageia using: urpmq
7786 elif [[ -n $( type -p urpmq ) ]];then
7787 REPO_DATA="$( urpmq --list-media active --list-url )"
7788 # now we need to create the structure: repo info: repo path
7789 # we do that by looping through the lines of the output and then
7790 # putting it back into the <data>:<url> format print repos expects to see
7791 # note this structure in the data, so store first line and make start of line
7792 # then when it's an http line, add it, and create the full line collection.
7793 # Contrib ftp://ftp.uwsg.indiana.edu/linux/mandrake/official/2011/x86_64/media/contrib/release
7794 # Contrib Updates ftp://ftp.uwsg.indiana.edu/linux/mandrake/official/2011/x86_64/media/contrib/updates
7795 # Non-free ftp://ftp.uwsg.indiana.edu/linux/mandrake/official/2011/x86_64/media/non-free/release
7796 # Non-free Updates ftp://ftp.uwsg.indiana.edu/linux/mandrake/official/2011/x86_64/media/non-free/updates
7797 # Nonfree Updates (Local19) /mnt/data/mirrors/mageia/distrib/cauldron/x86_64/media/nonfree/updates
7798 while read repo_line
7802 # need to dump leading/trailing spaces and clear out color codes for irc output
7803 sub(/^[[:space:]]+|[[:space:]]+$/,"",$0)
7804 # gsub(/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]/,"",$0) # leaving this pattern in case need it
7805 gsub(/
\e\[([0-9];)?[0-9]+m/,"",$0)
7808 # urpmq output is the same each line, repo name space repo url, can be:
7809 # rsync://, ftp://, file://, http:// OR repo is locally mounted on FS in some cases
7810 if [[ -n $( grep -E '(://|[[:space:]]/)' <<< $repo_line ) ]];then
7811 # cut out the repo first
7812 repo_data_working2=$( grep -Eo '([^[:space:]]+://|[[:space:]]/).*' <<< $repo_line )
7813 # then get the repo name string by slicing out the url string
7814 repo_name=$( sed "s|[[:space:]]*$repo_data_working2||" <<< $repo_line )
7815 repo_data_working="${repo_data_working}urpmq repo:$repo_name:$repo_data_working2\n"
7817 done <<< "$REPO_DATA"
7818 # echo and execute the line breaks inserted
7819 REPO_DATA="$( echo -e $repo_data_working )"
7820 elif [[ -f $freebsd_conf ]];then
7821 REPO_DATA="$( gawk -F '=' -v repoFile=$freebsd_conf '
7826 print "BSD ports servers:" repoFile ":" $2
7837 local runlevel_path=$( type -p runlevel )
7838 if [[ -n $runlevel_path ]];then
7839 runlvl="$( $runlevel_path | gawk '{ print $2 }' )"
7845 # note: it appears that at least as of 2014-01-13, /etc/inittab is going to be used for
7846 # default runlevel in upstart/sysvinit. systemd default is not always set so check to see
7848 get_runlevel_default()
7851 local default_runlvl=''
7852 local inittab='/etc/inittab'
7853 local systemd_default='/etc/systemd/system/default.target'
7854 local upstart_default='/etc/init/rc-sysinit.conf'
7856 # note: systemd systems do not necessarily have this link created
7857 if [[ -L $systemd_default ]];then
7858 default_runlvl=$( readlink $systemd_default )
7859 if [[ -n $default_runlvl ]];then
7860 default_runlvl=$( basename $default_runlvl )
7862 # http://askubuntu.com/questions/86483/how-can-i-see-or-change-default-run-level
7863 # note that technically default can be changed at boot but for inxi purposes that does
7864 # not matter, we just want to know the system default
7865 elif [[ -e $upstart_default ]];then
7866 # env DEFAULT_RUNLEVEL=2
7867 default_runlvl=$( gawk -F '=' '/^env[[:space:]]+DEFAULT_RUNLEVEL/ {
7869 }' $upstart_default )
7872 # handle weird cases where null but inittab exists
7873 if [[ -z $default_runlvl && -f $inittab ]];then
7874 default_runlvl=$( gawk -F ':' '
7875 /^id.*initdefault/ {
7879 echo $default_runlvl
7891 if [[ -n $Sensors_Data ]];then
7892 # note: non-configured sensors gives error message, which we need to redirect to stdout
7893 # also, -F ':' no space, since some cases have the data starting right after,like - :1287
7895 gawk -F ':' -v userCpuNo="$SENSORS_CPU_NO" '
7898 core0Temp="" # only if all else fails...
7902 indexCountaFanMain=0
7903 indexCountaFanDefault=0
7913 tempFanType="" # set to 1 or 2
7918 # new data arriving: gpu temp in sensors, have to skip that
7919 /^('"$SENSORS_GPU_SEARCH"')-pci/ {
7920 while ( getline && !/^$/ ) {
7921 # do nothing, just skip it
7924 # dumping the extra + signs after testing for them, nobody has negative temps.
7925 # also, note gawk treats ° as a space, so we have to get the C/F data
7926 # there are some guesses here, but with more sensors samples it will get closer.
7927 # note: using arrays starting at 1 for all fan arrays to make it easier overall
7928 # more validation because gensub if fails to get match returns full string, so
7929 # we have to be sure we are working with the actual real string before assiging
7930 # data to real variables and arrays. Extracting C/F degree unit as well to use
7931 # when constructing temp items for array.
7932 # note that because of charset issues, no tempUnit="°" tempWorkingUnit degree sign
7933 # used, but it is required in testing regex to avoid error.
7934 /^(M\/B|MB|SIO|SYS)(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
7935 moboTemp=gensub( /[ \t]+\+([0-9\.]*)(.*)/, "\\1", 1, $2 )
7936 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
7937 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
7938 tempUnit=tempWorkingUnit
7941 /^CPU(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
7942 cpuTemp=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
7943 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
7944 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
7945 tempUnit=tempWorkingUnit
7948 /^(P\/S|Power)(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
7949 psuTemp=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
7950 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
7951 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
7952 tempUnit=tempWorkingUnit
7955 $1 ~ /^temp1$/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
7956 tempWorking=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
7957 if ( temp1 == "" || tempWorking > 0 ) {
7960 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
7961 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
7962 tempUnit=tempWorkingUnit
7965 $1 ~ /^temp2$/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
7966 tempWorking=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
7967 if ( temp2 == "" || tempWorking > 0 ) {
7970 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
7971 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
7972 tempUnit=tempWorkingUnit
7976 # final fallback if all else fails, funtoo user showed sensors putting
7977 # temp on wrapped second line, not handled
7978 /^(core0|core 0)(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
7979 tempWorking=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
7980 if ( core0Temp == "" || tempWorking > 0 ) {
7981 core0Temp=tempWorking
7983 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
7984 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
7985 tempUnit=tempWorkingUnit
7989 # note: can be cpu fan:, cpu fan speed:, etc. Some cases have no space before
7990 # $2 starts (like so :1234 RPM), so skip that space test in regex
7991 /^CPU(.*)[ \t]*([0-9]+)[ \t]RPM/ {
7992 aFanMain[1]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
7994 /^(M\/B|MB|SYS)(.*)[ \t]*([0-9]+)[ \t]RPM/ {
7995 aFanMain[2]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
7997 /(Power|P\/S|POWER)(.*)[ \t]*([0-9]+)[ \t]RPM/ {
7998 aFanMain[3]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
8000 # note that the counters are dynamically set for fan numbers here
8001 # otherwise you could overwrite eg aux fan2 with case fan2 in theory
8002 # note: cpu/mobo/ps are 1/2/3
8003 # NOTE: test: ! i in array does NOT work, this appears to be an awk/gawk bug
8004 /^(AUX(1)? |CASE(1)? |CHASSIS(1)? )(.*)[ \t]*([0-9]+)[ \t]RPM/ {
8005 for ( i = 4; i < 7; i++ ){
8006 if ( i in aFanMain ){
8010 aFanMain[i]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
8015 /^(AUX([2-9]) |CASE([2-9]) |CHASSIS([2-9]) )(.*)[ \t]*([0-9]+)[ \t]RPM/ {
8016 for ( i = 5; i < 30; i++ ){
8017 if ( i in aFanMain ) {
8022 aFanMain[i]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
8027 # in rare cases syntax is like: fan1: xxx RPM
8028 /^(FAN(1)?[ \t:])(.*)[ \t]*([0-9]+)[ \t]RPM/ {
8029 aFanDefault[1]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
8031 /^FAN([2-9]|1[0-9])(.*)[ \t]*([0-9]+)[ \t]RPM/ {
8032 fanWorking=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
8033 sysFanNu=gensub( /fan([0-9]+)/, "\\1", 1, $1 )
8034 if ( sysFanNu ~ /^([0-9]+)$/ ) {
8035 # add to array if array index does not exist OR if number is > existing number
8036 if ( sysFanNu in aFanDefault ) {
8037 if ( fanWorking >= aFanDefault[sysFanNu] ) {
8038 aFanDefault[sysFanNu]=fanWorking
8042 aFanDefault[sysFanNu]=fanWorking
8048 # first we need to handle the case where we have to determine which temp/fan to use for cpu and mobo:
8049 # note, for rare cases of weird cool cpus, user can override in their prefs and force the assignment
8050 if ( temp1 != "" && temp2 != "" ){
8051 if ( userCpuNo != "" && userCpuNo ~ /(1|2)/ ) {
8052 tempFanType=userCpuNo
8055 # first some fringe cases with cooler cpu than mobo: assume which is cpu temp based on fan speed
8056 # but only if other fan speed is 0
8057 if ( temp1 >= temp2 && 1 in aFanDefault && 2 in aFanDefault && aFanDefault[1] == 0 && aFanDefault[2] > 0 ) {
8060 else if ( temp2 >= temp1 && 1 in aFanDefault && 2 in aFanDefault && aFanDefault[2] == 0 && aFanDefault[1] > 0 ) {
8063 # then handle the standard case if these fringe cases are false
8064 else if ( temp1 >= temp2 ) {
8072 # need a case for no temps at all reported, like with old intels
8073 else if ( temp2 == "" && cpuTemp == "" ){
8074 if ( temp1 == "" && moboTemp == "" ){
8077 else if ( temp1 != "" && moboTemp == "" ){
8080 else if ( temp1 != "" && moboTemp != "" ){
8085 # then get the real cpu temp, best guess is hottest is real
8086 if ( cpuTemp != "" ){
8089 else if ( tempFanType != "" ){
8090 if ( tempFanType == 1 ){
8100 # if all else fails, use core0 temp if it is present and cpu is null
8101 if ( cpuTempReal == "" && core0Temp != "" ) {
8102 cpuTempReal=core0Temp
8105 # then the real mobo temp
8106 if ( moboTemp != "" ){
8107 moboTempReal=moboTemp
8109 else if ( tempFanType != "" ){
8110 if ( tempFanType == 1 ) {
8120 # then set the cpu fan speed
8121 if ( aFanMain[1] == "" ) {
8122 # note, you cannot test for aFanDefault[1] or [2] != ""
8123 # because that creates an array item in gawk just by the test itself
8124 if ( tempFanType == 1 && 1 in aFanDefault ) {
8125 aFanMain[1]=aFanDefault[1]
8128 else if ( tempFanType == 2 && 2 in aFanDefault ) {
8129 aFanMain[1]=aFanDefault[2]
8134 # then we need to get the actual numeric max array count for both fan arrays
8135 for (i = 0; i <= 29; i++) {
8136 if ( i in aFanMain && i > indexCountaFanMain ) {
8137 indexCountaFanMain=i
8140 for (i = 0; i <= 14; i++) {
8141 if ( i in aFanDefault && i > indexCountaFanDefault ) {
8142 indexCountaFanDefault=i
8146 # clear out any duplicates. Primary fan real trumps fan working always if same speed
8147 for (i = 1; i <= indexCountaFanMain; i++) {
8148 if ( i in aFanMain && aFanMain[i] != "" && aFanMain[i] != 0 ) {
8149 for (j = 1; j <= indexCountaFanDefault; j++) {
8150 if ( j in aFanDefault && aFanMain[i] == aFanDefault[j] ) {
8157 # now see if you can find the fast little mobo fan, > 5000 rpm and put it as mobo
8158 # note that gawk is returning true for some test cases when aFanDefault[j] < 5000
8159 # which has to be a gawk bug, unless there is something really weird with arrays
8160 # note: 500 > aFanDefault[j] < 1000 is the exact trigger, and if you manually
8161 # assign that value below, the > 5000 test works again, and a print of the value
8162 # shows the proper value, so the corruption might be internal in awk.
8163 # Note: gensub is the culprit I think, assigning type string for range 501-1000 but
8164 # type integer for all others, this triggers true for >
8165 for (j = 1; j <= indexCountaFanDefault; j++) {
8166 if ( j in aFanDefault && int( aFanDefault[j] ) > 5000 && aFanMain[2] == "" ) {
8167 aFanMain[2] = aFanDefault[j]
8169 # then add one if required for output
8170 if ( indexCountaFanMain < 2 ) {
8171 indexCountaFanMain = 2
8176 # then construct the sys_fan string for echo, note that iteration 1
8177 # makes: fanDefaultString separator null, ie, no space or ,
8178 for (j = 1; j <= indexCountaFanDefault; j++) {
8179 fanDefaultString = fanDefaultString separator aFanDefault[j]
8182 separator="" # reset to null for next loop
8183 # then construct the sys_fan string for echo
8184 for (j = 1; j <= indexCountaFanMain; j++) {
8185 fanMainString = fanMainString separator aFanMain[j]
8189 # and then build the temps:
8190 if ( moboTempReal != "" ) {
8191 moboTempReal = moboTempReal tempUnit
8193 if ( cpuTempReal != "" ) {
8194 cpuTempReal = cpuTempReal tempUnit
8197 # if they are ALL null, print error message. psFan is not used in output currently
8198 if ( cpuTempReal == "" && moboTempReal == "" && aFanMain[1] == "" && aFanMain[2] == "" && aFanMain[3] == "" && fanDefaultString == "" ) {
8199 print "No active sensors found. Have you configured your sensors yet?"
8202 # then build array arrays:
8203 print cpuTempReal "," moboTempReal "," psuTemp
8204 # this is for output, a null print line does NOT create a new array index in bash
8205 if ( fanMainString == "" ) {
8209 print fanDefaultString
8211 }' <<< "$Sensors_Data" ) )
8215 temp_array=${A_SENSORS_DATA[@]}
8216 log_function_data "A_SENSORS_DATA: $temp_array"
8217 # echo "A_SENSORS_DATA: ${A_SENSORS_DATA[@]}"
8221 get_sensors_output()
8223 local sensors_path=$( type -p sensors ) sensors_data=''
8225 if [[ -n $sensors_path ]];then
8226 sensors_data="$( $sensors_path 2>/dev/null )"
8227 if [[ -n "$sensors_data" ]];then
8228 # make sure the file ends in newlines then characters, the newlines are lost in the echo unless
8229 # the data ends in some characters
8230 sensors_data="$sensors_data\n\n###"
8233 echo -e "$sensors_data"
8240 local shell_type="$( ps -p $PPID -o comm= 2>/dev/null )"
8241 local shell_version=''
8243 if [[ $B_EXTRA_DATA == 'true' && -n $shell_type ]];then
8246 shell_version=$( get_de_app_version "$shell_type" "^GNU[[:space:]]bash,[[:space:]]version" "4" | \
8247 sed $SED_RX 's/(\(.*|-release|-version)//' )
8249 # csh/dash use dpkg package version data, debian/buntu only
8251 shell_version=$( get_de_app_version "$shell_type" "^tcsh" "2" )
8254 shell_version=$( get_de_app_version "$shell_type" "$shell_type" "3" )
8257 shell_version=$( get_de_app_version "$shell_type" "version" "5" )
8260 shell_version=$( get_de_app_version "$shell_type" "^tcsh" "2" )
8263 shell_version=$( get_de_app_version "$shell_type" "^zsh" "2" )
8267 if [[ -n $shell_version ]];then
8268 shell_type="$shell_type $shell_version"
8278 local shell_parent='' script_parent=''
8280 # removed --no-headers to make bsd safe, adding in -j to make output the same
8281 script_parent=$( ps -j -fp $PPID 2>/dev/null | gawk '/'"$PPID"'/ { print $3 }' )
8282 log_function_data "script parent: $script_parent"
8283 shell_parent=$( ps -j -p $script_parent 2>/dev/null | gawk '/'"$script_parent"'/ { print $NF}' )
8284 # no idea why have to do script_parent action twice in su case, but you do, oh well.
8285 if [[ $shell_parent == 'su' ]];then
8286 script_parent=$( ps -j -fp $script_parent 2>/dev/null | gawk '/'"$script_parent"'/ { print $3 }' )
8287 script_parent=$( ps -j -fp $script_parent 2>/dev/null | gawk '/'"$script_parent"'/ { print $3 }' )
8288 shell_parent=$( ps -j -p $script_parent 2>/dev/null | gawk '/'"$script_parent"'/ { print $NF}' )
8291 log_function_data "shell parent final: $shell_parent"
8295 # this will be used for some bsd data types
8296 # args: $1 - option type
8301 local sysctl_data=''
8303 if [[ $B_SYSCTL ]];then
8304 sysctl_data="$( sysctl -$1 )"
8306 # log_function_data "sysctl_data: $sysctl_data"
8311 get_tty_console_irc()
8315 if [[ -n ${IRC_CLIENT} ]];then
8316 tty_number=$( gawk '
8320 # if multiple irc clients open, can give wrong results
8321 # so make sure to also use the PPID number to get the right tty
8322 /.*'$PPID'.*'${IRC_CLIENT}'/ {
8323 gsub(/[^0-9]/, "", $7)
8326 }' <<< "$Ps_aux_Data" )
8328 log_function_data "tty_number: $tty_number"
8337 local tty_number=$( basename "$( tty 2>/dev/null )" | sed 's/[^0-9]*//g' )
8344 get_unmounted_partition_data()
8347 local a_unmounted_working='' mounted_partitions='' separator='|' unmounted_fs=''
8348 local dev_working='' uuid_working='' label_working='' a_raid_working='' raid_partitions=''
8350 if [[ $B_PARTITIONS_FILE == 'true' ]];then
8351 # set dev disk label/uuid data globals
8352 get_partition_dev_data 'label'
8353 get_partition_dev_data 'uuid'
8354 # load the raid data array here so we can exclude its partitions
8355 if [[ $B_RAID_SET != 'true' ]];then
8358 # sr0 type cd drives are showing up now as unmounted partitions
8359 mounted_partitions="scd[0-9]+|sr[0-9]+|cdrom[0-9]*|cdrw[0-9]*|dvd[0-9]*|dvdrw[0-9]*"
8360 # create list for slicing out the mounted partitions
8361 for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
8364 a_unmounted_working=( ${A_PARTITION_DATA[i]} )
8366 if [[ -n ${a_unmounted_working[6]} ]];then
8367 mounted_partitions="$mounted_partitions$separator${a_unmounted_working[6]}"
8370 # now we need to exclude the mdraid partitions from the unmounted partition output as well
8371 for (( i=0; i < ${#A_RAID_DATA[@]}; i++ ))
8374 a_raid_working=( ${A_RAID_DATA[i]} )
8376 if [[ -n ${a_raid_working[3]} ]];then
8377 raid_partitions=$( sed $SED_RX 's/(\([^\)]*\)|\[[^\]]*\])//g' <<< ${a_raid_working[3]}\
8378 | sed 's/[[:space:]]\+/|/g' )
8379 mounted_partitions="$mounted_partitions$separator$raid_partitions"
8383 A_UNMOUNTED_PARTITION_DATA=( $( grep -Ev '[[:space:]]('$mounted_partitions')$' $FILE_PARTITIONS | gawk '
8387 # note that size 1 means it is a logical extended partition container
8388 # lvm might have dm-1 type syntax
8389 # need to exclude loop type file systems, squashfs for example
8390 /[a-z][0-9]+$|dm-[0-9]+$/ && $3 != 1 && $NF !~ /loop/ {
8391 size = sprintf( "%.2f", $3*1024/1000**3 )
8392 print $4 "," size "G"
8395 for (( i=0; i < ${#A_UNMOUNTED_PARTITION_DATA[@]}; i++ ))
8398 a_unmounted_working=( ${A_UNMOUNTED_PARTITION_DATA[i]} )
8401 label_working=$( grep -E "${a_unmounted_working[0]}$" <<< "$DEV_DISK_LABEL" | gawk '{
8404 uuid_working=$( grep -E "${a_unmounted_working[0]}$" <<< "$DEV_DISK_UUID" | gawk '{
8407 unmounted_fs=$( get_unmounted_partition_filesystem "/dev/${a_unmounted_working[0]}" )
8410 A_UNMOUNTED_PARTITION_DATA[i]=${a_unmounted_working[0]}","${a_unmounted_working[1]}","$label_working","$uuid_working","$unmounted_fs
8414 # echo "${A_PARTITION_DATA[@]}"
8415 # echo "${A_UNMOUNTED_PARTITION_DATA[@]}"
8419 # a few notes, normally file -s requires root, but you can set user rights in /etc/sudoers.
8420 # list of file systems: http://en.wikipedia.org/wiki/List_of_file_systems
8421 # args: $1 - /dev/<disk><part> to be tested for
8422 get_unmounted_partition_filesystem()
8425 local partition_filesystem='' sudo_command=''
8427 if [[ $B_FILE_TESTED != 'true' ]];then
8428 B_FILE_TESTED='true'
8429 FILE_PATH=$( type -p file )
8432 if [[ $B_SUDO_TESTED != 'true' ]];then
8433 B_SUDO_TESTED='true'
8434 SUDO_PATH=$( type -p sudo )
8437 if [[ -n $FILE_PATH && -n $1 ]];then
8438 # only use sudo if not root, -n option requires sudo -V 1.7 or greater. sudo will just error out
8439 # which is the safest course here for now, otherwise that interactive sudo password thing is too annoying
8440 # important: -n makes it non interactive, no prompt for password
8441 if [[ $B_ROOT != 'true' && -n $SUDO_PATH ]];then
8442 sudo_command='sudo -n '
8444 # this will fail if regular user and no sudo present, but that's fine, it will just return null
8445 # note the hack that simply slices out the first line if > 1 items found in string
8446 # also, if grub/lilo is on partition boot sector, no file system data is available
8447 # BSD fix: -Eio -Em 1
8448 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 '.*' )
8449 if [[ -n $partition_filesystem ]];then
8450 echo $partition_filesystem
8456 ## return uptime string
8460 ## note: removing gsub(/ /,"",a); to get get space back in there, goes right before print a
8461 local uptime_value="$( uptime | gawk '{
8462 a = gensub(/^.*up *([^,]*).*$/,"\\1","g",$0)
8465 echo "$uptime_value"
8466 log_function_data "uptime_value: $uptime_value"
8474 local location_site='http://geoip.ubuntu.com/lookup'
8475 local weather_feed='http://api.wunderground.com/auto/wui/geo/WXCurrentObXML/index.xml?query='
8476 local weather_spider='http://wunderground.com/'
8477 local data_grab_error='' wget_error=0
8478 local b_test_loc=false b_test_weather=false b_debug=false
8479 local test_dir="$HOME/bin/scripts/inxi/data/weather/"
8480 local test_location='location2.xml' test_weather='weather-feed.xml'
8481 local location_data='' location='' weather_data='' location_array_value='' a_location=''
8482 local weather_array_value='' site_elevation='' temp_array=''
8484 # first we get the location data, once that is parsed and handled, we move to getting the
8485 # actual weather data, assuming no errors
8486 if [[ -n $ALTERNATE_WEATHER_LOCATION ]];then
8487 # note, this api does not support spaces in names, replace spaces with + sign.
8488 location=$ALTERNATE_WEATHER_LOCATION
8489 # echo $ALTERNATE_WEATHER_LOCATION;exit
8491 if [[ $b_test_loc != 'true' ]];then
8492 location_data=$( wget -q -t 1 -T $WGET_TIMEOUT -O- $location_site || wget_error=$? )
8493 log_function_data "$location_data"
8494 if [[ $wget_error -ne 0 ]];then
8495 data_grab_error="Error: location server up but download error - wget: $wget_error"
8499 if [[ -f $test_dir$test_location ]];then
8500 location_data="$( cat $test_dir$test_location )"
8502 data_grab_error="Error: location xml local file not found."
8505 if [[ -n $data_grab_error ]];then
8507 elif [[ -z $( grep -i '<Response' <<< $location_data ) ]];then
8508 data_grab_error="Error: location downloaded but data contains no xml."
8510 # clean up xml and make easy to process with newlines, note, bsd sed has no support for inserting
8511 # \n dircctly so we have to use this hack
8512 # location_data="$( sed $SED_RX 's|><|>\n<|g' <<< $location_data )"
8513 location_data="$( sed $SED_RX 's|><|>\
8514 <|g' <<< $location_data )"
8515 # echo -e "ld:\n$location_data"
8516 location_array_value=$( gawk '
8517 function clean(data) {
8519 # some lines might be empty, so ignore those
8520 if (data !~ /^<[^>]+>$/ ) {
8521 returnData=gensub(/(.*>)([^<]*)(<.*)/, "\\2", 1, data)
8541 if ( $0 ~ /CountryCode3/ ){
8542 countryCode3=clean($0)
8545 countryCode=clean($0)
8549 countryName = clean($0)
8552 regionCode = clean($0)
8555 regionName = clean($0)
8561 postalCode = clean($0)
8564 latitude = clean($0)
8567 longitude = clean($0)
8570 timeZone = clean($0)
8573 locationString = city ";" regionCode ";" regionName ";" countryName ";" countryCode ";" countryCode3
8574 locationString = locationString ";" latitude "," longitude ";" postalCode ";" timeZone
8575 print locationString
8576 }' <<< "$location_data" )
8578 A_WEATHER_DATA[0]=$location_array_value
8580 a_location=( ${A_WEATHER_DATA[0]} )
8583 # assign location, cascade from most accurate
8584 # latitude,longitude first
8585 if [[ -n ${a_location[6]} ]];then
8586 location="${a_location[6]}"
8588 elif [[ -n ${a_location[0]} && -n ${a_location[1]} ]];then
8589 location="${a_location[0]},${a_location[1]}"
8590 # postal code last, that can be a very large region
8591 elif [[ -n ${a_location[7]} ]];then
8592 location=${a_location[7]}
8595 if [[ $b_debug == 'true' ]];then
8596 echo -e "location array:\n${A_WEATHER_DATA[0]}"
8597 echo "location: $location"
8599 log_function_data "location: $location"
8601 if [[ -z $location && -z $data_grab_error ]];then
8602 data_grab_error="Error: location data downloaded but no location detected."
8605 # now either dump process or go on to get weather data
8606 if [[ -z $data_grab_error ]];then
8607 if [[ $b_test_weather != 'true' ]];then
8608 weather_data="$( wget -q -t 1 -T $WGET_TIMEOUT -O- $weather_feed"$location" || wget_error=$? )"
8609 if [[ $wget_error -ne 0 ]];then
8610 data_grab_error="Error: weather server up but download error - wget: $wget_error"
8612 log_function_data "$weather_data"
8614 if [[ -f $test_dir$test_weather ]];then
8615 weather_data="$( cat $test_dir$test_weather)"
8617 data_grab_error="Error: weather feed xml local file not found."
8620 if [[ -z $data_grab_error && -z $( grep -i '<current_observation' <<< $weather_data ) ]];then
8621 data_grab_error="Error: weather data downloaded but shows no xml start."
8623 if [[ -z $data_grab_error ]];then
8625 weather_data=$( sed 's/^[[:space:]]*//' <<< "$weather_data" )
8626 site_elevation=$( grep -im 1 '<elevation>' <<< "$weather_data" | sed $SED_RX -e 's/<[^>]*>//g' \
8628 # we need to grab the location data from the feed for remote checks
8629 if [[ -n $ALTERNATE_WEATHER_LOCATION && -n $weather_data ]];then
8630 location_data=$( sed -e '/<current_observation>/,/<display_location>/d' -e '/<\/display_location>/,/<\/current_observation>/d' <<< "$weather_data" )
8631 # echo -e "ld1:\n$location_data"
8632 A_WEATHER_DATA[0]=$( gawk '
8633 function clean(data) {
8635 # some lines might be empty, so ignore those
8636 if (data !~ /^<[^>]+>$/ ) {
8637 returnData=gensub(/(.*>)([^<]*)(<.*)/, "\\2", 1, data)
8638 gsub(/^[[:space:]]+|[[:space:]]+$|^NA$|^N\/A$/, "", returnData)
8658 print city ";" state ";;;;" country
8659 }' <<< "$location_data" )
8660 # echo -e "location:\n${A_WEATHER_DATA[0]}"
8663 # clean off everything before/after observation_location
8664 weather_data=$( sed -e '/<current_observation>/,/<observation_location>/d' \
8665 -e '/<icons>/,/<\/current_observation>/d' <<< "$weather_data" -e 's/^[[:space:]]*$//g' -e '/^$/d' )
8667 # echo "$weather_data";exit
8668 weather_array_value=$( gawk -v siteElevation="$site_elevation" '
8669 function clean(data) {
8671 # some lines might be empty, so ignore those
8672 if (data !~ /^<[^>]+>$/ ) {
8673 returnData=gensub(/(.*>)([^<]*)(<.*)/, "\\2", 1, data)
8674 gsub(/^[[:space:]]+|[[:space:]]+$|^NA$|^N\/A$/, "", returnData)
8692 /observation_time>/ {
8693 observationTime=clean($0)
8694 sub(/Last Updated on /, "", observationTime )
8702 /temperature_string/ {
8703 tempString=clean($0)
8705 /relative_humidity/ {
8709 windString=clean($0)
8712 pressureString=clean($0)
8714 /heat_index_string/ {
8715 heatIndexString=clean($0)
8717 /windchill_string/ {
8718 windChillString=clean($0)
8721 weatherString = observationTime ";" localTime ";" weather ";" tempString ";" humidity
8722 weatherString = weatherString ";" windString ";" pressureString ";" dewpointString ";" heatIndexString
8723 weatherString = weatherString ";" windChillString ";" siteElevation
8725 }' <<< "$weather_data" )
8727 if [[ -z $weather_array_value ]];then
8728 data_grab_error="Error: weather info downloaded but no data detected."
8730 A_WEATHER_DATA[1]=$weather_array_value
8733 # now either dump process or go on to get weather data
8734 if [[ -n $data_grab_error ]];then
8735 A_WEATHER_DATA=$data_grab_error
8736 log_function_data "data grab error: $data_grab_error"
8739 if [[ $b_debug == 'true' ]];then
8740 echo "site_elevation: $site_elevation"
8741 echo "${A_WEATHER_DATA[1]}"
8743 temp_array=${A_WEATHER_DATA[@]}
8744 log_function_data "A_WEATHER_DATA: $temp_array"
8748 # ALTERNATE_WEATHER_LOCATION='portland,or'
8749 # get_weather_data;exit
8751 #### -------------------------------------------------------------------
8752 #### special data handling for specific options and conditions
8753 #### -------------------------------------------------------------------
8755 # args: $1 - string to strip color code characters out of
8756 # returns count of string length minus colors
8757 calculate_line_length()
8760 # ansi:
\e[1;34m irc: \x0312
8761 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 )
8766 ## multiply the core count by the data to be calculated, bmips, cache
8767 # args: $1 - string to handle; $2 - cpu count
8768 calculate_multicore_data()
8771 local string_number=$1 string_data=''
8773 if [[ -n $( grep -Ei '( mb| kb)' <<< $1 ) ]];then
8774 string_data=" $( gawk '{print $2}' <<< $1 )" # add a space for output
8775 string_number=$( gawk '{print $1}' <<< $1 )
8777 # handle weird error cases where it's not a number
8778 if [[ -n $( grep -E '^[0-9\.,]+$' <<< $string_number ) ]];then
8779 string_number=$( echo $string_number $2 | gawk '{
8783 elif [[ $string_number == '' ]];then
8786 # I believe that the above returns 'unknown' by default so no need for extra text
8787 string_number="$string_number "
8789 echo "$string_number$string_data"
8790 log_function_data "string_numberstring_data: $string_number$string_data"
8794 # prints out shortened list of flags, the main ones of interest
8795 # args: $1 - string of cpu flags to process
8800 local cpu_flags_working=$1
8801 local bits=$( uname -m | grep 64 )
8803 # no need to show pae for 64 bit cpus, it's pointless
8804 if [[ -n $bits ]];then
8805 cpu_flags_working=$( sed 's/[[:space:]]*pae//' <<< "$cpu_flags_working" )
8807 # must have a space after last item in list for RS=" "
8808 cpu_flags_working="$cpu_flags_working "
8810 # nx = AMD stack protection extensions
8811 # lm = Intel 64bit extensions
8812 # sse, sse2, pni = sse1,2,3,4,5 gfx extensions
8813 # svm = AMD pacifica virtualization extensions
8814 # vmx = Intel IVT (vanderpool) virtualization extensions
8819 i = 1 # start at one because of for increment issue
8823 /^(lm|nx|pae|pni|svm|vmx|(sss|ss)e([2-9])?([a-z])?(_[0-9])?)$/ {
8833 count = asort( a_flags )
8834 # note: why does gawk increment before the loop and not after? weird.
8835 for ( i=0; i <= count; i++ ){
8836 if ( flag_string == "" ) {
8837 flag_string = a_flags[i]
8840 flag_string = flag_string " " a_flags[i]
8844 }' <<< "$cpu_flags_working" )
8846 #grep -oE '\<(nx|lm|sse[0-9]?|pni|svm|vmx)\>' | tr '\n' ' '))
8847 if [[ -z $cpu_flags ]];then
8851 log_function_data "cpu_flags: $cpu_flags"
8855 #### -------------------------------------------------------------------
8856 #### print and processing of output data
8857 #### -------------------------------------------------------------------
8859 #### MASTER PRINT FUNCTION - triggers all line item print functions
8860 ## main function to print out, master for all sub print functions.
8864 # note that print_it_out passes local variable values on to its children,
8865 # and in some cases, their children, with Lspci_v_Data
8866 local Lspci_v_Data='' Lspci_n_Data='' # only for verbose
8867 local Sysctl_a_Data='' Dmesg_Boot_Data=''
8869 if [[ -n $BSD_TYPE ]];then
8870 Sysctl_a_Data="$( get_sysctl_data 'a' )"
8871 Dmesg_Boot_Data="$( get_dmesg_boot_data )"
8874 if [[ $B_SHOW_SHORT_OUTPUT == 'true' ]];then
8877 Lspci_v_Data="$( get_lspci_data 'v' )"
8878 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
8879 Lspci_n_Data="$( get_lspci_data 'n' )"
8881 if [[ $B_SHOW_SYSTEM == 'true' ]];then
8884 if [[ $B_SHOW_MACHINE == 'true' ]];then
8887 if [[ $B_SHOW_WEATHER == 'true' ]];then
8890 if [[ $B_SHOW_BASIC_CPU == 'true' || $B_SHOW_CPU == 'true' ]];then
8893 if [[ $B_SHOW_GRAPHICS == 'true' ]];then
8896 if [[ $B_SHOW_AUDIO == 'true' ]];then
8899 if [[ $B_SHOW_NETWORK == 'true' ]];then
8900 print_networking_data
8902 if [[ $B_SHOW_DISK_TOTAL == 'true' || $B_SHOW_BASIC_DISK == 'true' || $B_SHOW_DISK == 'true' ]];then
8903 print_hard_disk_data
8905 if [[ $B_SHOW_PARTITIONS == 'true' ]];then
8906 print_partition_data
8908 if [[ $B_SHOW_RAID == 'true' || $B_SHOW_BASIC_RAID == 'true' ]];then
8911 if [[ $B_SHOW_UNMOUNTED_PARTITIONS == 'true' ]];then
8912 print_unmounted_partition_data
8914 if [[ $B_SHOW_SENSORS == 'true' ]];then
8917 if [[ $B_SHOW_REPOS == 'true' ]];then
8920 if [[ $B_SHOW_PS_CPU_DATA == 'true' || $B_SHOW_PS_MEM_DATA == 'true' ]];then
8923 if [[ $B_SHOW_INFO == 'true' ]];then
8930 #### SHORT OUTPUT PRINT FUNCTION, ie, verbosity 0
8931 # all the get data stuff is loaded here to keep execution time down for single line print commands
8932 # these will also be loaded in each relevant print function for long output
8936 local current_kernel=$( get_kernel_version )
8937 local processes=$(( $( wc -l <<< "$Ps_aux_Data" ) - 1 ))
8938 local short_data='' i='' b_background_black='false'
8939 local memory=$( get_memory_data )
8940 local up_time="$( get_uptime )"
8942 # set A_CPU_CORE_DATA
8944 local cpc_plural='' cpu_count_print='' model_plural=''
8945 local cpu_physical_count=${A_CPU_CORE_DATA[0]}
8946 local cpu_core_count=${A_CPU_CORE_DATA[3]}
8947 local cpu_core_alpha=${A_CPU_CORE_DATA[1]}
8948 local cpu_type=${A_CPU_CORE_DATA[2]}
8950 if [[ $cpu_physical_count -gt 1 ]];then
8953 cpu_count_print="$cpu_physical_count "
8956 local cpu_data_string="${cpu_count_print}${cpu_core_alpha} core"
8957 # local cpu_core_count=${A_CPU_CORE_DATA[0]}
8961 ## note: if hdd_model is declared prior to use, whatever string you want inserted will
8962 ## be inserted first. In this case, it's desirable to print out (x) before each disk found.
8963 local a_hdd_data_count=$(( ${#A_HDD_DATA[@]} - 1 ))
8965 local a_hdd_basic_working=( ${A_HDD_DATA[$a_hdd_data_count]} )
8967 local hdd_capacity=${a_hdd_basic_working[0]}
8968 local hdd_used=${a_hdd_basic_working[1]}
8974 local a_cpu_working=(${A_CPU_DATA[0]})
8976 local cpu_model="${a_cpu_working[0]}"
8977 ## assemble data for output
8978 local cpu_clock="${a_cpu_working[1]}" # old CPU3
8979 # this gets that weird min/max final array item, which almost never contains any data of use
8980 local min_max_clock_nu=$(( ${#A_CPU_DATA[@]} - 1 ))
8981 local min_max_clock=${A_CPU_DATA[$min_max_clock_nu]}
8982 # this handles the case of for example ARM cpus, which will not have data for
8983 # min/max, since they don't have speed. Since that sets a flag, not found, just
8984 # look for that and use the speed from the first array array, same where we got
8986 if [[ "$min_max_clock" == 'N/A' && ${a_cpu_working[1]} != '' ]];then
8987 min_max_clock="${a_cpu_working[1]} MHz"
8989 local patch_version_number=$( get_patch_version_string )
8991 #set_color_scheme 12
8992 if [[ $B_RUNNING_IN_SHELL == 'false' ]];then
8993 for i in $C1 $C2 $CN
8996 "$GREEN"|"$WHITE"|"$YELLOW"|"$CYAN")
8997 b_background_black='true'
9001 if [[ $b_background_black == 'true' ]];then
9004 ## these need to be in quotes, don't know why
9005 if [[ ${!i} == $NORMAL ]];then
9006 declare $i="${!i}15,1"
9008 declare $i="${!i},1"
9011 #C1="${C1},1"; C2="${C2},1"; CN="${CN},1"
9014 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}"
9016 if [[ $SHOW_IRC -gt 0 ]];then
9017 short_data="${short_data}${C1}Client${C2}${SEP1}${IRC_CLIENT}${IRC_CLIENT_VERSION}${SEP2}"
9019 short_data="${short_data}${C1}$SCRIPT_NAME${C2}${SEP1}$SCRIPT_VERSION_NUMBER$patch_version_number${SEP2}${CN}"
9020 if [[ $SCHEME -gt 0 ]];then
9021 short_data="${short_data} $NORMAL"
9023 print_screen_output "$short_data"
9027 #### LINE ITEM PRINT FUNCTIONS
9029 # print sound card data
9033 local i='' card_id='' audio_data='' a_audio_data='' port_data='' pci_bus_id='' card_string=''
9034 local a_audio_working='' audio_driver='' alsa_data='' port_plural='' module_version='' chip_id=''
9035 local bus_usb_text='' bus_usb_id='' line_starter='Audio:' alsa='' alsa_version='' print_data=''
9037 # set A_AUDIO_DATA and get alsa data
9038 if [[ $BSD_TYPE == 'bsd' ]];then
9039 if [[ $B_PCICONF_SET == 'false' ]];then
9042 get_pciconf_card_data 'audio'
9048 # alsa driver data now prints out no matter what
9049 if [[ -n $A_ALSA_DATA ]];then
9051 if [[ -n ${A_ALSA_DATA[0]} ]];then
9052 alsa=${A_ALSA_DATA[0]}
9056 if [[ -n ${A_ALSA_DATA[1]} ]];then
9057 alsa_version=${A_ALSA_DATA[1]}
9061 alsa_data="${C1}Sound:${C2} $alsa ${C1}ver$SEP3${C2} $alsa_version"
9064 # note, error handling is done in the get function, so this will never be null, but
9065 # leaving the test just in case it's changed.
9066 if [[ -n ${A_AUDIO_DATA[@]} ]];then
9067 for (( i=0; i< ${#A_AUDIO_DATA[@]}; i++ ))
9070 a_audio_working=( ${A_AUDIO_DATA[i]} )
9085 if [[ ${#A_AUDIO_DATA[@]} -gt 1 ]];then
9086 card_id="-$(( $i + 1 ))"
9088 if [[ $BSD_TYPE != 'bsd' ]];then
9089 if [[ -n ${a_audio_working[3]} && $B_EXTRA_DATA == 'true' ]];then
9090 module_version=$( print_module_version "${a_audio_working[3]}" 'audio' )
9091 elif [[ -n ${a_audio_working[1]} && $B_EXTRA_DATA == 'true' ]];then
9092 module_version=$( print_module_version "${a_audio_working[1]}" 'audio' )
9095 # we're testing for the presence of the 2nd array item here, which is the driver name
9096 if [[ -n ${a_audio_working[1]} ]];then
9097 # note: linux drivers can have numbers, like tg3
9098 if [[ $BSD_TYPE == 'bsd' ]];then
9099 driver=$( sed 's/[0-9]$//' <<< ${a_audio_working[1]} )
9101 driver=${a_audio_working[1]}
9103 audio_driver="${C1}driver$SEP3${C2} ${driver} "
9105 if [[ -n ${a_audio_working[2]} && $B_EXTRA_DATA == 'true' ]];then
9106 if [[ $( wc -w <<< ${a_audio_working[2]} ) -gt 1 ]];then
9109 port_data="${C1}port$port_plural$SEP3${C2} ${a_audio_working[2]} "
9111 if [[ -n ${a_audio_working[4]} && $B_EXTRA_DATA == 'true' ]];then
9112 if [[ ${a_audio_working[1]} != 'USB Audio' ]];then
9113 bus_usb_text='bus-ID'
9114 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
9115 if [[ $BSD_TYPE != 'bsd' ]];then
9116 chip_id=$( get_lspci_chip_id "${a_audio_working[4]}" )
9118 chip_id=${a_audio_working[6]}
9122 bus_usb_text='usb-ID'
9123 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
9124 chip_id=${a_audio_working[5]}
9127 bus_usb_id=${a_audio_working[4]}
9128 pci_bus_id="${C1}$bus_usb_text$SEP3${C2} $bus_usb_id "
9129 if [[ -n $chip_id ]];then
9130 chip_id="${C1}chip-ID$SEP3${C2} $chip_id "
9133 if [[ -n ${a_audio_working[0]} ]];then
9134 card_string="${C1}Card$card_id:${C2} ${a_audio_working[0]} "
9135 audio_data="$audio_driver$port_data$pci_bus_id$chip_id"
9137 # only print alsa on last line if short enough, otherwise print on its own line
9138 if [[ $i -eq 0 ]];then
9139 if [[ -n $alsa_data && $( calculate_line_length "$card_string${audio_data}$alsa_data" ) -lt $COLS_INNER ]];then
9140 audio_data="$audio_data$alsa_data"
9144 if [[ -n $audio_data ]];then
9145 if [[ $( calculate_line_length "$card_string$audio_data" ) -lt $COLS_INNER ]];then
9146 print_data=$( create_print_line "$line_starter" "$card_string$audio_data" )
9147 print_screen_output "$print_data"
9150 # keep the driver on the same line no matter what, looks weird alone on its own line
9151 if [[ $B_EXTRA_DATA != 'true' ]];then
9152 print_data=$( create_print_line "$line_starter" "$card_string$audio_data" )
9153 print_screen_output "$print_data"
9155 print_data=$( create_print_line "$line_starter" "$card_string" )
9156 print_screen_output "$print_data"
9158 print_data=$( create_print_line "$line_starter" "$audio_data" )
9159 print_screen_output "$print_data"
9166 if [[ -n $alsa_data ]];then
9167 alsa_data=$( sed 's/ALSA/Advanced Linux Sound Architecture/' <<< $alsa_data )
9168 alsa_data=$( create_print_line "$line_starter" "$alsa_data" )
9169 print_screen_output "$alsa_data"
9177 local cpu_data='' i='' cpu_clock_speed='' cpu_multi_clock_data=''
9178 local bmip_data='' cpu_cache='' cpu_vendor='' cpu_flags='' flag_feature='flags'
9179 local a_cpu_working='' cpu_model='' cpu_clock='' cpu_null_error=''
9180 local cpc_plural='' cpu_count_print='' model_plural='' cpu_data_string=''
9181 local cpu_physical_count='' cpu_core_count='' cpu_core_alpha='' cpu_type=''
9182 local cpu_2_data='' line_starter=''
9184 ##print_screen_output "A_CPU_DATA[0]=\"${A_CPU_DATA[0]}\""
9185 # Array A_CPU_DATA always has one extra element: max clockfreq found.
9186 # that's why its count is one more than you'd think from cores/cpus alone
9191 a_cpu_working=(${A_CPU_DATA[0]})
9194 # Strange (and also some expected) behavior encountered. If print_screen_output() uses $1
9195 # as the parameter to output to the screen, then passing "<text1> ${ARR[@]} <text2>"
9196 # will output only <text1> and first element of ARR. That "@" splits in elements and "*" _doesn't_,
9197 # is to be expected. However, that text2 is consecutively truncated is somewhat strange, so take note.
9198 # This has been confirmed by #bash on freenode.
9199 # The above mentioned only emerges when using the debugging markers below
9200 ## print_screen_output "a_cpu_working=\"***${a_cpu_working[@]} $hostName+++++++\"----------"
9201 # unless all these are null, process whatever you have
9202 if [[ -n ${a_cpu_working[0]} || -n ${a_cpu_working[1]} || -n ${a_cpu_working[2]} || -n ${a_cpu_working[3]} ]];then
9203 cpu_model="${a_cpu_working[0]}"
9204 ## assemble data for output
9205 cpu_clock="${a_cpu_working[1]}"
9207 cpu_vendor=${a_cpu_working[5]}
9209 # set A_CPU_CORE_DATA
9211 cpu_physical_count=${A_CPU_CORE_DATA[0]}
9212 cpu_core_count=${A_CPU_CORE_DATA[3]}
9213 cpu_core_alpha=${A_CPU_CORE_DATA[1]}
9214 cpu_type=${A_CPU_CORE_DATA[2]}
9216 if [[ $cpu_physical_count -gt 1 ]];then
9218 cpu_count_print="$cpu_physical_count "
9221 line_starter="CPU$cpc_plural:"
9222 cpu_data_string="${cpu_count_print}${cpu_core_alpha} core"
9223 cpu_data="${C1}${cpu_data_string}${C2} ${a_cpu_working[0]}$model_plural (${cpu_type})"
9224 if [[ $B_SHOW_CPU == 'true' ]];then
9225 # update for multicore, bogomips x core count.
9226 if [[ $B_EXTRA_DATA == 'true' ]];then
9227 # if [[ $cpu_vendor != 'intel' ]];then
9228 # ARM may use the faked 1 cpucorecount to make this work
9229 # echo $cpu_core_count $cpu_physical_count
9230 if [[ -n ${a_cpu_working[4]} ]];then
9231 bmip_data=$( calculate_multicore_data "${a_cpu_working[4]}" "$(( $cpu_core_count * $cpu_physical_count ))" )
9232 bmip_data=${bmip_data%.*}
9235 # bmip_data="${a_cpu_working[4]}"
9237 # bogomips are a linux thing, but my guess is over time bsds will use them somewhere anyway
9238 if [[ $BSD_TYPE == 'bsd' && -z $bmip_data ]];then
9241 bmip_data="${C1}bmips$SEP3${C2} $bmip_data "
9244 ## note: this handles how intel reports L2, total instead of per core like AMD does
9245 # note that we need to multiply by number of actual cpus here to get true cache size
9246 if [[ -n ${a_cpu_working[2]} ]];then
9247 if [[ $cpu_vendor != 'intel' ]];then
9248 cpu_cache=$( calculate_multicore_data "${a_cpu_working[2]}" "$(( $cpu_core_count * $cpu_physical_count ))" )
9250 cpu_cache=$( calculate_multicore_data "${a_cpu_working[2]}" "$cpu_physical_count" )
9255 # only print shortened list
9256 if [[ $B_CPU_FLAGS_FULL != 'true' ]];then
9257 # gawk has already sorted this output, no flags returns -
9258 if [[ $B_EXTRA_DATA == 'true' ]];then
9259 cpu_flags=$( process_cpu_flags "${a_cpu_working[3]}" "${a_cpu_working[6]}" )
9260 cpu_flags="($cpu_flags)"
9261 if [[ ${a_cpu_working[6]} == 'true' ]];then
9262 flag_feature='features'
9265 cpu_flags="${C1}$flag_feature$SEP3${C2} $cpu_flags "
9268 # arm cpus do not have flags or cache
9269 if [[ ${a_cpu_working[6]} != 'true' ]];then
9270 cpu_data="$cpu_data${C2} ${C1}cache$SEP3${C2} $cpu_cache${CN}"
9271 cpu_2_data="$cpu_flags$bmip_data${CN}"
9273 cpu_data="$cpu_data${C2} (ARM)$bmip_data${CN}"
9276 # we don't this printing out extra line unless > 1 cpu core
9277 if [[ ${#A_CPU_DATA[@]} -gt 2 && $B_SHOW_CPU == 'true' ]];then
9278 cpu_clock_speed='' # null < verbosity level 5
9280 cpu_data="$cpu_data ${C1}clocked at${C2} ${a_cpu_working[1]%.*} MHz${CN}"
9282 cpu_2_data="$cpu_2_data$cpu_clock_speed"
9284 if [[ $BSD_TYPE == 'bsd' && $B_ROOT != 'true' ]];then
9285 cpu_null_error=' No permissions for sysctl use?'
9287 cpu_data="${C2}No CPU data available.$cpu_null_error"
9289 # echo $cpu_data $cpu_2_data
9290 # echo ln: $( calculate_line_length "$cpu_data $cpu_2_data" )
9291 # echo cpl: $( create_print_line "$line_starter" "${cpu_2_data}" ):
9292 # echo icols: $COLS_INNER
9293 # echo tc: $TERM_COLUMNS
9294 # echo :${cpu_2_data}:
9295 if [[ -n $cpu_2_data && $( calculate_line_length "$cpu_data $cpu_2_data" ) -gt $COLS_INNER ]];then
9296 cpu_data=$( create_print_line "$line_starter" "${cpu_data}" )
9298 print_screen_output "$cpu_data"
9299 cpu_data=$( create_print_line " " "${cpu_2_data}" )
9300 print_screen_output "$cpu_data"
9302 cpu_data=$( create_print_line "$line_starter" "${cpu_data}" )
9303 print_screen_output "$cpu_data ${cpu_2_data}"
9305 # we don't this printing out extra line unless > 1 cpu core
9306 # note the numbering, the last array item is the min/max/not found for cpu speeds
9307 if [[ ${#A_CPU_DATA[@]} -gt 2 && $B_SHOW_CPU == 'true' ]];then
9308 for (( i=0; i < ${#A_CPU_DATA[@]}-1; i++ ))
9311 a_cpu_working=(${A_CPU_DATA[i]})
9313 # note: the first iteration will create a first space, for color code separation below
9314 cpu_multi_clock_data="$cpu_multi_clock_data ${C1}$(( i + 1 )):${C2} ${a_cpu_working[1]%.*} MHz${CN}"
9315 # someone actually appeared with a 16 core system, so going to stop the cpu core throttle
9316 # if this had some other purpose which we can't remember we'll add it back in
9317 #if [[ $i -gt 10 ]];then
9321 if [[ -n $cpu_multi_clock_data ]];then
9322 cpu_multi_clock_data=$( create_print_line " " "${C1}Clock Speeds:${C2}$cpu_multi_clock_data" )
9323 print_screen_output "$cpu_multi_clock_data"
9326 if [[ $B_CPU_FLAGS_FULL == 'true' ]];then
9327 print_cpu_flags_full "${a_cpu_working[3]}" "${a_cpu_working[6]}"
9332 # takes list of all flags, split them and prints x per line
9333 # args: $1 - cpu flag string; $2 - arm true/false
9334 print_cpu_flags_full()
9337 # note: sort only sorts lines, not words in a string, so convert to lines
9338 local cpu_flags_full="$( echo $1 | tr " " "\n" | sort )"
9339 local a_cpu_flags='' line_starter='' temp_string=''
9340 local i=0 counter=0 starter_length=15 flag='' flag_data=''
9341 local line_length='' flag_feature='Flags' spacer='' flag_string=''
9343 if [[ $2 == 'true' ]];then
9344 flag_feature='Features'
9346 line_starter="CPU $flag_feature$SEP3"
9347 starter_length=$(( ${#line_starter} + 1 ))
9348 line_starter="${C1}$line_starter${C2} "
9349 line_length=$(( $COLS_INNER - $starter_length ))
9350 # build the flag line array
9351 for flag in $cpu_flags_full
9353 temp_string="$flag_string$spacer$flag"
9355 # handle inner line starter
9356 if [[ $counter -gt 0 ]];then
9357 line_length=$COLS_INNER
9359 if [[ $line_length -ge ${#temp_string} ]];then
9360 flag_string=$temp_string
9362 a_cpu_flags[$counter]=$flag_string
9368 if [[ -n $flag_string ]];then
9369 a_cpu_flags[$counter]=$flag_string
9372 for (( i=0; i < ${#a_cpu_flags[@]};i++ ))
9374 if [[ $i -gt 0 ]];then
9377 flag_data=$( create_print_line " " "$line_starter${a_cpu_flags[$i]}" )
9378 print_screen_output "$flag_data"
9383 print_graphics_data()
9386 local graphics_data='' card_id='' i='' root_alert='' root_x_string='' a_graphics_working=''
9387 local b_is_mesa='false' display_full_string='' card_bus_id='' card_data=''
9388 local res_tty='Resolution' xorg_data='' display_vendor_string='' chip_id=''
9389 local spacer='' driver='' driver_string='' driver_plural='' direct_render_string=''
9390 local separator_loaded='' separator_unloaded='' separator_failed=''
9391 local loaded='' unloaded='' failed='' display_server_string=''
9392 local line_starter='Graphics:'
9393 local screen_resolution="$( get_graphics_res_data )"
9395 # set A_DISPLAY_SERVER_DATA
9396 get_graphics_display_server_data
9397 local display_vendor=${A_DISPLAY_SERVER_DATA[0]}
9398 local display_version=${A_DISPLAY_SERVER_DATA[1]}
9400 get_graphics_glx_data
9401 local glx_renderer="${A_GLX_DATA[0]}"
9402 local glx_version="${A_GLX_DATA[1]}"
9403 # this can contain a long No case debugging message, so it's being sliced off
9404 # note: using grep -ioE '(No|Yes)' <<< ${A_GLX_DATA[2]} did not work in Arch, no idea why
9405 local glx_direct_render=$( gawk '{print $1}' <<< "${A_GLX_DATA[2]}" )
9407 # set A_GRAPHICS_CARD_DATA
9408 if [[ $BSD_TYPE == 'bsd' ]];then
9409 if [[ $B_PCICONF_SET == 'false' ]];then
9412 get_pciconf_card_data 'display'
9414 get_graphics_card_data
9416 # set A_GRAPHIC_DRIVERS
9419 if [[ ${#A_GRAPHIC_DRIVERS[@]} -eq 0 ]];then
9422 for (( i=0; i < ${#A_GRAPHIC_DRIVERS[@]}; i++ ))
9425 a_graphics_working=( ${A_GRAPHIC_DRIVERS[i]} )
9427 case ${a_graphics_working[1]} in
9429 loaded="$loaded$separator_loaded${a_graphics_working[0]}"
9430 separator_loaded=','
9433 unloaded="$unloaded$separator_unloaded${a_graphics_working[0]}"
9434 separator_unloaded=','
9437 failed="$failed$separator_failed${a_graphics_working[0]}"
9438 separator_failed=','
9443 if [[ -n $loaded ]];then
9444 driver="${driver} $loaded"
9446 if [[ -n $unloaded ]];then
9447 driver="${driver} (unloaded: $unloaded)"
9449 if [[ -n $failed ]];then
9450 driver="${driver} ${RED}FAILED:${C2} $failed"
9452 # sometimes for some reason there is no driver found but the array is started
9453 if [[ -z $driver ]];then
9457 if [[ ${#A_GRAPHIC_DRIVERS[@]} -gt 1 ]];then
9460 driver_string="${C1}driver$driver_plural$SEP3${C2}$driver "
9462 # some basic error handling:
9463 if [[ -z $screen_resolution ]];then
9464 screen_resolution='N/A'
9466 if [[ -z $display_vendor || -z $display_version ]];then
9467 display_vendor_string="N/A"
9469 display_vendor_string="$display_vendor $display_version"
9471 display_server_string="${C1}Display Server${SEP3}${C2} $display_vendor_string "
9473 if [[ $B_ROOT == 'true' ]];then
9474 root_x_string='for root '
9475 if [[ $B_RUNNING_IN_SHELL == 'true' || $B_CONSOLE_IRC == 'true' ]];then
9479 if [[ $B_RUNNING_IN_DISPLAY != 'true' ]];then
9480 root_x_string="${root_x_string}out of X"
9484 if [[ -n $root_x_string ]];then
9485 root_x_string="${C1}Advanced Data:${C2} N/A $root_x_string"
9488 display_full_string="$display_server_string$driver_string${C1}${res_tty}$SEP3${C2} ${screen_resolution} $root_x_string"
9490 if [[ ${#A_GRAPHICS_CARD_DATA[@]} -gt 0 ]];then
9491 for (( i=0; i < ${#A_GRAPHICS_CARD_DATA[@]}; i++ ))
9494 a_graphics_working=( ${A_GRAPHICS_CARD_DATA[i]} )
9497 card_data=${a_graphics_working[0]}
9498 if [[ $B_EXTRA_DATA == 'true' ]];then
9499 if [[ -n ${a_graphics_working[1]} ]];then
9500 card_bus_id=" ${C1}bus-ID$SEP3${C2} ${a_graphics_working[1]}"
9501 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
9502 if [[ $BSD_TYPE != 'bsd' ]];then
9503 chip_id=$( get_lspci_chip_id "${a_graphics_working[1]}" )
9505 chip_id=${a_graphics_working[2]}
9509 card_bus_id=" ${C1}bus-ID$SEP3${C2} N/A"
9512 if [[ -n $chip_id ]];then
9513 chip_id=" ${C1}chip-ID$SEP3${C2} $chip_id"
9515 if [[ ${#A_GRAPHICS_CARD_DATA[@]} -gt 1 ]];then
9516 card_id="Card-$(($i+1)):"
9520 graphics_data="${C1}$card_id${C2} $card_data$card_bus_id$chip_id "
9521 if [[ ${#A_GRAPHICS_CARD_DATA[@]} -gt 1 ]];then
9522 graphics_data=$( create_print_line "$line_starter" "${graphics_data}" )
9523 print_screen_output "$graphics_data"
9528 # handle cases where card detection fails, like in PS3, where lspci gives no output, or headless boxes..
9530 graphics_data="${C1}Card:${C2} Failed to Detect Video Card! "
9532 if [[ -n $graphics_data && $( calculate_line_length "${graphics_data}$display_full_string" ) -lt $COLS_INNER ]];then
9533 graphics_data=$( create_print_line "$line_starter" "${graphics_data}$display_full_string" )
9535 if [[ -n $graphics_data ]];then
9536 graphics_data=$( create_print_line "$line_starter" "$graphics_data" )
9537 print_screen_output "$graphics_data"
9540 graphics_data=$( create_print_line "$line_starter" "$display_full_string" )
9542 print_screen_output "$graphics_data"
9543 # if [[ -z $glx_renderer || -z $glx_version ]];then
9547 ## note: if glx render or display_version have no content, then mesa is true
9548 # if [[ $B_SHOW_DISPLAY_DATA == 'true' ]] && [[ $b_is_mesa != 'true' ]];then
9549 if [[ $B_SHOW_DISPLAY_DATA == 'true' && $B_ROOT != 'true' ]];then
9550 if [[ -z $glx_renderer ]];then
9553 if [[ -z $glx_version ]];then
9556 if [[ -z $glx_direct_render ]];then
9557 glx_direct_render='N/A'
9559 if [[ $B_HANDLE_CORRUPT_DATA == 'true' || $B_EXTRA_DATA == 'true' ]];then
9560 direct_render_string=" ${C1}Direct Rendering$SEP3${C2} ${glx_direct_render}${CN}"
9562 graphics_data="${C1}GLX Renderer$SEP3${C2} ${glx_renderer} ${C1}GLX Version$SEP3${C2} ${glx_version}${CN}$direct_render_string"
9563 graphics_data=$( create_print_line " " "$graphics_data" )
9565 print_screen_output "$graphics_data"
9570 print_hard_disk_data()
9573 local hdd_data='' hdd_data_2='' a_hdd_working='' hdd_temp_data='' hdd_string=''
9575 local dev_data='' size_data='' hdd_model='' usb_data='' hdd_name='' divisor=5
9576 local Line_Starter='Drives:' # inherited by print_optical_drives
9580 ## note: if hdd_model is declared prior to use, whatever string you want inserted will
9581 ## be inserted first. In this case, it's desirable to print out (x) before each disk found.
9582 local a_hdd_data_count=$(( ${#A_HDD_DATA[@]} - 1 ))
9584 local a_hdd_basic_working=( ${A_HDD_DATA[$a_hdd_data_count]} )
9586 local hdd_capacity="${a_hdd_basic_working[0]}"
9587 local hdd_used=${a_hdd_basic_working[1]}
9588 local bsd_unsupported='Hard drive data not yet supported for BSD systems.'
9589 local hdd_name_temp=''
9591 if [[ $B_SHOW_BASIC_DISK == 'true' || $B_SHOW_DISK == 'true' ]];then
9592 ## note: the output part of this should be in the print hdd data function, not here
9593 get_hard_drive_data_advanced
9594 for (( i=0; i < ${#A_HDD_DATA[@]} - 1; i++ ))
9596 # this adds the (x) numbering in front of each disk found, and creates the full disk string
9598 a_hdd_working=( ${A_HDD_DATA[i]} )
9600 if [[ $B_SHOW_DISK == 'true' ]];then
9601 if [[ -n ${a_hdd_working[3]} ]];then
9602 usb_data="${a_hdd_working[3]} "
9606 dev_data="/dev/${a_hdd_working[0]} "
9607 size_data=" ${C1}size$SEP3${C2} ${a_hdd_working[1]}"
9608 if [[ $B_EXTRA_DATA == 'true' && -n $dev_data ]];then
9609 hdd_temp_data=$( get_hdd_temp_data "$dev_data" )
9610 # error handling is done in get data function
9611 if [[ -n $hdd_temp_data ]];then
9612 hdd_temp_data=" ${C1}temp$SEP3${C2} ${hdd_temp_data}C"
9617 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
9618 hdd_serial=$( get_hdd_serial_number "${a_hdd_working[0]}" )
9619 if [[ -z $hdd_serial ]];then
9622 hdd_serial=" ${C1}serial$SEP3${C2} $hdd_serial"
9623 divisor=1 # print every line
9625 divisor=2 # for modulus line print out, either 2 items for full, or default for short
9627 dev_data="${C1}id$SEP3${C2} /dev/${a_hdd_working[0]} "
9629 if [[ -n ${a_hdd_working[2]} ]];then
9630 hdd_name_temp=${a_hdd_working[2]}
9634 hdd_name="${C1}model$SEP3${C2} $hdd_name_temp"
9635 hdd_string="$usb_data$dev_data$hdd_name$size_data$hdd_serial$hdd_temp_data"
9636 hdd_model="${hdd_model}${C1}$(($i+1)):${C2} $hdd_string "
9637 # printing line one, then new lines according to $divisor setting, and after, if leftovers, print that line.
9640 if [[ $divisor -eq 1 ]];then
9641 hdd_data=$( create_print_line "$Line_Starter" "${C1}HDD Total Size:${C2} ${hdd_capacity} (${hdd_used})" )
9642 print_screen_output "$hdd_data"
9644 hdd_data=$( create_print_line "$Line_Starter" "${hdd_model}" )
9645 print_screen_output "$hdd_data"
9648 hdd_data=$( create_print_line "$Line_Starter" "${C1}HDD Total Size:${C2} ${hdd_capacity} (${hdd_used}) ${hdd_model}" )
9649 print_screen_output "$hdd_data"
9655 # using modulus here, if divisible by $divisor, print line, otherwise skip
9656 if [[ $(( $i % $divisor )) -eq 0 ]];then
9657 hdd_data=$( create_print_line "$Line_Starter" "${hdd_model}${CN}" )
9658 print_screen_output "$hdd_data"
9665 # then print any leftover items
9666 if [[ -n $hdd_model ]];then
9667 hdd_data=$( create_print_line "$Line_Starter" "${hdd_model}${CN}" )
9668 print_screen_output "$hdd_data"
9670 # temporary message to indicate not yet supported
9671 if [[ $BSD_TYPE == 'bsd' ]];then
9672 hdd_data=$bsd_unsupported
9673 hdd_data=$( create_print_line "$Line_Starter" "$hdd_data${CN}" )
9674 print_screen_output "$hdd_data"
9678 # temporary message to indicate not yet supported
9679 hdd_data="${C1}HDD Total Size:${C2} ${hdd_capacity} (${hdd_used})"
9680 if [[ $BSD_TYPE == 'bsd' ]];then
9681 hdd_data=$bsd_unsupported
9683 hdd_data=$( create_print_line "$Line_Starter" "$hdd_data${CN}" )
9684 print_screen_output "$hdd_data"
9687 if [[ $B_SHOW_FULL_OPTICAL == 'true' || $B_SHOW_BASIC_OPTICAL == 'true' ]];then
9688 print_optical_drive_data
9698 local info_data='' line_starter='Info:' runlvl_default='' runlvl='' runlvl_title='runlevel'
9699 local init_data='' init_type='' init_version='' rc_type='' rc_version=''
9700 local client_data='' shell_data='' shell_parent='' tty_session=''
9701 local memory="$( get_memory_data )"
9702 local processes=$(( $( wc -l <<< "$Ps_aux_Data" ) - 1 ))
9703 local up_time="$( get_uptime )"
9704 local patch_version_number=$( get_patch_version_string )
9705 local gcc_string='' gcc_installed='' gcc_others='' closing_data=''
9707 if [[ -z $memory ]];then
9711 if [[ $B_EXTRA_DATA == 'true' ]];then
9712 get_gcc_system_version
9713 if [[ ${#A_GCC_VERSIONS[@]} -gt 0 ]];then
9714 if [[ -n ${A_GCC_VERSIONS[0]} ]];then
9715 gcc_installed=${A_GCC_VERSIONS[0]}
9719 if [[ $B_EXTRA_EXTRA_DATA == 'true' && -n ${A_GCC_VERSIONS[1]} ]];then
9720 gcc_others=" ${C1}alt$SEP3${C2} $( tr ',' '/' <<< ${A_GCC_VERSIONS[1]} )"
9722 gcc_installed="${C1}Gcc sys$SEP3${C2} $gcc_installed$gcc_others "
9725 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
9726 shell_data=$( get_shell_data )
9727 if [[ -n $shell_data ]];then
9728 # note, if you start this in tty, it will give 'login' as the parent, which we don't want.
9729 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
9730 if [[ $B_RUNNING_IN_DISPLAY != 'true' ]];then
9731 shell_parent=$( get_tty_number )
9732 shell_parent="tty $shell_parent"
9734 shell_parent=$( get_shell_parent )
9736 if [[ $shell_parent == 'login' ]];then
9738 elif [[ -n $shell_parent ]];then
9739 shell_parent=" running in $shell_parent"
9742 IRC_CLIENT="$IRC_CLIENT ($shell_data$shell_parent)"
9746 # Some code could look superfluous but BitchX doesn't like lines not ending in a newline. F*&k that bitch!
9747 # long_last=$( echo -ne "${C1}Processes$SEP3${C2} ${processes}${CN} | ${C1}Uptime$SEP3${C2} ${up_time}${CN} | ${C1}Memory$SEP3${C2} ${MEM}${CN}" )
9748 info_data="${C1}Processes$SEP3${C2} ${processes} ${C1}Uptime$SEP3${C2} ${up_time} ${C1}Memory$SEP3${C2} ${memory}${CN} "
9750 # this only triggers if no X data is present or if extra data switch is on
9751 if [[ $B_SHOW_DISPLAY_DATA != 'true' || $B_EXTRA_DATA == 'true' ]];then
9753 if [[ ${A_INIT_DATA[0]} == 'systemd' && -z $( grep -E '^[0-9]$' <<< ${A_INIT_DATA[4]} ) ]];then
9754 runlvl_title='target'
9756 init_type=${A_INIT_DATA[0]}
9757 if [[ -z $init_type ]];then
9761 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
9762 init_version=${A_INIT_DATA[1]}
9763 if [[ -z $init_version ]];then
9766 init_version=" ${C1}v$SEP3${C2} $init_version"
9767 rc_version=${A_INIT_DATA[3]}
9768 if [[ -n $rc_version ]];then
9769 rc_version=" ${C1}v$SEP3${C2} $rc_version"
9772 runlvl_default=${A_INIT_DATA[5]}
9774 # currently only using openrc here, otherwise show nothing
9775 rc_type=${A_INIT_DATA[2]}
9776 if [[ -n $rc_type ]];then
9777 rc_type=" ${C1}rc$SEP3${C2} $rc_type$rc_version"
9779 init_type="${C1}Init$SEP3${C2} $init_type$init_version "
9781 runlvl=${A_INIT_DATA[4]}
9782 if [[ -n $runlvl ]];then
9783 runlvl="${C1}$runlvl_title$SEP3${C2} $runlvl "
9785 if [[ -n $runlvl_default ]];then
9786 runlvl_default="${C1}default$SEP3${C2} $runlvl_default "
9788 init_data="$init_type$rc_type$runlvl$runlvl_default"
9790 if [[ $SHOW_IRC -gt 0 ]];then
9791 client_data="${C1}Client$SEP3${C2} ${IRC_CLIENT}${IRC_CLIENT_VERSION} "
9793 info_data="${info_data}"
9794 closing_data="$client_data${C1}$SCRIPT_NAME$SEP3${C2} $SCRIPT_VERSION_NUMBER$patch_version_number${CN}"
9796 # sometimes gcc is very long, and default runlevel can be long with systemd, so create a gcc-less line first
9797 if [[ $( calculate_line_length "${info_data}${init_data}${gcc_installed}${closing_data}" ) -gt $COLS_INNER ]];then
9798 info_data=${info_data}${init_data}
9799 info_data=$( create_print_line "$line_starter" "$info_data" )
9800 print_screen_output "$info_data"
9807 if [[ $( calculate_line_length "${info_data}${init_data}${gcc_installed}${closing_data}" ) -gt $COLS_INNER ]];then
9808 info_data=${info_data}${init_data}${gcc_installed}
9809 info_data=$( create_print_line "$line_starter" "$info_data" )
9810 print_screen_output "$info_data"
9817 info_data="${info_data}${init_data}${gcc_installed}${closing_data}"
9819 info_data=$( create_print_line "$line_starter" "$info_data" )
9820 if [[ $SCHEME -gt 0 ]];then
9821 info_data="${info_data} ${NORMAL}"
9823 print_screen_output "$info_data"
9828 print_machine_data()
9832 local system_line='' mobo_line='' bios_line='' chassis_line=''
9833 local mobo_vendor='' mobo_model='' mobo_version='' mobo_serial=''
9834 local bios_vendor='' bios_version='' bios_date='' bios_rom=''
9835 local system_vendor='' product_name='' product_version='' product_serial='' product_uuid=''
9836 local chassis_vendor='' chassis_type='' chassis_version='' chassis_serial=''
9837 local b_skip_system='false' b_skip_chassis='false'
9838 local sysDmiError='No /sys/class/dmi, using '
9839 local sysDmiNull='No /sys/class/dmi machine data: try newer kernel, or install dmidecode'
9840 # set A_MACHINE_DATA
9843 if [[ -n $BSD_TYPE ]];then
9845 sysDmiNull='No machine data available. Is dmidecode installed?'
9849 ## keys for machine data are:
9850 # 0-sys_vendor 1-product_name 2-product_version 3-product_serial 4-product_uuid
9851 # 5-board_vendor 6-board_name 7-board_version 8-board_serial
9852 # 9-bios_vendor 10-bios_version 11-bios_date
9854 # 12-chassis_vendor 13-chassis_type 14-chassis_version 15-chassis_serial
9856 if [[ ${#A_MACHINE_DATA[@]} -gt 0 ]];then
9857 # note: in some case a mobo/version will match a product name/version, do not print those
9858 # but for laptops, or even falsely id'ed desktops with batteries, let's print it all if it matches
9859 # there can be false id laptops if battery appears so need to make sure system is filled
9860 if [[ -z ${A_MACHINE_DATA[0]} ]];then
9861 b_skip_system='true'
9863 if [[ $B_PORTABLE != 'true' ]];then
9864 # ibm / ibm can be true; dell / quantum is false, so in other words, only do this
9865 # in case where the vendor is the same and the version is the same and not null,
9866 # otherwise the version information is going to be different in all cases I think
9867 if [[ -n ${A_MACHINE_DATA[0]} && ${A_MACHINE_DATA[0]} == ${A_MACHINE_DATA[5]} ]];then
9868 if [[ -n ${A_MACHINE_DATA[2]} && ${A_MACHINE_DATA[2]} == ${A_MACHINE_DATA[7]} ]] || \
9869 [[ -z ${A_MACHINE_DATA[2]} && ${A_MACHINE_DATA[1]} == ${A_MACHINE_DATA[6]} ]];then
9870 b_skip_system='true'
9875 # no point in showing chassis if system isn't there, it's very unlikely that would be correct
9876 if [[ $B_EXTRA_EXTRA_DATA == 'true' && $b_skip_system != 'true' ]];then
9877 if [[ -n ${A_MACHINE_DATA[7]} && ${A_MACHINE_DATA[14]} == ${A_MACHINE_DATA[7]} ]];then
9878 b_skip_chassis='true'
9880 if [[ -n ${A_MACHINE_DATA[12]} && $b_skip_chassis != 'true' ]];then
9881 # no need to print the vendor string again if it's the same
9882 if [[ ${A_MACHINE_DATA[12]} != ${A_MACHINE_DATA[0]} ]];then
9883 chassis_vendor=" ${A_MACHINE_DATA[12]}"
9885 if [[ -n ${A_MACHINE_DATA[13]} ]];then
9886 chassis_type=" ${C1}type$SEP3${C2} ${A_MACHINE_DATA[13]}"
9888 if [[ -n ${A_MACHINE_DATA[14]} ]];then
9889 chassis_version=" ${C1}version$SEP3${C2} ${A_MACHINE_DATA[14]}"
9891 if [[ -n ${A_MACHINE_DATA[15]} && $B_OUTPUT_FILTER != 'true' ]];then
9892 chassis_serial=" ${C1}serial$SEP3${C2} ${A_MACHINE_DATA[15]}"
9894 if [[ -n "$chassis_vendor$chassis_type$chassis_version$chassis_serial" ]];then
9895 chassis_line="${C1}Chassis$SEP3${C2}$chassis_vendor$chassis_type$chassis_version$chassis_serial"
9899 if [[ -n ${A_MACHINE_DATA[5]} ]];then
9900 mobo_vendor=${A_MACHINE_DATA[5]}
9904 if [[ -n ${A_MACHINE_DATA[6]} ]];then
9905 mobo_model=${A_MACHINE_DATA[6]}
9909 if [[ -n ${A_MACHINE_DATA[7]} ]];then
9910 mobo_version=" ${C1}version$SEP3${C2} ${A_MACHINE_DATA[7]}"
9912 if [[ -n ${A_MACHINE_DATA[8]} && $B_OUTPUT_FILTER != 'true' ]];then
9913 mobo_serial=" ${C1}serial$SEP3${C2} ${A_MACHINE_DATA[8]}"
9915 if [[ -n ${A_MACHINE_DATA[9]} ]];then
9916 bios_vendor=${A_MACHINE_DATA[9]}
9920 if [[ -n ${A_MACHINE_DATA[10]} ]];then
9921 bios_version=${A_MACHINE_DATA[10]}
9922 if [[ -n ${A_MACHINE_DATA[16]} ]];then
9923 bios_version="$bios_version rv ${A_MACHINE_DATA[16]}"
9928 if [[ -n ${A_MACHINE_DATA[11]} ]];then
9929 bios_date=${A_MACHINE_DATA[11]}
9933 if [[ $B_EXTRA_EXTRA_DATA == 'true' && -n ${A_MACHINE_DATA[17]} ]];then
9934 bios_rom=" ${C1}rom size$SEP3${C2} ${A_MACHINE_DATA[17]}"
9936 mobo_line="${C1}Mobo$SEP3${C2} $mobo_vendor ${C1}model$SEP3${C2} $mobo_model$mobo_version$mobo_serial"
9937 bios_line="${C1}Bios$SEP3${C2} $bios_vendor ${C1}version$SEP3${C2} $bios_version ${C1}date$SEP3${C2} $bios_date$bios_rom"
9938 if [[ $( calculate_line_length "$mobo_line$bios_line" ) -lt $COLS_INNER ]];then
9939 mobo_line="$mobo_line $bios_line"
9942 if [[ $b_skip_system == 'true' ]];then
9943 system_line=$mobo_line
9946 # this has already been tested for above so we know it's not null
9947 system_vendor=${A_MACHINE_DATA[0]}
9948 if [[ $B_PORTABLE == 'true' ]];then
9949 system_vendor="$system_vendor (portable)"
9951 if [[ -n ${A_MACHINE_DATA[1]} ]];then
9952 product_name=${A_MACHINE_DATA[1]}
9956 if [[ -n ${A_MACHINE_DATA[2]} ]];then
9957 product_version=" ${C1}version$SEP3${C2} ${A_MACHINE_DATA[2]}"
9959 if [[ -n ${A_MACHINE_DATA[3]} && $B_OUTPUT_FILTER != 'true' ]];then
9960 product_serial=" ${C1}serial$SEP3${C2} ${A_MACHINE_DATA[3]} "
9962 system_line="${C1}System$SEP3${C2} $system_vendor ${C1}product$SEP3${C2} $product_name$product_version$product_serial"
9963 if [[ -n $chassis_line && $( calculate_line_length "$system_line$chassis_line" ) -lt $COLS_INNER ]];then
9964 system_line="$system_line $chassis_line"
9970 system_line="${C2}$sysDmiNull${CN}"
9972 # patch to dump all of above if dmidecode was data source and non root user
9973 if [[ ${A_MACHINE_DATA[0]} == 'dmidecode-non-root-user' || ${A_MACHINE_DATA[0]} == 'dmidecode-no-smbios-dmi-data' ]];then
9974 if [[ ${A_MACHINE_DATA[0]} == 'dmidecode-non-root-user' ]];then
9975 system_line="${C2}${sysDmiError}dmidecode: you must be root to run dmidecode${CN}"
9976 elif [[ ${A_MACHINE_DATA[0]} == 'dmidecode-no-smbios-dmi-data' ]];then
9977 system_line="${C2}${sysDmiError}dmidecode: no machine data available${CN}"
9983 system_line=$( create_print_line "Machine:" "$system_line" )
9984 print_screen_output "$system_line"
9985 if [[ -n $mobo_line ]];then
9986 mobo_line=$( create_print_line " " "$mobo_line" )
9987 print_screen_output "$mobo_line"
9989 if [[ -n $bios_line ]];then
9990 bios_line=$( create_print_line " " "$bios_line" )
9991 print_screen_output "$bios_line"
9993 if [[ -n $chassis_line ]];then
9994 chassis_line=$( create_print_line " " "$chassis_line" )
9995 print_screen_output "$chassis_line"
10001 # args: $1 - module name (could be > 1, so loop it ); $2 - audio (optional)
10002 print_module_version()
10005 local module_versions='' module='' version='' prefix='' modules=$1
10007 # note that sound driver data tends to have upper case, but modules are lower
10008 if [[ $2 == 'audio' ]];then
10009 if [[ -z $( grep -E '^snd' <<< $modules ) ]];then
10010 prefix='snd_' # sound modules start with snd_
10012 modules=$( tr '[A-Z]' '[a-z]' <<< $modules )
10013 modules=$( tr '-' '_' <<< $modules )
10014 # special intel processing, generally no version info though
10015 if [[ $modules == 'hda intel' ]];then
10016 modules='hda_intel'
10017 elif [[ $modules == 'intel ich' ]];then
10022 for module in $modules
10024 version=$( get_module_version_number "$prefix$module" )
10025 if [[ -n $version ]];then
10026 module_versions="$module_versions $version"
10030 if [[ -n $module_versions ]];then
10031 echo " ${C1}ver$SEP3${C2}$module_versions"
10036 print_networking_data()
10039 local i='' card_id='' network_data='' a_network_working='' port_data='' driver_data=''
10040 local card_string='' port_plural='' module_version='' pci_bus_id='' bus_usb_text=''
10041 local bus_usb_id='' line_starter='Network:' card_string='' card_data='' chip_id=''
10043 # set A_NETWORK_DATA
10044 if [[ $BSD_TYPE == 'bsd' ]];then
10045 if [[ $B_PCICONF_SET == 'false' ]];then
10048 get_pciconf_card_data 'network'
10050 get_networking_data
10053 # will never be null because null is handled in get_network_data, but in case we change
10054 # that leaving this test in place.
10055 if [[ -n ${A_NETWORK_DATA[@]} ]];then
10056 for (( i=0; i < ${#A_NETWORK_DATA[@]}; i++ ))
10059 a_network_working=( ${A_NETWORK_DATA[i]} )
10060 IFS="$ORIGINAL_IFS"
10074 if [[ ${#A_NETWORK_DATA[@]} -gt 1 ]];then
10075 chip_id="-$(( $i + 1 ))"
10077 if [[ -n ${a_network_working[1]} && $B_EXTRA_DATA == 'true' && $BSD_TYPE != 'bsd' ]];then
10078 module_version=$( print_module_version "${a_network_working[1]}" )
10080 if [[ -n ${a_network_working[1]} ]];then
10081 # note: linux drivers can have numbers, like tg3
10082 if [[ $BSD_TYPE == 'bsd' ]];then
10083 driver=$( sed 's/[0-9]*$//' <<< ${a_network_working[1]} )
10085 driver=${a_network_working[1]}
10087 driver_data="${C1}driver$SEP3${C2} ${driver}$module_version "
10089 if [[ -n ${a_network_working[2]} && $B_EXTRA_DATA == 'true' ]];then
10090 if [[ $( wc -w <<< ${a_network_working[2]} ) -gt 1 ]];then
10093 port_data="${C1}port$port_plural$SEP3${C2} ${a_network_working[2]} "
10095 if [[ -n ${a_network_working[4]} && $B_EXTRA_DATA == 'true' ]];then
10096 if [[ -z $( grep '^usb-' <<< ${a_network_working[4]} ) ]];then
10097 bus_usb_text='bus-ID'
10098 bus_usb_id=${a_network_working[4]}
10099 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
10100 if [[ $BSD_TYPE != 'bsd' ]];then
10101 chip_id=$( get_lspci_chip_id "${a_network_working[4]}" )
10103 chip_id=${a_network_working[10]}
10107 bus_usb_text='usb-ID'
10108 bus_usb_id=$( cut -d '-' -f '2-4' <<< ${a_network_working[4]} )
10109 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
10110 chip_id=${a_network_working[10]}
10113 pci_bus_id="${C1}$bus_usb_text$SEP3${C2} $bus_usb_id"
10114 if [[ -n $chip_id ]];then
10115 chip_id=" ${C1}chip-ID$SEP3${C2} $chip_id"
10118 card_string="${C1}Card$card_id:${C2} ${a_network_working[0]} "
10119 card_data="$driver_data$port_data$pci_bus_id$chip_id"
10120 if [[ $( calculate_line_length "$card_string$card_data" ) -gt $COLS_INNER ]];then
10121 network_data=$( create_print_line "$line_starter" "$card_string" )
10124 print_screen_output "$network_data"
10126 network_data=$( create_print_line "$line_starter" "$card_string$card_data" )
10128 print_screen_output "$network_data"
10129 if [[ $B_SHOW_ADVANCED_NETWORK == 'true' ]];then
10130 print_network_advanced_data
10134 network_data="${C1}Card:${C2} Failed to Detect Network Card! "
10135 network_data=$( create_print_line "$line_starter" "$network_data" )
10136 print_screen_output "$network_data"
10138 if [[ $B_SHOW_IP == 'true' ]];then
10139 print_networking_ip_data
10144 print_network_advanced_data()
10147 local network_data='' if_id='N/A' duplex='N/A' mac_id='N/A' speed='N/A' oper_state='N/A'
10148 local b_is_wifi='false' speed_string='' duplex_string=''
10150 # first check if it's a known wifi id'ed card, if so, no print of duplex/speed
10151 if [[ -n $( grep -Esi '(wireless|wifi|wi-fi|wlan|802\.11|centrino)' <<< ${a_network_working[0]} ) ]];then
10154 if [[ -n ${a_network_working[5]} ]];then
10155 if_id=${a_network_working[5]}
10157 if [[ -n ${a_network_working[6]} ]];then
10158 oper_state=${a_network_working[6]}
10160 # no print out for wifi since it doesn't have duplex/speed data availabe
10161 # note that some cards show 'unknown' for state, so only testing explicitly
10162 # for 'down' string in that to skip showing speed/duplex
10163 if [[ $b_is_wifi != 'true' && $oper_state != 'down' ]];then
10164 if [[ -n ${a_network_working[7]} ]];then
10165 # make sure the value is strictly numeric before appending Mbps
10166 if [[ -n $( grep -E '^[0-9\.,]+$' <<< "${a_network_working[7]}" ) ]];then
10167 speed="${a_network_working[7]} Mbps"
10169 speed=${a_network_working[7]}
10172 speed_string="${C1}speed$SEP3${C2} $speed "
10173 if [[ -n ${a_network_working[8]} ]];then
10174 duplex=${a_network_working[8]}
10176 duplex_string="${C1}duplex$SEP3${C2} $duplex "
10178 if [[ -n ${a_network_working[9]} ]];then
10179 if [[ $B_OUTPUT_FILTER == 'true' ]];then
10180 mac_id=$FILTER_STRING
10182 mac_id=${a_network_working[9]}
10185 network_data="${C1}IF:${C2} $if_id ${C1}state$SEP3${C2} $oper_state $speed_string$duplex_string${C1}mac$SEP3${C2} $mac_id"
10186 network_data=$( create_print_line " " "$network_data" )
10187 print_screen_output "$network_data"
10192 print_networking_ip_data()
10195 local ip=$( get_networking_wan_ip_data )
10196 local wan_ip_data='' a_interfaces_working='' interfaces='' i=''
10197 local if_id='' if_ip='' if_ipv6='' if_ipv6_string='' full_string='' if_string=''
10198 local if_id_string='' if_ip_string=''
10199 local line_max=$(( $COLS_INNER - 40 ))
10201 # set A_INTERFACES_DATA
10202 get_networking_local_ip_data
10203 # first print output for wan ip line. Null is handled in the get function
10204 if [[ -z $ip ]];then
10207 if [[ $B_OUTPUT_FILTER == 'true' ]];then
10211 wan_ip_data="${C1}WAN IP:${C2} $ip "
10212 # then create the list of local interface/ip
10213 i=0 ## loop starts with 1 by auto-increment so it only shows cards > 1
10214 while [[ -n ${A_INTERFACES_DATA[i]} ]]
10217 a_interfaces_working=(${A_INTERFACES_DATA[i]})
10218 IFS="$ORIGINAL_IFS"
10223 if [[ -z $( grep '^Interface' <<< ${a_interfaces_working[0]} ) ]];then
10224 if [[ -n ${a_interfaces_working[1]} ]];then
10225 if [[ $B_OUTPUT_FILTER == 'true' ]];then
10226 if_ip=$FILTER_STRING
10228 if_ip=${a_interfaces_working[1]}
10231 if_ip_string=" ${C1}ip$SEP3${C2} $if_ip"
10232 if [[ $B_EXTRA_DATA == 'true' ]];then
10233 if [[ -n ${a_interfaces_working[3]} ]];then
10234 if [[ $B_OUTPUT_FILTER == 'true' ]];then
10235 if_ipv6=$FILTER_STRING
10237 if_ipv6=${a_interfaces_working[3]}
10240 if_ipv6_string=" ${C1}ip-v6$SEP3${C2} $if_ipv6"
10243 if [[ -n ${a_interfaces_working[0]} ]];then
10244 if_id=${a_interfaces_working[0]}
10246 if_string="$wan_ip_data$if_string${C1}IF:${C2} $if_id$if_ip_string$if_ipv6_string "
10248 if [[ $( calculate_line_length "$if_string" ) -gt $line_max ]];then
10249 full_string=$( create_print_line " " "$if_string" )
10250 print_screen_output "$full_string"
10256 # then print out anything not printed already
10257 if [[ -n $if_string ]];then
10258 full_string=$( create_print_line " " "$if_string" )
10259 print_screen_output "$full_string"
10264 print_optical_drive_data()
10267 local a_drives='' drive_data='' counter=''
10268 local drive_id='' drive_links='' vendor='' speed='' multisession='' mcn='' audio=''
10269 local dvd='' state='' rw_support='' rev='' separator='' drive_string=''
10270 get_optical_drive_data
10271 # 0 - true dev path, ie, sr0, hdc
10272 # 1 - dev links to true path
10273 # 2 - device vendor - for hdx drives, vendor model are one string from proc
10275 # 4 - device rev version
10276 if [[ ${#A_OPTICAL_DRIVE_DATA[@]} -gt 0 ]];then
10277 for (( i=0; i < ${#A_OPTICAL_DRIVE_DATA[@]}; i++ ))
10280 a_drives=(${A_OPTICAL_DRIVE_DATA[i]})
10281 IFS="$ORIGINAL_IFS"
10295 if [[ ${#A_OPTICAL_DRIVE_DATA[@]} -eq 1 && -z ${a_drives[0]} && -z ${a_drives[1]} ]];then
10296 drive_string="No optical drives detected."
10297 B_SHOW_FULL_OPTICAL='false'
10299 if [[ ${#A_OPTICAL_DRIVE_DATA[@]} -gt 1 ]];then
10300 counter="-$(( i + 1 ))"
10302 if [[ -z ${a_drives[0]} ]];then
10305 drive_id="/dev/${a_drives[0]}"
10307 drive_links=$( sed 's/~/,/g' <<< ${a_drives[1]} )
10308 if [[ -z $drive_links ]];then
10311 if [[ -n ${a_drives[2]} ]];then
10312 vendor=${a_drives[2]}
10313 if [[ -n ${a_drives[3]} ]];then
10314 vendor="$vendor ${a_drives[3]}"
10317 if [[ -z $vendor ]];then
10318 if [[ -n ${a_drives[3]} ]];then
10319 vendor=${a_drives[3]}
10324 if [[ $B_EXTRA_DATA == 'true' ]];then
10325 if [[ -n ${a_drives[4]} ]];then
10330 rev=" ${C1}rev$SEP3${C2} $rev"
10332 drive_string="$drive_id ${C1}model$SEP3${C2} $vendor$rev ${C1}dev-links$SEP3${C2} $drive_links"
10334 drive_data="${C1}Optical${counter}:${C2} $drive_string"
10335 drive_data=$( create_print_line "$Line_Starter" "$drive_data" )
10336 print_screen_output "$drive_data"
10339 # 6 - multisession support
10348 if [[ $B_SHOW_FULL_OPTICAL == 'true' ]];then
10349 if [[ -z ${a_drives[5]} ]];then
10352 speed="${a_drives[5]}x"
10354 if [[ -z ${a_drives[8]} ]];then
10356 elif [[ ${a_drives[8]} == 1 ]];then
10361 audio=" ${C1}audio$SEP3${C2} $audio"
10362 if [[ -z ${a_drives[6]} ]];then
10364 elif [[ ${a_drives[6]} == 1 ]];then
10369 multisession=" ${C1}multisession$SEP3${C2} $multisession"
10370 if [[ -z ${a_drives[11]} ]];then
10372 elif [[ ${a_drives[11]} == 1 ]];then
10377 if [[ $B_EXTRA_DATA == 'true' ]];then
10378 if [[ -z ${a_drives[14]} ]];then
10381 state="${a_drives[14]}"
10383 state=" ${C1}state$SEP3${C2} $state"
10385 if [[ -n ${a_drives[9]} && ${a_drives[9]} == 1 ]];then
10389 if [[ -n ${a_drives[10]} && ${a_drives[10]} == 1 ]];then
10390 rw_support="${rw_support}${separator}cd-rw"
10393 if [[ -n ${a_drives[12]} && ${a_drives[12]} == 1 ]];then
10394 rw_support="${rw_support}${separator}dvd-r"
10397 if [[ -n ${a_drives[13]} && ${a_drives[13]} == 1 ]];then
10398 rw_support="${rw_support}${separator}dvd-ram"
10401 if [[ -z $rw_support ]];then
10405 drive_data="${C1}Features: speed$SEP3${C2} $speed$multisession$audio ${C1}dvd$SEP3${C2} $dvd ${C1}rw$SEP3${C2} $rw_support$state"
10406 drive_data=$( create_print_line "$Line_Starter" "$drive_data" )
10407 print_screen_output "$drive_data"
10416 print_partition_data()
10419 local a_partition_working='' partition_used='' partition_data=''
10420 local counter=0 i=0 a_partition_data='' line_starter='' line_max=$(( $COLS_INNER - 25 ))
10421 local partitionIdClean='' part_dev='' full_dev='' part_label='' full_label=''
10422 local part_uuid='' full_uuid='' dev_remote='' full_fs='' line_max_label_uuid=$COLS_INNER
10423 local b_non_dev='false' holder=''
10425 # set A_PARTITION_DATA
10428 for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
10431 a_partition_working=(${A_PARTITION_DATA[i]})
10432 IFS="$ORIGINAL_IFS"
10436 if [[ $B_SHOW_PARTITIONS_FULL == 'true' ]] || [[ ${a_partition_working[4]} == 'main' ]];then
10437 if [[ -n ${a_partition_working[2]} ]];then
10438 partition_used="${C1}used$SEP3${C2} ${a_partition_working[2]} (${a_partition_working[3]}) "
10440 partition_used='' # reset partition used to null
10442 if [[ -n ${a_partition_working[5]} ]];then
10443 full_fs="${a_partition_working[5]}"
10445 full_fs='N/A' # reset partition fs type
10447 full_fs="${C1}fs$SEP3${C2} $full_fs "
10449 if [[ $B_SHOW_LABELS == 'true' || $B_SHOW_UUIDS == 'true' ]];then
10450 if [[ -n ${a_partition_working[6]} ]];then
10451 if [[ -z $( grep -E '(^//|:/|non-dev)' <<< ${a_partition_working[6]} ) ]];then
10452 part_dev="/dev/${a_partition_working[6]}"
10454 elif [[ -n $( grep '^non-dev' <<< ${a_partition_working[6]} ) ]];then
10455 holder=$( sed 's/non-dev-//' <<< ${a_partition_working[6]} )
10459 part_dev="${a_partition_working[6]}"
10460 dev_remote='remote'
10466 full_dev="${C1}$dev_remote$SEP3${C2} $part_dev "
10467 if [[ $B_SHOW_LABELS == 'true' && $dev_remote != 'remote' ]];then
10468 if [[ -n ${a_partition_working[7]} ]];then
10469 part_label="${a_partition_working[7]}"
10473 full_label="${C1}label$SEP3${C2} $part_label "
10475 if [[ $B_SHOW_UUIDS == 'true' && $dev_remote != 'remote' ]];then
10476 if [[ -n ${a_partition_working[8]} ]];then
10477 part_uuid="${a_partition_working[8]}"
10481 full_uuid="${C1}uuid$SEP3${C2} $part_uuid"
10484 # don't show user names in output
10485 if [[ $B_OUTPUT_FILTER == 'true' ]];then
10486 partitionIdClean=$( sed $SED_RX "s|/home/([^/]+)/(.*)|/home/$FILTER_STRING/\2|" <<< ${a_partition_working[0]} )
10488 partitionIdClean=${a_partition_working[0]}
10490 id_size_fs="${C1}ID:${C2} $partitionIdClean ${C1}size$SEP3${C2} ${a_partition_working[1]} $partition_used$full_fs$full_dev"
10491 label_uuid="$full_label$full_uuid"
10492 # label/uuid always print one per line, so only wrap if it's very long
10493 if [[ $B_SHOW_UUIDS == 'true' && $B_SHOW_LABELS == 'true' && $( calculate_line_length "$id_size_fs$label_uuid" ) -gt $line_max_label_uuid ]];then
10494 a_partition_data[$counter]="$id_size_fs"
10496 a_partition_data[$counter]="$label_uuid"
10498 a_partition_data[$counter]="${a_partition_data[$counter]}$id_size_fs$label_uuid"
10500 # because these lines can vary widely, using dynamic length handling here
10501 if [[ $B_SHOW_LABELS == 'true' || $B_SHOW_UUIDS == 'true' ]] || [[ $( calculate_line_length "${a_partition_data[$counter]}" ) -gt $line_max ]];then
10506 # print out all lines, line starter on first line
10507 for (( i=0; i < ${#a_partition_data[@]};i++ ))
10509 if [[ $i -eq 0 ]];then
10510 line_starter='Partition:'
10514 partition_data=$( create_print_line "$line_starter" "${a_partition_data[$i]}" )
10515 print_screen_output "$partition_data"
10521 print_program_version()
10523 local patch_version_number=$( get_patch_version_string )
10524 local program_version="${C1}$SCRIPT_NAME$SEP3${C2} $SCRIPT_VERSION_NUMBER$patch_version_number${CN}"
10525 # great trick from: http://ideatrash.net/2011/01/bash-string-padding-with-sed.html
10526 # left pad: sed -e :a -e 's/^.\{1,80\}$/& /;ta'
10527 # right pad: sed -e :a -e 's/^.\{1,80\}$/ &/;ta'
10528 # center pad: sed -e :a -e 's/^.\{1,80\}$/ & /;ta'
10529 #local line_max=$COLS_INNER
10530 #program_version="$( sed -e :a -e "s/^.\{1,$line_max\}$/ &/;ta" <<< $program_version )" # use to create padding if needed
10531 # program_version=$( create_print_line "Version:" "$program_version" )
10532 print_screen_output "$program_version"
10539 local b_print_first='true'
10541 if [[ $B_SHOW_PS_CPU_DATA == 'true' ]];then
10542 get_ps_tcm_data 'cpu'
10543 print_ps_item 'cpu' "$b_print_first"
10544 b_print_first='false'
10546 if [[ $B_SHOW_PS_MEM_DATA == 'true' ]];then
10547 get_ps_tcm_data 'mem'
10548 print_ps_item 'mem' "$b_print_first"
10554 # args: $1 - cpu/mem; $2 true/false
10558 local a_ps_data='' ps_data='' line_starter='' line_start_data='' full_line=''
10559 local app_name='' app_pid='' app_cpu='' app_mem='' throttled='' app_daemon=''
10560 local b_print_first=$2 line_counter=0 i=0 count_nu='' extra_data=''
10562 if [[ -n $PS_THROTTLED ]];then
10563 throttled=" ${C1} - throttled from${C2} $PS_THROTTLED"
10567 line_start_data="${C1}CPU - % used - top ${C2} $PS_COUNT ${C1}active$throttled "
10570 line_start_data="${C1}Memory - MB / % used - top ${C2} $PS_COUNT ${C1}active$throttled"
10574 if [[ $b_print_first == 'true' ]];then
10575 line_starter='Processes:'
10580 # appName, appPath, appStarterName, appStarterPath, cpu, mem, pid, vsz, user
10581 ps_data=$( create_print_line "$line_starter" "$line_start_data" )
10582 print_screen_output "$ps_data"
10584 for (( i=0; i < ${#A_PS_DATA[@]}; i++ ))
10587 a_ps_data=(${A_PS_DATA[i]})
10588 IFS="$ORIGINAL_IFS"
10590 # handle the converted app names, with ~..~ means it didn't have a path
10591 if [[ -n $( grep -E '^~.*~$' <<< ${a_ps_data[0]} ) ]];then
10592 app_daemon='daemon'
10594 app_daemon='command'
10597 app_name=" ${C1}$app_daemon$SEP3${C2} ${a_ps_data[0]}"
10598 if [[ ${a_ps_data[0]} != ${a_ps_data[2]} ]];then
10599 app_name="$app_name ${C1}(started by$SEP3${C2} ${a_ps_data[2]}${C1})${C2}"
10601 app_pid=" ${C1}pid$SEP3${C2} ${a_ps_data[6]}"
10602 # ${C1}user:${C2} ${a_ps_data[8]}
10605 app_cpu=" ${C1}cpu$SEP3${C2} ${a_ps_data[4]}%"
10606 if [[ $B_EXTRA_DATA == 'true' ]];then
10607 extra_data=" ${C1}mem$SEP3${C2} ${a_ps_data[7]}MB (${a_ps_data[5]}%)${C2}"
10611 app_mem=" ${C1}mem$SEP3${C2} ${a_ps_data[7]}MB (${a_ps_data[5]}%)${C2}"
10612 if [[ $B_EXTRA_DATA == 'true' ]];then
10613 extra_data=" ${C1}cpu$SEP3${C2} ${a_ps_data[4]}%"
10617 (( line_counter++ ))
10618 count_nu="${C1}$line_counter:${C2}"
10619 full_line="$count_nu$app_cpu$app_mem$app_name$app_pid$extra_data"
10620 ps_data=$( create_print_line " " "$full_line" )
10621 print_screen_output "$ps_data"
10630 local device='' device_string='' device_state='' raid_level='' device_components=''
10631 local device_report='' u_data='' blocks='' super_blocks='' algorithm='' chunk_size=''
10632 local bitmap_values='' recovery_progress_bar='' recovery_percent='' recovered_sectors=''
10633 local finish_time='' recovery_speed='' raid_counter=0 device_counter=1 basic_counter=1
10634 local a_raid_working='' raid_data='' kernel_support='' read_ahead='' unused_devices=''
10635 local basic_raid='' basic_raid_separator='' basic_raid_plural='' inactive=''
10636 local component_separator='' device_id='' print_string='' loop_limit=0 array_count_unused=''
10637 local array_count='' raid_event='' b_print_lines='true'
10638 local no_raid_detected='' dev_string='/dev/'
10639 local empty_raid_data='' report_size='report' blocks_avail='blocks' chunk_raid_usage='chunk size'
10641 if [[ -n $BSD_TYPE ]];then
10642 no_raid_detected='No zfs software RAID detected - other types not yet supported.'
10643 empty_raid_data='No zfs RAID data available - other types not yet supported.'
10644 report_size='full size'
10645 blocks_avail='available size'
10646 chunk_raid_usage='raid allocated'
10648 no_raid_detected="No RAID data available - $FILE_MDSTAT is missing - is md_mod kernel module loaded?"
10649 empty_raid_data="No RAID devices detected - $FILE_MDSTAT and md_mod kernel raid module present"
10652 if [[ $BSD_TYPE == 'bsd' ]];then
10655 if [[ $B_RAID_SET != 'true' ]];then
10659 for (( i=0; i < ${#A_RAID_DATA[@]}; i++ ))
10662 a_raid_working=(${A_RAID_DATA[i]})
10663 IFS="$ORIGINAL_IFS"
10665 # reset on each iteration
10669 component_separator=''
10671 device_components=''
10680 recovery_percent=''
10681 recovery_progress_bar=''
10682 recovered_sectors=''
10688 if [[ -n $( grep '^md' <<< ${a_raid_working[0]} ) && -z $BSD_TYPE ]] || \
10689 [[ -n $BSD_TYPE && ${a_raid_working[0]} != '' ]];then
10690 if [[ $B_SHOW_BASIC_RAID == 'true' ]];then
10691 if [[ $basic_raid != '' ]];then
10692 basic_raid_plural='s'
10694 if [[ ${a_raid_working[1]} == 'inactive' ]];then
10695 inactive=" - ${a_raid_working[1]}"
10697 basic_raid="$basic_raid$basic_raid_separator${C1}$basic_counter${SEP3}${C2} $dev_string${a_raid_working[0]}$inactive"
10698 basic_raid_separator=' '
10699 (( basic_counter++ ))
10701 device_id="-$device_counter"
10702 device="$dev_string${a_raid_working[0]}"
10704 (( device_counter++ ))
10705 if [[ ${a_raid_working[1]} != '' ]];then
10706 device_state=" - ${a_raid_working[1]}"
10709 if [[ ${a_raid_working[2]} == '' ]];then
10712 raid_level=${a_raid_working[2]}
10714 # there's one case: md0 : inactive that has to be protected against
10715 if [[ ${a_raid_working[2]} == '' && ${a_raid_working[1]} == 'inactive' ]];then
10718 raid_level=" ${C1}raid${SEP3}${C2} $raid_level"
10720 if [[ ${a_raid_working[4]} != '' ]];then
10721 device_report="${a_raid_working[4]}"
10723 device_report="N/A"
10725 if [[ $B_EXTRA_DATA == 'true' ]];then
10726 if [[ ${a_raid_working[6]} != '' ]];then
10727 blocks=${a_raid_working[6]}
10731 blocks=" ${C1}$blocks_avail${SEP3}${C2} $blocks"
10733 if [[ ${a_raid_working[9]} != '' ]];then
10734 chunk_size=${a_raid_working[9]}
10738 chunk_size=" ${C1}$chunk_raid_usage${SEP3}${C2} $chunk_size"
10739 if [[ ${a_raid_working[10]} != '' ]];then
10740 bitmap_value='true'
10741 bitmap_value=" ${C1}bitmap${SEP3}${C2} $bitmap_value"
10744 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
10745 if [[ ${a_raid_working[5]} != '' ]];then
10746 u_data=" ${a_raid_working[5]}"
10748 if [[ ${a_raid_working[7]} != '' ]];then
10749 super_blocks=" ${C1}super blocks${SEP3}${C2} ${a_raid_working[7]}"
10751 if [[ ${a_raid_working[8]} != '' ]];then
10752 algorithm=" ${C1}algorithm${SEP3}${C2} ${a_raid_working[8]}"
10755 if [[ ${a_raid_working[3]} == '' ]];then
10756 if [[ ${a_raid_working[1]} != 'inactive' ]];then
10757 device_components='N/A'
10760 for component in ${a_raid_working[3]}
10762 if [[ $B_EXTRA_DATA != 'true' ]];then
10763 component=$( sed 's/\[[0-9]\+\]//' <<< $component )
10765 # NOTE: for bsd zfs, states are: ONLINE,DEGRADED,OFFLINE (at least)
10766 if [[ -n $( grep -E '(F|DEGRADED)' <<< $component ) ]];then
10767 component=$( sed -e 's/(F)//' -e 's/F//' -e 's/DEGRADED//' <<< $component )
10768 failed="$failed $component"
10770 elif [[ -n $( grep -E '(S|OFFLINE)' <<< $component ) ]];then
10771 component=$( sed -e 's/(S)//' -e 's/S//' -e 's/OFFLINE//' <<< $component )
10772 spare="$spare $component"
10775 device_components="$device_components$component_separator$component"
10776 component_separator=' '
10780 if [[ $failed != '' ]];then
10781 failed=" ${C1}FAILED${SEP3}${C2}$failed${C2}"
10783 if [[ $spare != '' ]];then
10784 spare=" ${C1}spare${SEP3}${C2}$spare${C2}"
10787 if [[ -n $device_components || -n $spare || -n $failed ]];then
10788 if [[ $B_EXTRA_DATA != 'true' && -z $BSD_TYPE ]];then
10789 if [[ $device_report != 'N/A' && -n $device_components ]];then
10790 device_components="$device_report - $device_components"
10793 if [[ $device_components == '' ]];then
10794 device_components='none'
10796 device_components="${C1}online${SEP3}${C2} $device_components"
10797 device_components=" ${C1}components${SEP3}${C2} $device_components$failed$spare"
10800 a_raid_data[$raid_counter]="${C1}Device$device_id${SEP3}${C2} $device$device_state$raid_level$device_components"
10802 if [[ $B_EXTRA_DATA == 'true' && ${a_raid_working[1]} != 'inactive' ]];then
10803 a_raid_data[$raid_counter]="${C1}Device$device_id${SEP3}${C2} $device$device_state$device_components"
10804 (( raid_counter++ ))
10805 print_string="${C1}Info${SEP3}${C2}$raid_level ${C1}$report_size${SEP3}${C2} $device_report$u_data"
10806 print_string="$print_string$blocks$chunk_size$bitmap_value$super_blocks$algorithm"
10807 a_raid_data[$raid_counter]="$print_string"
10809 a_raid_data[$raid_counter]="${C1}Device$device_id${SEP3}${C2} $device$device_state$raid_level$device_components"
10811 (( raid_counter++ ))
10813 # now let's do the recover line if required
10814 if [[ ${a_raid_working[12]} != '' ]];then
10815 recovery_percent=$( cut -d '~' -f 2 <<< ${a_raid_working[12]} )
10816 if [[ ${a_raid_working[14]} != '' ]];then
10817 finish_time=${a_raid_working[14]}
10821 finish_time=" ${C1}time remaining${SEP3}${C2} $finish_time"
10822 if [[ $B_EXTRA_DATA == 'true' ]];then
10823 if [[ ${a_raid_working[13]} != '' ]];then
10824 recovered_sectors=" ${C1}sectors${SEP3}${C2} ${a_raid_working[13]}"
10827 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
10828 if [[ ${a_raid_working[11]} != '' ]];then
10829 recovery_progress_bar=" ${a_raid_working[11]}"
10831 if [[ ${a_raid_working[15]} != '' ]];then
10832 recovery_speed=" ${C1}speed${SEP3}${C2} ${a_raid_working[15]}"
10836 a_raid_data[$raid_counter]="${C1}Recovering${SEP3}${C2} $recovery_percent$recovery_progress_bar$recovered_sectors$finish_time$recovery_speed"
10837 (( raid_counter++ ))
10840 elif [[ ${a_raid_working[0]} == 'KernelRaidSupport' ]];then
10841 if [[ ${a_raid_working[1]} == '' ]];then
10842 kernel_support='N/A'
10844 kernel_support=${a_raid_working[1]}
10846 kernel_support=" ${C1}supported${SEP3}${C2} $kernel_support"
10847 elif [[ ${a_raid_working[0]} == 'ReadAhead' ]];then
10848 if [[ ${a_raid_working[1]} != '' ]];then
10849 read_ahead=${a_raid_working[1]}
10850 read_ahead=" ${C1}read ahead${SEP3}${C2} $read_ahead"
10852 elif [[ ${a_raid_working[0]} == 'UnusedDevices' ]];then
10853 if [[ ${a_raid_working[1]} == '' ]];then
10854 unused_devices='N/A'
10856 unused_devices=${a_raid_working[1]}
10858 unused_devices="${C1}Unused Devices${SEP3}${C2} $unused_devices"
10859 elif [[ ${a_raid_working[0]} == 'raidEvent' ]];then
10860 if [[ ${a_raid_working[1]} != '' ]];then
10861 raid_event=${a_raid_working[1]}
10862 raid_event=" ${C1}Raid Event${SEP3}${C2} ${a_raid_working[1]}"
10867 if [[ $B_SHOW_BASIC_RAID == 'true' && $basic_raid != '' ]];then
10868 a_raid_data[0]="${C1}Device$basic_raid_plural${SEP3}${C2} $basic_raid"
10870 # note bsd temp test hack to make it run
10871 if [[ $B_MDSTAT_FILE != 'true' && -z $BSD_TYPE ]] || \
10872 [[ -n $BSD_TYPE && $B_BSD_RAID == 'false' ]];then
10873 if [[ $B_SHOW_RAID_R == 'true' ]];then
10874 a_raid_data[0]="$no_raid_detected"
10876 b_print_lines='false'
10879 if [[ ${a_raid_data[0]} == '' ]];then
10880 if [[ $B_SHOW_BASIC_RAID != 'true' ]];then
10881 a_raid_data[0]="$empty_raid_data"
10883 b_print_lines='false'
10886 # now let's add on the system line and the unused device line. Only print on -xx
10887 if [[ $kernel_support$read_ahead$raid_event != '' ]];then
10888 array_count=${#a_raid_data[@]}
10889 a_raid_data[array_count]="${C1}System${SEP3}${C2}$kernel_support$read_ahead$raid_event"
10892 if [[ $unused_devices != '' ]];then
10893 array_count_unused=${#a_raid_data[@]}
10894 a_raid_data[array_count_unused]="$unused_devices"
10899 # we don't want to print anything if it's -b and no data is present, just a waste of a line
10900 if [[ $b_print_lines == 'true' ]];then
10901 # print out all lines, line starter on first line
10902 for (( i=0; i < ${#a_raid_data[@]} - $loop_limit;i++ ))
10904 if [[ $i -eq 0 ]];then
10905 line_starter='RAID:'
10909 if [[ $B_EXTRA_EXTRA_DATA == 'true' && $array_count != '' ]];then
10910 if [[ $i == 0 ]];then
10911 raid_data=$( create_print_line "$line_starter" "${a_raid_data[array_count]}" )
10912 print_screen_output "$raid_data"
10916 raid_data=$( create_print_line "$line_starter" "${a_raid_data[i]}" )
10917 print_screen_output "$raid_data"
10918 if [[ $B_EXTRA_EXTRA_DATA == 'true' && $array_count_unused != '' ]];then
10919 if [[ $i == $(( array_count_unused - 2 )) ]];then
10920 raid_data=$( create_print_line "$line_starter" "${a_raid_data[array_count_unused]}" )
10921 print_screen_output "$raid_data"
10930 # currently only apt using distros support this feature, but over time we can add others
10934 local repo_count=0 repo_line='' file_name='' file_content='' file_name_holder=''
10935 local repo_full='' b_print_next_line='false' repo_type=''
10939 if [[ -n $REPO_DATA ]];then
10940 # loop through the variable's lines one by one, update counter each iteration
10941 while read repo_line
10944 repo_type=$( cut -d ':' -f 1 <<< $repo_line )
10945 file_name=$( cut -d ':' -f 2 <<< $repo_line )
10946 file_content=$( cut -d ':' -f 3-7 <<< $repo_line )
10947 # this will dump unwanted white space line starters. Some irc channels
10948 # use bots that show page title for urls, so need to break the url by adding
10950 if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
10951 file_content=$( echo $file_content | sed 's|://|: //|' )
10953 file_content=$( echo $file_content )
10955 # echo $file_name : $file_name_holder : $repo_type : $file_content
10956 # check file name, if different, update the holder for print out
10957 if [[ $file_name != $file_name_holder ]];then
10958 if [[ $repo_type == 'pisi repo' || $repo_type == 'urpmq repo' ]];then
10959 repo_full="${C1}$repo_type:${C2} $file_name"
10961 repo_full="${C1}Active $repo_type in file:${C2} $file_name"
10963 file_name_holder=$file_name
10964 b_print_next_line='true'
10966 repo_full=$file_content
10968 # first line print Repos:
10969 if [[ $repo_count -eq 1 ]];then
10970 repo_full=$( create_print_line "Repos:" "$repo_full" )
10972 repo_full=$( create_print_line " " "$repo_full" )
10974 print_screen_output "$repo_full"
10975 # this prints the content of the file as well as the file name
10976 if [[ $b_print_next_line == 'true' ]];then
10977 repo_full=$( create_print_line " " "$file_content" )
10978 print_screen_output "$repo_full"
10979 b_print_next_line='false'
10981 done <<< "$REPO_DATA"
10983 repo_full=$( create_print_line "Repos:" "${C1}Error:${C2} $SCRIPT_NAME does not support this feature for your distro yet." )
10984 print_screen_output "$repo_full"
10989 print_sensors_data()
10992 local mobo_temp='' cpu_temp='' psu_temp='' cpu_fan='' mobo_fan='' ps_fan='' sys_fans='' sys_fans2=''
10993 local temp_data='' fan_data='' fan_data2='' b_is_error='false' fan_count=0 gpu_temp=''
10994 local a_sensors_working=''
10995 local no_sensors_message='None detected - is lm-sensors installed and configured?'
10996 local Sensors_Data="$( get_sensors_output )"
10999 if [[ $BSD_TYPE == 'bsd' ]];then
11000 no_sensors_message='This feature is not yet supported for BSD systems.'
11004 a_sensors_working=( ${A_SENSORS_DATA[0]} )
11005 IFS="$ORIGINAL_IFS"
11006 # initial error cases, for missing app or unconfigured sensors. Note that array 0
11007 # always has at least 3 items, cpu/mobo/psu temp in it. If the count is 0, then
11008 # no sensors are installed/configured
11009 if [[ ${#a_sensors_working[@]} -eq 0 ]];then
11010 cpu_temp=$no_sensors_message
11013 for (( i=0; i < ${#A_SENSORS_DATA[@]}; i++ ))
11016 a_sensors_working=( ${A_SENSORS_DATA[i]} )
11017 IFS="$ORIGINAL_IFS"
11019 # first the temp data
11021 if [[ -n ${a_sensors_working[0]} ]];then
11022 cpu_temp=${a_sensors_working[0]}
11026 cpu_temp="${C1}System Temperatures: cpu$SEP3${C2} $cpu_temp "
11028 if [[ -n ${a_sensors_working[1]} ]];then
11029 mobo_temp=${a_sensors_working[1]}
11033 mobo_temp="${C1}mobo$SEP3${C2} $mobo_temp "
11035 if [[ -n ${a_sensors_working[2]} ]];then
11036 psu_temp="${C1}psu$SEP3${C2} ${a_sensors_working[2]} "
11038 gpu_temp=$( get_gpu_temp_data )
11039 # dump the unneeded screen data for single gpu systems
11040 if [[ $( wc -w <<< $gpu_temp ) -eq 1 && $B_EXTRA_DATA != 'true' ]];then
11041 gpu_temp=${gpu_temp#*:}
11043 if [[ -n $gpu_temp ]];then
11044 gpu_temp="${C1}gpu$SEP3${C2} ${gpu_temp} "
11047 # then the fan data from main fan array
11049 for (( j=0; j < ${#a_sensors_working[@]}; j++ ))
11053 # we need to make sure it's either cpu fan OR cpu fan and sys fan 1
11054 if [[ -n ${a_sensors_working[0]} ]];then
11055 cpu_fan="${a_sensors_working[0]}"
11056 elif [[ -z ${a_sensors_working[0]} && -n ${a_sensors_working[1]} ]];then
11057 cpu_fan="${a_sensors_working[1]}"
11061 cpu_fan="${C1}Fan Speeds (in rpm): cpu$SEP3${C2} $cpu_fan "
11065 if [[ -n ${a_sensors_working[1]} ]];then
11066 mobo_fan="${C1}mobo$SEP3${C2} ${a_sensors_working[1]} "
11071 if [[ -n ${a_sensors_working[2]} ]];then
11072 ps_fan="${C1}psu$SEP3${C2} ${a_sensors_working[2]} "
11077 if [[ -n ${a_sensors_working[$j]} ]];then
11078 fan_number=$(( $j - 2 )) # sys fans start on array key 5
11079 # wrap after fan 6 total
11080 if [[ $fan_count -lt 7 ]];then
11081 sys_fans="$sys_fans${C1}sys-$fan_number$SEP3${C2} ${a_sensors_working[$j]} "
11083 sys_fans2="$sys_fans2${C1}sys-$fan_number$SEP3${C2} ${a_sensors_working[$j]} "
11092 for (( j=0; j < ${#a_sensors_working[@]}; j++ ))
11096 if [[ -n ${a_sensors_working[$j]} ]];then
11097 fan_number=$(( $j + 1 )) # sys fans start on array key 5
11098 # wrap after fan 6 total
11099 if [[ $fan_count -lt 7 ]];then
11100 sys_fans="$sys_fans${C1}fan-$fan_number$SEP3${C2} ${a_sensors_working[$j]} "
11102 sys_fans2="$sys_fans2${C1}fan-$fan_number$SEP3${C2} ${a_sensors_working[$j]} "
11113 # turning off all output for case where no sensors detected or no sensors output
11114 # unless -s used explicitly. So for -F type output won't show unless valid or -! 1 used
11115 if [[ $b_is_error != 'true' || $B_SHOW_SENSORS == 'true' || $B_TESTING_1 == 'true' ]];then
11116 temp_data="$cpu_temp$mobo_temp$psu_temp$gpu_temp"
11117 temp_data=$( create_print_line "Sensors:" "$temp_data" )
11118 print_screen_output "$temp_data"
11119 # don't print second or subsequent lines if error data
11120 fan_data="$cpu_fan$mobo_fan$ps_fan$sys_fans"
11121 if [[ $b_is_error != 'true' && -n $fan_data ]];then
11122 fan_data=$( create_print_line " " "$fan_data" )
11123 print_screen_output "$fan_data"
11124 # and then second wrapped fan line if needed
11125 if [[ -n $sys_fans2 ]];then
11126 fan_data2=$( create_print_line " " "$sys_fans2" )
11127 print_screen_output "$fan_data2"
11134 print_system_data()
11137 local system_data='' bits='' desktop_environment='' dm_data='' de_extra_data=''
11138 local host_kernel_string='' de_distro_string='' host_string='' desktop_type='Desktop'
11139 local host_name=$HOSTNAME
11140 local current_kernel=$( get_kernel_version )
11141 local distro="$( get_distro_data )"
11142 local tty_session=''
11144 # I think these will work, maybe, if logged in as root and in X
11145 if [[ $B_RUNNING_IN_DISPLAY == 'true' ]];then
11146 desktop_environment=$( get_desktop_environment )
11147 if [[ -z $desktop_environment ]];then
11148 desktop_environment='N/A'
11151 if [[ $B_EXTRA_EXTRA_EXTRA_DATA == 'true' ]];then
11152 de_extra_data=$( get_desktop_extra_data )
11153 if [[ -n $de_extra_data ]];then
11154 de_extra_data=" ${C1}info$SEP3${C2} $de_extra_data"
11158 tty_session=$( get_tty_number )
11159 if [[ -z $tty_session && $B_CONSOLE_IRC == 'true' ]];then
11160 tty_session=$( get_tty_console_irc )
11162 if [[ -n $tty_session ]];then
11163 tty_session=" $tty_session"
11165 desktop_environment="tty$tty_session"
11166 desktop_type='Console'
11168 # having dm type can be useful if you are accessing remote system
11169 # or are out of X and don't remember which dm is running the system
11170 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
11171 dm_data=$( get_display_manager )
11172 # here we only want the dm info to show N/A if in X
11173 if [[ -z $dm_data && $B_RUNNING_IN_DISPLAY == 'true' ]];then
11176 # only print out of X if dm_data has info, then it's actually useful, but
11177 # for headless servers, no need to print dm stuff.
11178 if [[ -n $dm_data ]];then
11179 dm_data=" ${C1}dm$SEP3${C2} $dm_data"
11183 de_distro_string="${C1}$desktop_type$SEP3${C2} $desktop_environment$de_extra_data$dm_data ${C1}Distro$SEP3${C2} $distro"
11184 if [[ $B_EXTRA_DATA == 'true' ]];then
11185 gcc_string=$( get_gcc_kernel_version )
11186 if [[ -n $gcc_string ]];then
11187 gcc_string=", ${C1}gcc$SEP3${C2} $gcc_string"
11190 # check for 64 bit first
11191 if [[ -n $( uname -m | grep -E '(x86_64|amd64)' ) ]];then
11196 bits=" (${bits} bit${gcc_string})"
11197 if [[ $B_SHOW_HOST == 'true' ]];then
11198 if [[ -z $HOSTNAME ]];then
11199 if [[ -n $( type p hostname ) ]];then
11200 host_name=$( hostname )
11202 if [[ -z $host_name ]];then
11206 host_string="${C1}Host$SEP3${C2} $host_name "
11207 system_data=$( create_print_line "System:" "$host_string$host_name ${C1}Kernel$SEP3${C2}" )
11209 host_kernel_string="$host_string${C1}Kernel$SEP3${C2} $current_kernel$bits "
11210 if [[ $( calculate_line_length "$host_kernel_string$de_distro_string" ) -lt $COLS_INNER ]];then
11211 system_data="$host_kernel_string$de_distro_string"
11212 system_data=$( create_print_line "System:" "$system_data" )
11214 system_data=$( create_print_line "System:" "$host_kernel_string" )
11215 print_screen_output "$system_data"
11216 system_data=$( create_print_line " " "$de_distro_string" )
11218 print_screen_output "$system_data"
11222 print_unmounted_partition_data()
11225 local a_unmounted_data='' line_starter='' unmounted_data='' full_fs=''
11226 local full_dev='' full_size='' full_label='' full_uuid='' full_string=''
11227 local bsd_unsupported='This feature is not yet supported for BSD systems.'
11229 if [[ -z ${A_PARTITION_DATA} ]];then
11232 get_unmounted_partition_data
11234 if [[ ${#A_UNMOUNTED_PARTITION_DATA[@]} -ge 1 ]];then
11235 for (( i=0; i < ${#A_UNMOUNTED_PARTITION_DATA[@]}; i++ ))
11238 a_unmounted_data=(${A_UNMOUNTED_PARTITION_DATA[i]})
11239 IFS="$ORIGINAL_IFS"
11240 if [[ -z ${a_unmounted_data[0]} ]];then
11243 full_dev="/dev/${a_unmounted_data[0]}"
11245 full_dev="${C1}ID:${C2} $full_dev"
11246 if [[ -z ${a_unmounted_data[1]} ]];then
11249 full_size=${a_unmounted_data[1]}
11251 full_size="${C1}size$SEP3${C2} $full_size"
11252 if [[ -z ${a_unmounted_data[2]} ]];then
11255 full_label=${a_unmounted_data[2]}
11257 full_label="${C1}label$SEP3${C2} $full_label"
11258 if [[ -z ${a_unmounted_data[3]} ]];then
11261 full_uuid=${a_unmounted_data[3]}
11263 full_uuid="${C1}uuid$SEP3${C2} $full_uuid"
11264 if [[ -z ${a_unmounted_data[4]} ]];then
11267 full_fs="${C1}fs$SEP3${C2} ${a_unmounted_data[4]}"
11269 full_string="$full_dev $full_size $full_label $full_uuid $full_fs"
11270 if [[ $i -eq 0 ]];then
11271 line_starter='Unmounted:'
11275 # temporary message to indicate not yet supported
11276 if [[ $BSD_TYPE == 'bsd' ]];then
11277 full_string=$bsd_unsupported
11279 unmounted_data=$( create_print_line "$line_starter" "$full_string" )
11280 print_screen_output "$unmounted_data"
11283 unmounted_data=$( create_print_line "Unmounted:" "No unmounted partitions detected" )
11284 print_screen_output "$unmounted_data"
11290 print_weather_data()
11294 local weather_data='' location_string='' local_time='' time_string='' pressure=''
11295 local a_location='' a_weather='' weather_string='' weather='' temp='' winds='' humidity=''
11296 local time_zone='' observation_time='' city='' state='' country='' altitude=''
11297 local heat_index="" wind_chill='' dewpoint='' xxx_humidity=''
11298 local openP='(' closeP=')'
11300 if [[ $B_RUNNING_IN_SHELL == 'false' ]];then
11307 # city ";" regionCode ";" regionName ";" countryName ";" countryCode ";" countryCode3
11308 # ";" latitude "," longitude ";" postalCode ";" timeZone
11310 # observationTime ";" localTime ";" weather ";" tempString ";" humidity
11311 # ";" windString ";" pressureString ";" dewpointString ";" heatIndexString
11312 # ";" windChillString ";" siteElevation
11314 if [[ ${#A_WEATHER_DATA[@]} -eq 2 ]];then
11316 a_location=(${A_WEATHER_DATA[0]})
11317 a_weather=(${A_WEATHER_DATA[1]})
11318 IFS="$ORIGINAL_IFS"
11320 if [[ -n ${a_weather[3]} ]];then
11321 temp=${a_weather[3]}
11325 if [[ -n ${a_weather[2]} ]];then
11326 weather=" - ${a_weather[2]}"
11330 if [[ $B_EXTRA_DATA == 'true' ]];then
11331 if [[ -n ${a_weather[5]} ]];then
11332 winds=" ${C1}Wind$SEP3${C2} ${a_weather[5]}"
11335 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
11336 if [[ -n ${a_weather[4]} ]];then
11337 humidity=" ${C1}Humidity$SEP3${C2} ${a_weather[4]}"
11339 if [[ -n ${a_weather[6]} ]];then
11340 pressure="${C1}Pressure$SEP3${C2} ${a_weather[6]} "
11343 weather_string="${C1}Conditions$SEP3${C2} $temp$weather$winds$humidity"
11345 if [[ -n ${a_weather[1]} ]];then
11346 local_time=" ${a_weather[1]}"
11348 local_time=" $(date)"
11350 if [[ $B_EXTRA_DATA == 'true' && -n ${a_location[8]} ]];then
11351 time_zone=" (${a_location[8]})"
11353 time_string="${C1}Time$SEP3${C2}$local_time$time_zone"
11355 if [[ $B_EXTRA_DATA != 'true' ]];then
11356 weather_data="$weather_string $time_string"
11357 weather_data=$( create_print_line "Weather:" "$weather_data" )
11358 print_screen_output "$weather_data"
11360 weather_data="$weather_string"
11361 weather_data=$( create_print_line "Weather:" "$weather_data" )
11362 print_screen_output "$weather_data"
11363 if [[ $B_EXTRA_EXTRA_EXTRA_DATA == 'true' ]];then
11364 if [[ -n ${a_weather[8]} ]];then
11365 heat_index="${C1}Heat Index$SEP3${C2} ${a_weather[8]} "
11367 if [[ -n ${a_weather[9]} ]];then
11368 wind_chill="${C1}Wind Chill$SEP3${C2} ${a_weather[9]} "
11370 if [[ -n ${a_weather[7]} ]];then
11371 dew_point="${C1}Dew Point$SEP3${C2} ${a_weather[7]} "
11373 if [[ -n ${a_weather[0]} ]];then
11374 observation_time=" ${C1}Observation Time$SEP3${C2} ${a_weather[0]} "
11376 if [[ $B_OUTPUT_FILTER != 'true' ]];then
11377 if [[ -n ${a_location[0]} ]];then
11378 city=" ${a_location[0]}"
11380 if [[ -n ${a_location[1]} ]];then
11381 state=" ${a_location[1]}"
11383 if [[ -n ${a_location[5]} ]];then
11384 country=" $openP${a_location[5]}$closeP"
11386 if [[ -n ${a_weather[10]} ]];then
11387 altitude=" ${C1}Altitude$SEP3${C2} ${a_weather[10]}"
11389 location_string="${C1}Location$SEP3${C2}$city$state$country$altitude "
11391 location_string=$time_string$observation_time
11393 observation_time=''
11395 # the last three are oftenblank
11396 if [[ -z "$heat_index$wind_chill$dew_point" ]];then
11397 weather_data=$( create_print_line " " "$pressure$location_string" )
11398 print_screen_output "$weather_data"
11400 weather_data=$( create_print_line " " "$pressure$heat_index$wind_chill$dew_point" )
11401 print_screen_output "$weather_data"
11402 if [[ $B_OUTPUT_FILTER != 'true' ]];then
11403 weather_data=$( create_print_line " " "$location_string" )
11404 print_screen_output "$weather_data"
11407 if [[ -n $time_string$observation_time ]];then
11408 weather_data=$( create_print_line " " "$time_string$observation_time" )
11409 print_screen_output "$weather_data"
11412 if [[ -n $pressure$time_string ]];then
11413 weather_data="$pressure$time_string"
11414 weather_data=$( create_print_line " " "$weather_data" )
11415 print_screen_output "$weather_data"
11420 weather_data=$( create_print_line "Weather:" "Weather data failure: $(date)" )
11421 print_screen_output "$weather_data"
11422 weather_data=$( create_print_line " " "${A_WEATHER_DATA}" )
11423 print_screen_output "$weather_data"
11428 ########################################################################
11429 #### SCRIPT EXECUTION
11430 ########################################################################
11432 main $@ ## From the End comes the Beginning
11434 ## note: this EOF is needed for smxi handling, this is what triggers the full download ok