2 ########################################################################
5 #### Date: March 26 2012
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 script by locsmif
16 #### As time permits functionality improvements and recoding will occur.
18 #### inxi, the universal, portable, system info script 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-12 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: http://techpatterns.com/forums/about1131.html
29 #### Script svn: http://code.google.com/p/inxi
31 #### This program is free software; you can redistribute it and/or modify
32 #### it under the terms of the GNU General Public License as published by
33 #### the Free Software Foundation; either version 3 of the License, or
34 #### (at your option) any later version.
36 #### This program is distributed in the hope that it will be useful,
37 #### but WITHOUT ANY WARRANTY; without even the implied warranty of
38 #### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39 #### GNU General Public License for more details.
41 #### You should have received a copy of the GNU General Public License
42 #### along with this program. If not, see <http://www.gnu.org/licenses/>.
44 #### If you don't understand what Free Software is, please read (or reread)
45 #### this page: http://www.gnu.org/philosophy/free-sw.html
46 ########################################################################
47 #### * Package names in (...) are the Debian Squeeze package name. Check your
48 #### distro for proper package name by doing this: which <application>
49 #### then find what package owns that application file. Or run --recommends
50 #### which shows package names for Debian/Ubuntu, Arch, and Fedora/Redhat/Suse
53 #### * bash >=3.0 (bash); df, readlink, stty, tr, uname, wc (coreutils);
54 #### gawk (gawk); grep (grep); lspci (pciutils);
55 #### free, ps, uptime (procps); find (findutils)
56 #### * Also the proc filesystem should be present and mounted
57 #### * Some features, like -M and -d will not work, or will work incompletely,
58 #### if /sys is missing
60 #### Apparently unpatched bash 3.0 has arrays broken; bug reports:
61 #### http://ftp.gnu.org/gnu/bash/bash-3.0-patches/bash30-008
62 #### http://lists.gnu.org/archive/html/bug-bash/2004-08/msg00144.html
63 #### Bash 3.1 for proper array use
65 #### Arrays work in bash 2.05b, but "grep -Em" does not
67 #### RECOMMENDS (Needed to run certain features, listed by option)
68 #### -A - for output of usb audio information: lsusb (usbutils)
69 #### -Ax -Nx - for audio/network module version: modinfo (module-init-tools)
70 #### -Dx - for hdd temp output (root only default): hddtemp (hddtemp)
71 #### For user level hdd temp output: sudo (sudo)
72 #### Note: requires user action for this feature to run as user (edit /etc/sudoers file)
73 #### -G - full graphics output requires: glxinfo (mesa-utils); xdpyinfo (X11-utils);
74 #### xrandr (x11-xserver-utils)
75 #### -i - IP information, local/wan - ip (iproute) legacy, not used if ip present: ifconfig (net-tools)
76 #### -Ix - view current runlevel while not in X window system (or with -x): runlevel (sysvinit)
77 #### -M - for older systems whose kernel does not have /sys data for machine, dmidecode (dmidecode)
78 #### -o - for unmounted file system information in unmounted drives (root only default): file (file)
79 #### Note: requires user action for this feature to run as user (edit /etc/sudoers file)
80 #### For user level unmounted file system type output: sudo (sudo)
81 #### -s For any sensors output, fan, temp, etc: sensors (lm-sensors)
82 #### Note: requires setup of lm-sensors (sensors-detect and adding modules/modprobe/reboot,
83 #### and ideally, pwmconfig) prior to full output being available.
84 #### -S For desktop environment, user must be in X and have xprop installed (in X11-utils)
85 ########################################################################
87 #### * Character Encoding: UTF-8 - this file contains special characters that must be opened and saved as UTF8
88 #### * Indentation: TABS
89 #### * Do not use `....` (back quotes), those are totally non-reabable, use $(....).
90 #### * Do not use one liner flow controls.
91 #### The ONLY time you should use ';' (semi-colon) is in this single case: if [[ condition ]];then.
92 #### Never use compound 'if': ie, if [[ condition ]] && statement.
93 #### * Note: [[ -n $something ]] - double brackets does not require quotes for variables: ie, "$something".
94 #### * Always use quotes, double or single, for all string values.
95 #### * All new code/methods must be in a function.
96 #### * For all boolean tests, use 'true' / 'false'.
97 #### !! Do NOT use 0 or 1 unless it's a function return.
98 #### * Avoid complicated tests in the if condition itself.
99 #### * To 'return' a value in a function, use 'echo <var>'.
100 #### * For gawk: use always if ( num_of_cores > 1 ) { hanging { starter for all blocks
101 #### This lets us use one method for all gawk structures, including BEGIN/END, if, for, etc
103 #### VARIABLE/FUNCTION NAMING:
104 #### * All functions should follow standard naming--verb adjective noun.
105 #### ie, get_cpu_data
106 #### * All variables MUST be initialized / declared explicitly, either top of file, for Globals, or using local
107 #### * All variables should clearly explain what they are, except counters like i, j.
108 #### * Each word of Bash variable must be separated by '_' (underscore) (camel form), like: cpu_data
109 #### * Each word of Gawk variable must be like this (first word lower, following start with upper): cpuData
110 #### * Global variables are 'UPPER CASE', at top of script.
111 #### ie, SOME_VARIABLE=''
112 #### * Local variables are 'lower case' and declared at the top of the function using local, always.
113 #### ie: local some_variable=''
114 #### * Locals that will be inherited by child functions have first char capitalized (so you know they are inherited).
115 #### ie, Some_Variable
116 #### * Booleans should start with b_ (local) or B_ (global) and state clearly what is being tested.
117 #### * Arrays should start with a_ (local) or A_ (global).
120 #### * The color variable ${C2} must always be followed by a space unless you know what
121 #### character is going to be next for certain. Otherwise irc color codes can be accidentally
122 #### activated or altered.
123 #### * For native script konversation support (check distro for correct konvi scripts path):
124 #### ln -s <path to inxi> /usr/share/apps/konversation/scripts/inxi
125 #### DCOP doesn't like \n, so avoid using it for most output unless required, as in error messages.
126 #### * print_screen_output " " # requires space, not null, to avoid error in for example in irssi
127 #### * For logging of array data, array must be placed into the temp_array, otherwise only the first key logs
128 #### * In gawk search patterns, . is a wildcard EXCEPT in [0-9.] type containers, then it's a literal
129 #### So outside of bracketed items, it must be escaped, \. but inside, no need. Outside of gawk it should
130 #### be escaped in search patterns if you are using it as a literal.
132 #### As with all 'rules' there are acceptions, these are noted where used.
133 ###################################################################################
134 #### KDE Konversation information. Moving from dcop(qt3/KDE3) to dbus(qt4/KDE4)
135 ###################################################################################
136 #### * dcop and dbus -- these talk back to Konversation from this script
137 #### * Scripting info -- http://konversation.berlios.de/docs/scripting.html
138 #### -- http://www.kde.org.uk/apps/konversation/
139 #### * dbus info -- http://dbus.freedesktop.org/doc/dbus-tutorial.html
140 #### view dbus info -- https://fedorahosted.org/d-feet/
142 #### * Konvi dbus/usage-- qdbus org.kde.konversation /irc say <server> <target-channel> <output>
143 #### * Python usage -- http://wiki.python.org/moin/DbusExamples (just in case)
145 #### Because webpages come and go, the above information needs to be moved to inxi's wiki
146 ########################################################################
147 #### Valuable Resources
148 #### gawk arrays: http://www.math.utah.edu/docs/info/gawk_12.html
149 ########################################################################
151 #### inxi supports advanced testing triggers to do various things, using -! <arg>
152 #### -! 1 - triggers default B_TESTING_1='true' to trigger some test or other
153 #### -! 2 - triggers default B_TESTING_2='true' to trigger some test or other
154 #### -! 3 - triggers B_TESTING_1='true' and B_TESTING_2='true'
155 #### -! 10 - triggers an update from the primary dev download server instead of svn
156 #### -! 11 - triggers an update from svn branch one - if present, of course
157 #### -! 12 - triggers an update from svn branch two - if present, of course
158 #### -! 13 - triggers an update from svn branch three - if present, of course
159 #### -! 14 - triggers an update from svn branch four - if present, of course
160 #### -! <http://......> - Triggers an update from whatever server you list.
161 #### LOG FLAGS (logs to $HOME/.inxi/inxi.log with rotate 3 total)
162 #### -@ 8 - Basic data logging of generated data / array values
163 #### -@ 9 - Full logging of all data used, including cat of files and system data
164 #### -@ 10 - Basic data logging plus color code logging
165 ########################################################################
167 ########################################################################
169 ## NOTE: we can use hwinfo if it's available in all systems, or most, to get
170 ## a lot more data and verbosity levels going
171 # set to default LANG to avoid locales errors with , or .
173 ### Variable initializations: null values
176 # override in user config if desired, seems like less than .3 doesn't work as reliably
180 FILTER_STRING='<filter>'
182 IRC_CLIENT_VERSION=''
184 LINE_MAX_CONSOLE='115'
191 ### primary data array holders ## usage: 'A_<var>'
197 A_CPU_TYPE_PCNT_CCNT=''
207 A_OPTICAL_DRIVE_DATA=''
211 A_UNMOUNTED_PARTITION_DATA=''
214 ### Boolean true/false globals ## usage: 'B_<var>'
215 # flag to allow distro maintainers to turn off update features. If false, turns off
216 # -U and -! testing/advanced update options, as well as removing the -U help menu item
217 B_ALLOW_UPDATE='true'
218 B_COLOR_SCHEME_SET='false'
219 B_CONSOLE_IRC='false'
220 # triggers full display of cpu flags
221 B_CPU_FLAGS_FULL='false'
222 # test for dbus irc client
223 B_DBUS_CLIENT='false'
226 # Debug flood override: make 'true' to allow long debug output
227 B_DEBUG_FLOOD='false'
228 # show extra output data
231 B_EXTRA_EXTRA_DATA='false'
232 # override certain errors due to currupted data
233 B_HANDLE_CORRUPT_DATA='false'
236 B_LOG_FULL_DATA='false'
237 B_OUTPUT_FILTER='false'
238 B_OVERRIDE_FILTER='false'
243 B_RUN_COLOR_SELECTOR='false'
244 # Running in a shell? Defaults to false, and is determined later.
245 B_RUNNING_IN_SHELL='false'
246 if tty >/dev/null;then
247 B_RUNNING_IN_SHELL='true'
249 # this sets the debug buffer
251 B_SHOW_ADVANCED_NETWORK='false'
252 # Show sound card data
254 B_SHOW_BASIC_CPU='false'
255 B_SHOW_BASIC_DISK='false'
256 B_SHOW_BASIC_OPTICAL='false'
258 B_SHOW_DISK_TOTAL='false'
260 # Show full hard disk output
261 B_SHOW_FULL_HDD='false'
262 B_SHOW_FULL_OPTICAL='false'
263 B_SHOW_GRAPHICS='false'
264 # Set this to 'false' to avoid printing the hostname, this isn't used except for
265 # user configuration options via config files
269 B_SHOW_LABELS='false'
270 B_SHOW_MACHINE='false'
271 B_SHOW_NETWORK='false'
272 # either -v > 3 or -P will show partitions
273 B_SHOW_PARTITIONS='false'
274 B_SHOW_PARTITIONS_FULL='false'
275 B_SHOW_PS_CPU_DATA='false'
276 B_SHOW_PS_MEM_DATA='false'
278 B_RUNNING_IN_X='false'
279 B_SHOW_SENSORS='false'
280 # triggers only short inxi output
281 B_SHOW_SHORT_OUTPUT='false'
282 B_SHOW_SYSTEM='false'
283 B_SHOW_UNMOUNTED_PARTITIONS='false'
285 B_SHOW_X_DATA='false'
286 # triggers various debugging and new option testing
289 B_UPLOAD_DEBUG_DATA='false'
290 B_USB_NETWORKING='false'
291 # set to true here for debug logging from script start
292 B_USE_LOGGING='false'
296 ### Directory/file exist flags; test as [[ $(boolean) ]] not [[ $boolean ]]
297 B_ASOUND_DEVICE_FILE='false'
298 B_ASOUND_VERSION_FILE='false'
300 B_CPUINFO_FILE='false'
302 B_MEMINFO_FILE='false'
303 B_MODULES_FILE='false' #
304 B_MOUNTS_FILE='false'
305 B_PARTITIONS_FILE='false' #
309 ### File's used when present
310 FILE_ASOUND_DEVICE='/proc/asound/cards'
311 FILE_ASOUND_MODULES='/proc/asound/modules' # not used but maybe for -A?
312 FILE_ASOUND_VERSION='/proc/asound/version'
313 FILE_CPUINFO='/proc/cpuinfo'
314 FILE_LSB_RELEASE='/etc/lsb-release'
315 FILE_MEMINFO='/proc/meminfo'
316 FILE_MODULES='/proc/modules'
317 FILE_MOUNTS='/proc/mounts'
318 FILE_PARTITIONS='/proc/partitions'
319 FILE_SCSI='/proc/scsi/scsi'
320 FILE_XORG_LOG='/var/log/Xorg.0.log' # if not found, search and replace with actual location
322 ## app tested for and present, to avoid repeat tests
323 B_FILE_TESTED='false'
324 B_HDDTEMP_TESTED='false'
325 B_MODINFO_TESTED='false'
326 B_SUDO_TESTED='false'
332 ### Variable initializations: constants
334 DEBUG=0 # Set debug levels from 1-10 (8-10 trigger logging levels)
335 # Debug Buffer Index, index into a debug buffer storing debug messages until inxi is 'all up'
337 ## note: the debugger rerouting to /dev/null has been moved to the end of the get_parameters function
338 ## so -@[number] debug levels can be set if there is a failure, otherwise you can't even see the errors
340 # Defaults to 2, make this 1 for normal, 0 for no colorcodes at all. Use following variables in config
341 # files to change defaults for each type, or global
342 # Same as runtime parameter.
343 DEFAULT_COLOR_SCHEME=2
344 # Always leave these blank, these are only going to be set in inxi.conf files, that makes testing
345 # for user changes easier after sourcing the files
346 GLOBAL_COLOR_SCHEME=''
348 IRC_CONS_COLOR_SCHEME=''
349 IRC_X_TERM_COLOR_SCHEME=''
350 CONSOLE_COLOR_SCHEME=''
351 VIRT_TERM_COLOR_SCHEME=''
353 # Default indentation level
356 # logging eval variables, start and end function: Insert to LOGFS LOGFE when debug level >= 8
357 LOGFS_STRING='log_function_data fs $FUNCNAME "$( echo $@ )"'
358 LOGFE_STRING='log_function_data fe $FUNCNAME'
361 # uncomment for debugging from script start
362 # LOGFS=$LOGFS_STRING
363 # LOGFE=$LOGFE_STRING
365 # default to false, no konversation found, 1 is native konvi (qt3/KDE3) script mode, 2 is /cmd inxi start,
366 ## 3 is Konversation > 1.2 (qt4/KDE4)
368 # NO_CPU_COUNT=0 # Wether or not the string "dual" or similar is found in cpuinfo output. If so, avoid dups.
369 # This is a variable that controls how many parameters inxi will parse in a /proc/<pid>/cmdline file before stopping.
371 SCHEME=0 # set default scheme - do not change this, it's set dynamically
372 # this is set in user prefs file, to override dynamic temp1/temp2 determination of sensors output in case
373 # cpu runs colder than mobo
375 # SHOW_IRC=1 to avoid showing the irc client version number, or SHOW_IRC=0 to disable client information completely.
377 # Verbosity level defaults to 0, this can also be set with -v0, -v2, -v3, etc as a parameter.
379 # Supported number of verbosity levels, including 0
382 # Clear nullglob, because it creates unpredictable situations with IFS=$'\n' ARR=($VAR) IFS="$ORIGINAL_IFS"
383 # type constructs. Stuff like [rev a1] is now seen as a glob expansion pattern, and fails, and
384 # therefore results in nothing.
386 ## info on bash built in: $IFS - http://tldp.org/LDP/abs/html/internalvariables.html
387 # Backup the current Internal Field Separator
390 # These two determine separators in single line output, to force irc clients not to break off sections
393 # these will assign a separator to non irc states. Important! Using ':' can trigger stupid emoticon
394 # behaviors in output on IRC, so do not use those.
397 SEP3='' # do not set, will be set dynamically
399 ### Script names/paths - must be non root writable
400 SCRIPT_DATA_DIR="$HOME/.inxi"
401 ALTERNATE_FTP='' # for data uploads
402 LOG_FILE="$SCRIPT_DATA_DIR/inxi.log"
403 LOG_FILE_1="$SCRIPT_DATA_DIR/inxi.1.log"
404 LOG_FILE_2="$SCRIPT_DATA_DIR/inxi.2.log"
406 SCRIPT_PATCH_NUMBER=''
407 SCRIPT_PATH="" #filled-in in Main
408 SCRIPT_VERSION_NUMBER="" #filled-in in Main
409 SCRIPT_DOWNLOAD='http://inxi.googlecode.com/svn/trunk/'
410 SCRIPT_DOWNLOAD_BRANCH_1='http://inxi.googlecode.com/svn/branches/one/'
411 SCRIPT_DOWNLOAD_BRANCH_2='http://inxi.googlecode.com/svn/branches/two/'
412 SCRIPT_DOWNLOAD_BRANCH_3='http://inxi.googlecode.com/svn/branches/three/'
413 SCRIPT_DOWNLOAD_BRANCH_4='http://inxi.googlecode.com/svn/branches/four/'
414 SCRIPT_DOWNLOAD_DEV='http://smxi.org/test/'
415 KONVI_CFG="konversation/scripts/$SCRIPT_NAME.conf" # relative path to $(kde-config --path data)
417 ### Script Localization
418 # Make sure every program speaks English.
423 # A more elegant way to have a scheme that doesn't print color codes (neither ANSI nor mIRC) at all. See below.
425 # DGREY BLACK RED DRED GREEN DGREEN YELLOW DYELLOW
426 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"
427 IRC_COLORS=" \x0314 \x0301 \x0304 \x0305 \x0309 \x0303 \x0308 \x0307"
428 # BLUE DBLUE MAGENTA DMAGENTA CYAN DCYAN WHITE GREY NORMAL
429 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"
430 IRC_COLORS=" $IRC_COLORS \x0312 \x0302 \x0313 \x0306 \x0311 \x0310 \x0300 \x0315 \x03"
432 #ANSI_COLORS=($ANSI_COLORS); IRC_COLORS=($IRC_COLORS)
433 A_COLORS_AVAILABLE=( DGREY BLACK RED DRED GREEN DGREEN YELLOW DYELLOW BLUE DBLUE MAGENTA DMAGENTA CYAN DCYAN WHITE GREY NORMAL )
435 # See above for notes on EMPTY
436 ## note: group 1: 0, 1 are null/normal
437 ## Following: group 2: generic, light/dark or dark/light; group 3: dark on light; group 4 light on dark;
438 # this is the count of the first two groups, starting at zero
450 DYELLOW,NORMAL,NORMAL
453 MAGENTA,NORMAL,NORMAL
458 DBLUE,DMAGENTA,NORMAL
461 DGREEN,DYELLOW,NORMAL
463 DMAGENTA,BLACK,NORMAL
473 MAGENTA,YELLOW,NORMAL
479 ## Actual color variables
485 # In cases of derived distros where the version file of the base distro can also be found under /etc,
486 # the derived distro's version file should go first. (Such as with Sabayon / Gentoo)
487 DISTROS_DERIVED="antix-version aptosid-version kanotix-version knoppix-version mandrake-release pardus-release sabayon-release siduction-version sidux-version turbolinux-release zenwalk-version"
488 # debian_version excluded from DISTROS_PRIMARY so Debian can fall through to /etc/issue detection. Same goes for Ubuntu.
489 DISTROS_EXCLUDE_LIST="debian_version ubuntu_version"
490 DISTROS_PRIMARY="gentoo-release redhat-release slackware-version SuSE-release"
491 DISTROS_LSB_GOOD="mandrake-release mandriva-release mandrakelinux-release"
492 ## Distros with known problems
493 # DSL (Bash 2.05b: grep -m doesn't work; arrays won't work) --> unusable output
494 # Puppy Linux 4.1.2 (Bash 3.0: arrays won't work) --> works partially
497 # Note that \<ltd\> bans only words, not parts of strings; in \<corp\> you can't use punctuation characters like . or ,
498 # we're saving about 10+% of the total script exec time by hand building the ban lists here, using hard quotes.
499 BAN_LIST_NORMAL='computing|computer|corporation|communications|electronics|electrical|electric|gmbh|group|industrial|international|revision|software|technologies|technology|ltd\.|\<ltd\>|inc\.|\<inc\>|intl\.|co\.|\<co\>|corp\.|\<corp\>|\(tm\)|\(r\)|®|\(rev ..\)'
500 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]'
502 SENSORS_GPU_SEARCH='intel|radeon|nouveau'
504 ### USB networking search string data, because some brands can have other products than
505 ### wifi/nic cards, they need further identifiers, with wildcards.
506 ### putting the most common and likely first, then the less common, then some specifics
507 USB_NETWORK_SEARCH="Wi-Fi.*Adapter|Wireless.*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"
508 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"
509 # then a few known hard to ID ones added
510 # belkin=050d; d-link=07d1; netgear=0846; ralink=148f; realtek=0bda;
511 USB_NETWORK_SEARCH="$USB_NETWORK_SEARCH|050d:935b|0bda:8189|0bda:8197"
513 # WARNING: In the main part below (search for 'KONVI')
514 # there's a check for Konversation-specific config files.
515 # Any one of these can override the above if inxi is run
518 ########################################################################
519 #### MAIN: Where it all begins
520 ########################################################################
525 local color_scheme=''
527 # This function just initializes variables
528 initialize_script_data
530 # Check for dependencies BEFORE running ANYTHING else except above functions
531 # Not all distro's have these depends installed by default. Don't want to run
532 # this if the user is requesting to see this information in the first place
533 if [[ $1 != '--recommends' ]];then
535 check_script_suggested_apps
538 ### Only continue if depends ok
539 SCRIPT_PATH=$( dirname $0 )
540 SCRIPT_VERSION_NUMBER=$( grep -im 1 'version:' $SCRIPT_PATH/$SCRIPT_NAME | gawk '{print $3}' )
541 SCRIPT_PATCH_NUMBER=$( grep -im 1 'Patch Number:' $SCRIPT_PATH/$SCRIPT_NAME | gawk '{print $4}' )
543 ### Source global config overrides
544 if [[ -s /etc/$SCRIPT_NAME.conf ]];then
545 source /etc/$SCRIPT_NAME.conf
547 # Source user config variables override /etc/inxi.conf variables
548 if [[ -s $HOME/.$SCRIPT_NAME/$SCRIPT_NAME.conf ]];then
549 source $HOME/.$SCRIPT_NAME/$SCRIPT_NAME.conf
552 ## this needs to run before the KONVI stuff is set below
553 ## Konversation 1.2 apparently does not like the $PPID test in get_start_client
554 ## So far there is no known way to detect if qt4_konvi is the parent process
555 ## this method will infer qt4_konvi as parent
558 # note: this only works if it's run from inside konversation as a script builtin or something
559 # only do this if inxi has been started as a konversation script, otherwise bypass this
560 # KONVI=3 ## for testing puroses
561 if [[ $KONVI -eq 1 || $KONVI -eq 3 ]];then
562 if [[ $KONVI -eq 1 ]]; then ## dcop Konversation (ie 1.x < 1.2(qt3))
567 elif [[ $KONVI -eq 3 ]]; then ## dbus Konversation (> 1.2 (qt4))
568 DCSERVER="$1" ##dbus testing
569 DCTARGET="$2" ##dbus testing
573 # The section below is on request of Argonel from the Konversation developer team:
574 # it sources config files like $HOME/.kde/share/apps/konversation/scripts/inxi.conf
576 for kde_config in $( kde-config --path data )
578 if [[ -r ${kde_config}${KONVI_CFG} ]];then
579 source "${kde_config}${KONVI_CFG}"
586 ## leave this for debugging dcop stuff if we get that working
587 # print_screen_output "DCPORT: $DCPORT"
588 # print_screen_output "DCSERVER: $DCSERVER"
589 # print_screen_output "DCTARGET: $DCTARGET"
591 # first init function must be set first for colors etc. Remember, no debugger
592 # stuff works on this function unless you set the debugging flag manually.
593 # Debugging flag -@ [number] will not work until get_parameters runs.
595 # "$@" passes every parameter separately quoted, "$*" passes all parameters as one quoted parameter.
596 # must be here to allow debugger and other flags to be set.
599 # If no colorscheme was set in the parameter handling routine, then set the default scheme
600 if [[ $B_COLOR_SCHEME_SET != 'true' ]];then
601 # This let's user pick their color scheme. For IRC, only shows the color schemes, no interactive
602 # The override value only will be placed in user config files. /etc/inxi.conf can also override
603 if [[ $B_RUN_COLOR_SELECTOR == 'true' ]];then
604 select_default_color_scheme
606 # set the default, then override as required
607 color_scheme=$DEFAULT_COLOR_SCHEME
608 if [[ -n $GLOBAL_COLOR_SCHEME ]];then
609 color_scheme=$GLOBAL_COLOR_SCHEME
611 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
612 if [[ -n $CONSOLE_COLOR_SCHEME && -z $DISPLAY ]];then
613 color_scheme=$CONSOLE_COLOR_SCHEME
614 elif [[ -n $VIRT_TERM_COLOR_SCHEME ]];then
615 color_scheme=$VIRT_TERM_COLOR_SCHEME
618 if [[ -n $IRC_X_TERM_COLOR_SCHEME && $B_CONSOLE_IRC == 'true' && -n $DISPLAY ]];then
619 color_scheme=$IRC_X_TERM_COLOR_SCHEME
620 elif [[ -n $IRC_CONS_COLOR_SCHEME && -z $DISPLAY ]];then
621 color_scheme=$IRC_CONS_COLOR_SCHEME
622 elif [[ -n $IRC_COLOR_SCHEME ]];then
623 color_scheme=$IRC_COLOR_SCHEME
627 set_color_scheme $color_scheme
630 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
631 LINE_MAX=$LINE_MAX_CONSOLE
634 # too hard to read if no colors, so force that for users on irc
635 if [[ $SCHEME == 0 ]];then
640 LINE_MAX=$LINE_MAX_IRC
643 # all the pre-start stuff is in place now
645 script_debugger "Debugger: $SCRIPT_NAME is up and running..."
647 # then create the output
651 if [[ $B_RUNNING_IN_SHELL == 'true' && $SCHEME -gt 0 ]];then
655 # weechat's executor plugin forced me to do this, and rightfully so, because else the exit code
656 # from the last command is taken..
660 #### -------------------------------------------------------------------
661 #### basic tests: set script data, booleans, PATH
662 #### -------------------------------------------------------------------
664 # Set PATH data so we can access all programs as user. Set BAN lists.
665 # initialize some boleans, these directories are used throughout the script
666 # some apps are used for extended functions any directory used, should be
667 # checked here first.
669 initialize_script_data()
673 # now set the script BOOLEANS for files required to run features
674 if [[ -d "/proc/" ]];then
680 initialize_script_paths
682 # found a case of battery existing but having nothing in it on desktop mobo
683 # not all laptops show the first,
684 if [[ -n $( ls /proc/acpi/battery 2>/dev/null ) ]];then
687 if [[ -e $FILE_CPUINFO ]]; then
688 B_CPUINFO_FILE='true'
691 if [[ -e $FILE_MEMINFO ]];then
692 B_MEMINFO_FILE='true'
695 if [[ -e $FILE_ASOUND_DEVICE ]];then
696 B_ASOUND_DEVICE_FILE='true'
699 if [[ -e $FILE_ASOUND_VERSION ]];then
700 B_ASOUND_VERSION_FILE='true'
703 if [[ -f $FILE_LSB_RELEASE ]];then
707 if [[ -e $FILE_SCSI ]];then
711 if [[ -n $DISPLAY ]];then
713 B_RUNNING_IN_X='true'
716 if [[ -e $FILE_MODULES ]];then
717 B_MODULES_FILE='true'
720 if [[ -e $FILE_MOUNTS ]];then
724 if [[ -e $FILE_PARTITIONS ]];then
725 B_PARTITIONS_FILE='true'
727 # default to the normal location, then search for it
728 if [[ -e $FILE_XORG_LOG ]];then
731 # Detect location of the Xorg log file
732 if [[ -n $( type -p xset ) ]]; then
733 FILE_XORG_LOG=$( xset q 2>/dev/null | grep -i 'Log file' | gawk '{print $3}')
734 if [[ -e $FILE_XORG_LOG ]];then
739 # gfx output will require this flag
740 if [[ $( whoami ) == 'root' ]];then
746 initialize_script_paths()
748 local path='' added_path='' b_path_found='' sys_path=''
749 # Extra path variable to make execute failures less likely, merged below
750 local extra_paths="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin"
752 # Fallback paths put into $extra_paths; This might, among others, help on gentoo.
753 # Now, create a difference of $PATH and $extra_paths and add that to $PATH:
755 for path in $extra_paths
758 for sys_path in $PATH
760 if [[ $path == $sys_path ]];then
764 if [[ $b_path_found == 'false' ]];then
765 added_path="$added_path:$path"
770 PATH="${PATH}${added_path}"
771 ##echo "PATH='$PATH'"
772 ##/bin/sh -c 'echo "PATH in subshell=\"$PATH\""'
776 check_script_suggested_apps()
779 local bash_array_test=( "one" "two" )
781 # check for array ability of bash, this is only good for the warning at this time
782 # the boolean could be used later
783 # bash version 2.05b is used in DSL
784 # bash version 3.0 is used in Puppy Linux; it has a known array bug <reference to be placed here>
785 # versions older than 3.1 don't handle arrays
786 # distro's using below 2.05b are unknown, released in 2002
787 if [[ ${bash_array_test[1]} -eq "two" ]];then
790 script_debugger "Suggestion: update to Bash v3.1 for optimal inxi output"
792 # now setting qdbus/dcop for first run, some systems can have both by the way
793 if [[ -n $( type -p qdbus ) ]];then
796 if [[ -n $( type -p dcop ) ]];then
802 # Determine if any of the absolutely necessary tools are absent
804 check_script_depends()
807 local app_name='' app_path=''
808 # bc removed from deps for now
809 local depends="df free gawk grep lspci ps readlink tr uname uptime wc"
810 # no need to add xprop because it will just give N/A if not there, but if we expand use of xprop,
811 # should add that here as a test, then use the B_SHOW_X_DATA flag to trigger the tests in de function
812 local x_apps="xrandr xdpyinfo glxinfo"
814 if [[ $B_RUNNING_IN_X == 'true' ]];then
815 for app_name in $x_apps
817 app_path=$( type -p $app_name )
818 if [[ -z $app_path ]];then
819 script_debugger "Resuming in non X mode: $app_name not found. For package install advice run: $SCRIPT_NAME --recommends"
820 B_SHOW_X_DATA='false'
828 for app_name in $depends
830 app_path=$( type -p $app_name )
831 if [[ -z $app_path ]];then
832 error_handler 5 "$app_name"
838 ## note: this is now running inside each gawk sequence directly to avoid exiting gawk
839 ## looping in bash through arrays, then re-entering gawk to clean up, then writing back to array
840 ## in bash. For now I'll leave this here because there's still some interesting stuff to get re methods
841 # Enforce boilerplate and buzzword filters
842 # args: $1 - BAN_LIST_NORMAL/BAN_LIST_CPU; $2 - string to sanitize
843 sanitize_characters()
846 # Cannot use strong quotes to unquote a string with pipes in it!
847 # bash will interpret the |'s as usual and try to run a subshell!
848 # Using weak quotes instead, or use '"..."'
855 gsub(/ [ ]+/,\" \") ## ([ ]+) with (space)
856 gsub(/^ +| +$/,\"\") ## (pipe char) with (nothing)
857 print ## prints (returns) cleaned input
862 # Set the colorscheme
863 # args: $1 = <scheme number>|<"none">
867 local i='' a_script_colors='' a_color_codes=''
869 if [[ $1 -ge ${#A_COLOR_SCHEMES[@]} ]];then
872 # Set a global variable to allow checking for chosen scheme later
874 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
875 a_color_codes=( $ANSI_COLORS )
877 a_color_codes=( $IRC_COLORS )
879 for (( i=0; i < ${#A_COLORS_AVAILABLE[@]}; i++ ))
881 eval "${A_COLORS_AVAILABLE[i]}=\"${a_color_codes[i]}\""
884 a_script_colors=( ${A_COLOR_SCHEMES[$1]} )
886 # then assign the colors globally
887 C1="${!a_script_colors[0]}"
888 C2="${!a_script_colors[1]}"
889 CN="${!a_script_colors[2]}"
890 # ((COLOR_SCHEME++)) ## note: why is this? ##
894 select_default_color_scheme()
897 local spacer=' ' options='' user_selection='' config_variable=''
898 local config_file="$HOME/.$SCRIPT_NAME/$SCRIPT_NAME.conf"
899 local irc_clear="
\e[0m"
900 local irc_gui='Unset' irc_console='Unset' irc_x_term='Unset'
901 local console='Unset' virt_term='Unset' global='Unset'
903 if [[ -n $IRC_COLOR_SCHEME ]];then
904 irc_gui="Set: $IRC_COLOR_SCHEME"
906 if [[ -n $IRC_CONS_COLOR_SCHEME ]];then
907 irc_console="Set: $IRC_CONS_COLOR_SCHEME"
909 if [[ -n $IRC_X_TERM_COLOR_SCHEME ]];then
910 irc_x_term="Set: $IRC_X_TERM_COLOR_SCHEME"
912 if [[ -n $VIRT_TERM_COLOR_SCHEME ]];then
913 virt_term="Set: $VIRT_TERM_COLOR_SCHEME"
915 if [[ -n $CONSOLE_COLOR_SCHEME ]];then
916 console="Set: $CONSOLE_COLOR_SCHEME"
918 if [[ -n $GLOBAL_COLOR_SCHEME ]];then
919 global="Set: $GLOBAL_COLOR_SCHEME"
922 # don't want these printing in irc since they show literally
923 if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
926 # first make output neutral so it's just plain default for console client
928 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
929 print_screen_output "Welcome to $SCRIPT_NAME! Please select the default $COLOR_SELECTION color scheme."
930 # print_screen_output "You will see this message only one time per user account, unless you set preferences in: /etc/$SCRIPT_NAME.conf"
931 print_screen_output " "
933 print_screen_output "Because there is no way to know your $COLOR_SELECTION foreground/background colors, you can"
934 print_screen_output "set your color preferences from color scheme option list below. 0 is no colors, 1 neutral."
935 print_screen_output "After these, there are 3 sets: 1-dark or light backgrounds; 2-light backgrounds; 3-dark backgrounds."
936 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
937 print_screen_output "Please note that this will set the $COLOR_SELECTION preferences only for user: $(whoami)"
939 print_screen_output "------------------------------------------------------------------------------"
940 for (( i=0; i < ${#A_COLOR_SCHEMES[@]}; i++ ))
942 if [[ $i -gt 9 ]];then
945 # only offer the safe universal defaults
946 case $COLOR_SELECTION in
947 global|irc|irc-console|irc-virtual-terminal)
948 if [[ $i -gt $SAFE_COLOR_COUNT ]];then
954 print_screen_output "$irc_clear $i)$spacer${C1}Card:${C2} nVidia G86 [GeForce 8400 GS] ${C1}X.Org${C2} 1.7.7"
958 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
960 print_screen_output "$irc_clear $i)${spacer}Remove all color settings. Restore $SCRIPT_NAME default."
961 print_screen_output "$irc_clear $(($i+1)))${spacer}Continue, no changes or config file setting."
962 print_screen_output "$irc_clear $(($i+2)))${spacer}Exit, use another terminal, or set manually."
963 print_screen_output "------------------------------------------------------------------------------"
964 print_screen_output "Simply type the number for the color scheme that looks best to your eyes for your $COLOR_SELECTION settings"
965 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:"
966 print_screen_output "94 (console, no X - $console); 95 (terminal, X - $virt_term); 96 (irc, gui, X - $irc_gui);"
967 print_screen_output "97 (irc, X, in terminal - $irc_x_term); 98 (irc, no X - $irc_console); 99 (global - $global)"
968 print_screen_output "Your selection(s) will be stored here: $config_file"
969 print_screen_output "Global overrides all individual color schemes. Individual schemes remove the global setting."
970 print_screen_output "------------------------------------------------------------------------------"
972 if [[ -n $( grep -Es '^([0-9]+)$' <<< "$user_selection" ) && $user_selection -lt $i ]];then
973 case $COLOR_SELECTION in
975 config_variable='IRC_COLOR_SCHEME'
978 config_variable='IRC_CONS_COLOR_SCHEME'
980 irc-virtual-terminal)
981 config_variable='IRC_X_TERM_COLOR_SCHEME'
984 config_variable='CONSOLE_COLOR_SCHEME'
987 config_variable='VIRT_TERM_COLOR_SCHEME'
990 config_variable='GLOBAL_COLOR_SCHEME'
993 set_color_scheme $user_selection
994 # make file/directory first if missing
995 if [[ ! -f $config_file ]];then
996 if [[ ! -d $HOME/.$SCRIPT_NAME ]];then
997 mkdir $HOME/.$SCRIPT_NAME
1001 if [[ -z $( grep -s "$config_variable=" $config_file ) ]];then
1002 print_screen_output "Creating and updating config file for $COLOR_SELECTION color scheme now..."
1003 echo "$config_variable=$user_selection" >> $config_file
1005 print_screen_output "Updating config file for $COLOR_SELECTION color scheme now..."
1006 sed -i "s/$config_variable=.*/$config_variable=$user_selection/" $config_file
1008 # file exists now so we can go on to cleanup
1009 case $COLOR_SELECTION in
1010 irc|irc-console|irc-virtual-terminal|console|virtual-terminal)
1011 sed -i '/GLOBAL_COLOR_SCHEME=/d' $config_file
1014 sed -i -e '/VIRT_TERM_COLOR_SCHEME=/d' -e '/CONSOLE_COLOR_SCHEME=/d' -e '/IRC_COLOR_SCHEME=/d' \
1015 -e '/IRC_CONS_COLOR_SCHEME=/d' -e '/IRC_X_TERM_COLOR_SCHEME=/d' $config_file
1018 elif [[ $user_selection == $i ]];then
1019 print_screen_output "Removing all color settings from config file now..."
1020 sed -i -e '/VIRT_TERM_COLOR_SCHEME=/d' -e '/GLOBAL_COLOR_SCHEME=/d' -e '/CONSOLE_COLOR_SCHEME=/d' \
1021 -e '/IRC_COLOR_SCHEME=/d' -e '/IRC_CONS_COLOR_SCHEME=/d' -e '/IRC_X_TERM_COLOR_SCHEME=/d' $config_file
1022 set_color_scheme $DEFAULT_COLOR_SCHEME
1023 elif [[ $user_selection == $(( $i+1 )) ]];then
1024 print_screen_output "Ok, continuing $SCRIPT_NAME unchanged. You can set the colors anytime by starting with: -c 95 to 99"
1025 if [[ -n $CONSOLE_COLOR_SCHEME && -z $DISPLAY ]];then
1026 set_color_scheme $CONSOLE_COLOR_SCHEME
1027 elif [[ -n $VIRT_TERM_COLOR_SCHEME ]];then
1028 set_color_scheme $VIRT_TERM_COLOR_SCHEME
1030 set_color_scheme $DEFAULT_COLOR_SCHEME
1032 elif [[ $user_selection == $(( $i+2 )) ]];then
1033 set_color_scheme $DEFAULT_COLOR_SCHEME
1034 print_screen_output "Ok, exiting $SCRIPT_NAME now. You can set the colors later."
1037 print_screen_output "Error - Invalid Selection. You entered this: $user_selection"
1038 print_screen_output " "
1039 select_default_color_scheme
1042 print_screen_output "------------------------------------------------------------------------------"
1043 print_screen_output "After finding the scheme number you like, simply run this again in a terminal to set the configuration"
1044 print_screen_output "data file for your irc client. You can set color schemes for the following: start inxi with -c plus:"
1045 print_screen_output "94 (console, no X - $console); 95 (terminal, X - $virt_term); 96 (irc, gui, X - $irc_gui);"
1046 print_screen_output "97 (irc, X, in terminal - $irc_x_term); 98 (irc, no X - $irc_console); 99 (global - $global)"
1053 ########################################################################
1054 #### UTILITY FUNCTIONS
1055 ########################################################################
1057 #### -------------------------------------------------------------------
1058 #### error handler, debugger, script updater
1059 #### -------------------------------------------------------------------
1062 # args: $1 - error number; $2 - optional, extra information
1066 local error_message=''
1068 # assemble the error message
1070 2) error_message="large flood danger, debug buffer full!"
1072 3) error_message="unsupported color scheme number: $2"
1074 4) error_message="unsupported verbosity level: $2"
1076 5) error_message="dependency not met: $2 not found in path.\nFor distribution installation package names and missing apps information, run: $SCRIPT_NAME --recommends"
1078 6) error_message="/proc not found! Quitting..."
1080 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"
1082 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"
1084 9) error_message="unsupported debugging level: $2"
1087 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/"
1090 error_message="unsupported testing option argument: -! $2"
1093 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."
1096 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"
1099 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"
1102 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"
1105 error_message="$SCRIPT_NAME downloaded but the file data is corrupted. Purged data and using current version."
1108 error_message="The option you selected has been deprecated. $2\nSee the -h (help) menu for currently supported options."
1110 *) error_message="error unknown: $@"
1114 # then print it and exit
1115 print_screen_output "Error $1: $error_message"
1120 # prior to script up set, pack the data into an array
1121 # then we'll print it out later.
1122 # args: $1 - $@ debugging string text
1126 if [[ $B_SCRIPT_UP == 'true' ]];then
1127 # only return if debugger is off and no pre start up errors have occured
1128 if [[ $DEBUG -eq 0 && $DEBUG_BUFFER_INDEX -eq 0 ]];then
1130 # print out the stored debugging information if errors occured
1131 elif [[ $DEBUG_BUFFER_INDEX -gt 0 ]];then
1132 for (( DEBUG_BUFFER_INDEX=0; DEBUG_BUFFER_INDEX < ${#A_DEBUG_BUFFER[@]}; DEBUG_BUFFER_INDEX++ ))
1134 print_screen_output "${A_DEBUG_BUFFER[$DEBUG_BUFFER_INDEX]}"
1136 DEBUG_BUFFER_INDEX=0
1138 # or print out normal debugger messages if debugger is on
1139 if [[ $DEBUG -gt 0 ]];then
1140 print_screen_output "$1"
1143 if [[ $B_DEBUG_FLOOD == 'true' && $DEBUG_BUFFER_INDEX -gt 10 ]];then
1145 # this case stores the data for later printout, will print out only
1146 # at B_SCRIPT_UP == 'true' if array index > 0
1148 A_DEBUG_BUFFER[$DEBUG_BUFFER_INDEX]="$1"
1149 # increment count for next pre script up debugging error
1150 (( DEBUG_BUFFER_INDEX++ ))
1156 # NOTE: no logging available until get_parameters is run, since that's what sets logging
1157 # in order to trigger earlier logging manually set B_USE_LOGGING to true in top variables.
1158 # $1 alone: logs data; $2 with or without $3 logs func start/end.
1159 # $1 type (fs/fe/cat/raw) or logged data; [$2 is $FUNCNAME; [$3 - function args]]
1162 if [ "$B_USE_LOGGING" == 'true' ];then
1163 local logged_data='' spacer=' ' line='----------------------------------------'
1166 logged_data="Function: $2 - Primary: Start"
1168 logged_data="$logged_data\n${spacer}Args: $3"
1173 logged_data="Function: $2 - Primary: End"
1177 if [[ $B_LOG_FULL_DATA == 'true' ]];then
1178 logged_data="\n$line\nFull file data: cat $2\n\n$( cat $2 )\n$line\n"
1183 if [[ $B_LOG_FULL_DATA == 'true' ]];then
1184 logged_data="\n$line\nRaw system data:\n\n$2\n$line\n"
1192 # Create any required line breaks and strip out escape color code, either ansi (case 1)or irc (case 2).
1193 # This pattern doesn't work for irc colors, if we need that someone can figure it out
1194 if [[ -n $logged_data ]];then
1195 if [[ $B_LOG_COLORS != 'true' ]];then
1196 echo -e "${spacer}$logged_data" | sed -r 's/\x1b\[[0-9]{1,2}(;[0-9]{1,2}){0,2}m//g' >> $LOG_FILE
1198 echo -e "${spacer}$logged_data" >> $LOG_FILE
1204 # called in the initial -@ 10 script args setting so we can get logging as soon as possible
1205 # will have max 3 files, inxi.log, inxi.1.log, inxi.2.log
1206 create_rotate_logfiles()
1208 if [[ ! -d $SCRIPT_DATA_DIR ]];then
1209 mkdir $SCRIPT_DATA_DIR
1211 # do the rotation if logfile exists
1212 if [[ -f $LOG_FILE ]];then
1213 # copy if present second to third
1214 if [[ -f $LOG_FILE_1 ]];then
1215 mv -f $LOG_FILE_1 $LOG_FILE_2
1217 # then copy initial to second
1218 mv -f $LOG_FILE $LOG_FILE_1
1220 # now create the logfile
1222 # and echo the start data
1223 echo "=========================================================" >> $LOG_FILE
1224 echo "START $SCRIPT_NAME LOGGING:" >> $LOG_FILE
1225 echo "Script started: $( date +%Y-%m-%d-%H:%M:%S )" >> $LOG_FILE
1226 echo "=========================================================" >> $LOG_FILE
1229 # args: $1 - download url, not including file name; $2 - string to print out
1230 # note that $1 must end in / to properly construct the url path
1231 script_self_updater()
1234 local wget_error=0 file_contents=''
1235 print_screen_output "Starting $SCRIPT_NAME self updater."
1236 print_screen_output "Currently running $SCRIPT_NAME version number: $SCRIPT_VERSION_NUMBER"
1237 print_screen_output "Current version patch number: $SCRIPT_PATCH_NUMBER"
1238 print_screen_output "Updating $SCRIPT_NAME in $SCRIPT_PATH using $2 as download source..."
1240 file_contents="$( wget -q -O - $1$SCRIPT_NAME )" || wget_error=$?
1241 # then do the actual download
1242 if [[ $wget_error -eq 0 ]];then
1243 # make sure the whole file got downloaded and is in the variable
1244 if [[ -n $( grep '###\*\*EOF\*\*###' <<< "$file_contents" ) ]];then
1245 echo "$file_contents" > $SCRIPT_PATH/$SCRIPT_NAME || error_handler 14 "$?"
1246 chmod +x $SCRIPT_PATH/$SCRIPT_NAME || error_handler 15 "$?"
1247 SCRIPT_VERSION_NUMBER=$( grep -im 1 'version:' $SCRIPT_PATH/$SCRIPT_NAME | gawk '{print $3}' )
1248 SCRIPT_PATCH_NUMBER=$( grep -im 1 'Patch Number:' $SCRIPT_PATH/$SCRIPT_NAME | gawk '{print $4}' )
1249 print_screen_output "Successfully updated to $2 version: $SCRIPT_VERSION_NUMBER"
1250 print_screen_output "New $2 version patch number: $SCRIPT_PATCH_NUMBER"
1251 print_screen_output "To run the new version, just start $SCRIPT_NAME again."
1256 # now run the error handlers on any wget failure
1258 if [[ $2 == 'svn server' ]];then
1259 error_handler 8 "$wget_error"
1260 elif [[ $2 == 'alt server' ]];then
1261 error_handler 10 "$1"
1263 error_handler 12 "$1"
1269 # args: $1 - debug data type: sys|xorg|disk
1270 debug_data_collector()
1272 local xiin_app='' xiin_data_file='' xiin_download='' error='' b_run_xiin='false'
1273 local debug_data_dir="inxi-$(tr ' ' '-' <<< $HOSTNAME | tr '[A-Z]' '[a-z]' )-$1-$(date +%Y%m%d)"
1274 local completed_gz_file='' xiin_file='xiin.py' ftp_upload='ftp.techpatterns.com/incoming'
1275 local Line='-------------------------'
1277 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
1278 if [[ -n $ALTERNATE_FTP ]];then
1279 ftp_upload=$ALTERNATE_FTP
1281 echo "Starting debugging data collection type: $1"
1282 echo -n "Checking/creating required directories... "
1283 if [[ ! -d $SCRIPT_DATA_DIR ]];then
1284 mkdir $SCRIPT_DATA_DIR
1288 if [[ -d $debug_data_dir ]];then
1289 echo 'Deleting previous xiin data directory...'
1290 rm -rf $debug_data_dir
1292 mkdir $debug_data_dir
1293 if [[ -f $debug_data_dir.tar.gz ]];then
1294 echo 'Deleting previous tar.gz file...'
1295 rm -f $debug_data_dir.tar.gz
1298 echo 'Collecting system info: sensors, lsusb, lspci, lspci -v data, plus /proc data'
1299 lsusb &> $debug_data_dir/lsusb.txt
1300 lspci &> $debug_data_dir/lspci.txt
1301 lspci -v &> $debug_data_dir/lspci-v.txt
1302 ps aux &> $debug_data_dir/ps-aux.txt
1303 sensors &> $debug_data_dir/sensors.txt
1304 ls /usr/bin/gcc* &> $debug_data_dir/gcc-sys-versions.txt
1305 gcc --version &> $debug_data_dir/gcc-version.txt
1306 cat $FILE_LSB_RELEASE &> $debug_data_dir/lsb-release.txt
1307 cat $FILE_ASOUND_DEVICE &> $debug_data_dir/proc-asound-device.txt
1308 cat $FILE_ASOUND_VERSION &> $debug_data_dir/proc-asound-version.txt
1309 cat $FILE_CPUINFO &> $debug_data_dir/proc-cpu-info.txt
1310 cat $FILE_MEMINFO &> $debug_data_dir/proc-meminfo.txt
1311 cat $FILE_MODULES &> $debug_data_dir/proc-modules.txt
1312 cat /proc/net/arp &> $debug_data_dir/proc-net-arp.txt
1313 check_recommends &> $debug_data_dir/check-recommends.txt
1314 # first download and verify xiin
1315 if [[ $B_UPLOAD_DEBUG_DATA == 'true' || $1 == 'disk' || $1 == 'sys' || $1 == 'all' ]];then
1316 touch $debug_data_dir/xiin-error.txt
1317 echo "Downloading required tree traverse tool $xiin_file..."
1318 if [[ -f xiin && ! -f $xiin_file ]];then
1319 mv -f xiin $xiin_file
1321 # -Nc is creating really weird download anomolies, so using -O instead
1322 xiin_download="$( wget -q -O - http://inxi.googlecode.com/svn/branches/xiin/$xiin_file )"
1323 # if nothing got downloaded kick out error, otherwise we'll use an older version
1324 if [[ $? -gt 0 && ! -f $xiin_file ]];then
1325 echo -e "ERROR: Failed to download required file: $xiin_file\nMaybe the remote site is down or your networking is broken?"
1326 echo "Continuing with incomplete data collection."
1327 echo "$xiin_file download failed and no existing $xiin_file" >> $debug_data_dir/xiin-error.txt
1328 elif [[ -n $( grep -s '# EOF' <<< "$xiin_download" ) || -f $xiin_file ]];then
1329 if [[ -n $( grep -s '# EOF' <<< "$xiin_download" ) ]];then
1330 echo "Updating $xiin_file from remote location"
1331 echo "$xiin_download" > $xiin_file
1333 echo "Using local $xiin_file due to download failure"
1337 echo -e "ERROR: $xiin_file downloaded but the program file data is corrupted.\nContinuing with incomplete data collection."
1338 echo "$xiin_file downloaded but the program file data is corrupted." >> $debug_data_dir/xiin-error.txt
1341 # note, only bash 4> supports ;;& for case, so using if/then here
1342 if [[ $1 == 'disk' || $1 == 'sys' || $1 == 'all' ]];then
1343 xiin_data_file=$SCRIPT_DATA_DIR/$debug_data_dir/xiin-sys.txt
1344 echo 'Collecting networking data...'
1345 ifconfig &> $debug_data_dir/ifconfig.txt
1346 ip addr &> $debug_data_dir/ip-addr.txt
1347 if [[ $b_run_xiin == 'true' ]];then
1349 echo "Running $xiin_file tool now on /sys..."
1350 python ./$xiin_file -d /sys -f $xiin_data_file
1351 if [[ $? -ne 0 ]];then
1353 echo -e "ERROR: $xiin_file exited with error $error - removing data file.\nContinuing with incomplete data collection."
1354 echo "Continuing with incomplete data collection."
1355 rm -f $xiin_data_file
1356 echo "$xiin_file data generation failed with python error $error" >> $debug_data_dir/xiin-error.txt
1361 if [[ $1 == 'xorg' || $1 == 'all' ]];then
1362 if [[ $B_RUNNING_IN_X != 'true' ]];then
1363 echo 'Warning: only some of the data collection can occur if you are not in X'
1364 touch $debug_data_dir/warning-user-not-in-x
1366 if [[ $B_ROOT == 'true' ]];then
1367 echo 'Warning: only some of the data collection can occur if you are running as Root user'
1368 touch $debug_data_dir/warning-root-user
1370 echo 'Collecting Xorg log and xorg.conf files'
1371 if [[ -e $FILE_XORG_LOG ]];then
1372 cat $FILE_XORG_LOG &> $debug_data_dir/xorg-log-file.txt
1374 touch $debug_data_dir/no-xorg-log-file
1376 if [[ -e /etc/X11/xorg.conf ]];then
1377 cp /etc/X11/xorg.conf $debug_data_dir
1379 touch $debug_data_dir/no-xorg-conf-file
1381 if [[ -n $( ls /etc/X11/xorg.conf.d/ 2>/dev/null ) ]];then
1382 ls /etc/X11/xorg.conf.d &> $debug_data_dir/ls-etc-x11-xorg-conf-d.txt
1383 cp /etc/X11/xorg.conf.d $debug_data_dir
1385 touch $debug_data_dir/no-xorg-conf-d-files
1387 echo 'Collecting X, xprop, glxinfo, xrandr, xdpyinfo data...'
1388 xprop -root &> $debug_data_dir/xprop_root.txt
1389 glxinfo &> $debug_data_dir/glxinfo.txt
1390 xdpyinfo &> $debug_data_dir/xdpyinfo.txt
1391 xrandr &> $debug_data_dir/xrandr.txt
1392 X -version &> $debug_data_dir/x-version.txt
1393 Xorg -version &> $debug_data_dir/xorg-version.txt
1395 if [[ $1 == 'disk' || $1 == 'all' ]];then
1396 echo 'Collecting dev, label, disk, uuid data, df...'
1397 ls -l /dev &> $debug_data_dir/dev-data.txt
1398 ls -l /dev/disk &> $debug_data_dir/dev-disk-data.txt
1399 ls -l /dev/disk/by-id &> $debug_data_dir/dev-disk-id-data.txt
1400 ls -l /dev/disk/by-label &> $debug_data_dir/dev-disk-label-data.txt
1401 ls -l /dev/disk/by-uuid &> $debug_data_dir/dev-disk-uuid-data.txt
1402 ls -l /dev/disk/by-path &> $debug_data_dir/dev-disk-path-data.txt
1403 readlink /dev/root &> $debug_data_dir/dev-root.txt
1404 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-excludes.txt
1405 swapon -s &> $debug_data_dir/swapon-s.txt
1406 df -P --exclude-type=aufs --exclude-type=squashfs --exclude-type=unionfs --exclude-type=devtmpfs --exclude-type=tmpfs --exclude-type=iso9660 &> $debug_data_dir/df-excludes.txt
1407 cat $FILE_PARTITIONS &> $debug_data_dir/proc-partitions.txt
1408 cat $FILE_SCSI &> $debug_data_dir/proc-scsi.txt
1409 cat $FILE_MOUNTS &> $debug_data_dir/proc-mounts.txt
1410 cat /proc/sys/dev/cdrom/info &> $debug_data_dir/proc-cdrom-info.txt
1411 ls /proc/ide/ &> $debug_data_dir/proc-ide.txt
1412 cat /proc/ide/*/* &> $debug_data_dir/proc-ide-hdx-cat.txt
1413 cat /etc/fstab &> $debug_data_dir/etc-fstab.txt
1414 cat /etc/mtab &> $debug_data_dir/etc-mtab.txt
1416 echo 'Creating inxi output file now. This can take a few seconds...'
1417 $SCRIPT_NAME -Fploudxx -c 0 -@ 8 > $debug_data_dir/inxi-Fploudxx.txt
1418 cp $LOG_FILE $SCRIPT_DATA_DIR/$debug_data_dir
1419 if [[ -f $debug_data_dir.tar.gz ]];then
1420 echo "Found and removing previous tar.gz data file: $debug_data_dir.tar.gz"
1421 rm -f $debug_data_dir.tar.gz
1423 echo 'Creating tar.gz compressed file of this material now. Contents:'
1425 tar -cvzf $debug_data_dir.tar.gz $debug_data_dir
1427 echo 'Cleaning up leftovers...'
1428 rm -rf $debug_data_dir
1429 echo 'Testing gzip file integrity...'
1430 gzip -t $debug_data_dir.tar.gz
1431 if [[ $? -gt 0 ]];then
1432 echo 'Data in gz is corrupted, removing gzip file, try running data collector again.'
1433 rm -f $debug_data_dir.tar.gz
1434 echo "Data in gz is corrupted, removed gzip file" >> $debug_data_dir/gzip-error.txt
1436 echo 'All done, you can find your data gzipped directory here:'
1437 completed_gz_file=$SCRIPT_DATA_DIR/$debug_data_dir.tar.gz
1438 echo $completed_gz_file
1439 if [[ $B_UPLOAD_DEBUG_DATA == 'true' ]];then
1441 if [[ $b_run_xiin == 'true' ]];then
1442 echo "Running automatic upload of data to remote server $ftp_upload now..."
1443 python ./$xiin_file --version
1444 python ./$xiin_file -u $completed_gz_file $ftp_upload
1445 if [[ $? -gt 0 ]];then
1447 echo "Error: looks like the ftp upload failed. Error number: $?"
1448 echo "The ftp upload failed. Error number: $?" >> $debug_data_dir/xiin-error.txt
1451 echo 'Unable to run the automoatic ftp upload because of an error with the xiin download.'
1452 echo "Unable to run the automoatic ftp upload because of an error with the xiin download" >> $debug_data_dir/xiin-error.txt
1455 echo 'You can upload this here using most file managers: ftp.techpatterns.com/incoming'
1456 echo 'then let a maintainer know it is uploaded.'
1460 echo 'This feature only available in console or shell client! Exiting now.'
1467 local Line='-----------------------------------------------------------------------------------------'
1468 local gawk_version='N/A' sed_version='N/A' sudo_version='N/A' python_version='N/A'
1470 if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
1471 print_screen_output "Sorry, you can't run this option in an IRC client."
1475 initialize_script_paths
1477 echo "$SCRIPT_NAME will now begin checking for the programs it needs to operate. First a check of"
1478 echo "the main languages and tools $SCRIPT_NAME uses. Python is only for debugging data collection."
1480 echo "Bash version: $( bash --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^GNU bash/ {print $4}' )"
1481 if [[ -n $( type -p gawk ) ]];then
1482 gawk_version=$( gawk --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^GNU Awk/ {print $3}' )
1484 if [[ -n $( type -p sed ) ]];then
1485 sed_version=$( sed --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^GNU sed version/ {print $4}' )
1487 if [[ -n $( type -p sudo ) ]];then
1488 sudo_version=$( sudo -V 2>&1 | awk 'BEGIN {IGNORECASE=1} /^Sudo version/ {print $3}' )
1490 if [[ -n $( type -p python ) ]];then
1491 python_version=$( python --version 2>&1 | awk 'BEGIN {IGNORECASE=1} /^Python/ {print $2}' )
1493 echo "Gawk version: $gawk_version"
1494 echo "Sed version: $sed_version"
1495 echo "Sudo version: $sudo_version"
1496 echo "Python version: $python_version"
1498 echo "Test One: Required System Directories."
1499 echo "If one of these system directories is missing, $SCRIPT_NAME cannot operate:"
1501 check_recommends_items 'required-dirs'
1502 echo "Test Two: Required Core Applications."
1503 echo "If one of these applications is missing, $SCRIPT_NAME cannot operate:"
1505 check_recommends_items 'required-apps'
1506 echo 'Test Three: Script Recommends for Graphics Features. If you do not use X these do not matter.'
1507 echo "If one of these applications is missing, $SCRIPT_NAME will have incomplete output:"
1509 check_recommends_items 'recommended-x-apps'
1510 echo 'Test Four: Script Recommends for Remaining Features.'
1511 echo "If one of these applications is missing, $SCRIPT_NAME will have incomplete output:"
1513 check_recommends_items 'recommended-apps'
1514 echo 'Test Five: System Directories for Various Information.'
1515 echo "If one of these directories is missing, $SCRIPT_NAME will have incomplete output:"
1517 check_recommends_items 'system-dirs'
1518 echo 'All tests completed.'
1520 # args: $1 - check item
1521 check_recommends_items()
1523 local item='' item_list='' item_string='' missing_items='' missing_string=''
1524 local package='' application='' feature='' type='' starter='' finisher=''
1525 local package_deb='' package_pacman='' package_rpm=''
1526 local print_string='' separator=''
1527 local required_dirs='/proc /sys'
1528 # package-owner: 1 - debian/ubuntu; 2 - arch; 3 - yum/rpm
1529 # pardus: pisi sf -q /usr/bin/package
1530 local required_apps='
1531 df:coreutils~coreutils~coreutils~:partition_data
1532 free:procps~procps~procps~:system_memory
1533 gawk:gawk~gawk~gawk~:core_tool
1534 grep:grep~grep~grep~:string_search
1535 lspci:pciutils~pciutils~pciutils~:hardware_data
1536 ps:procps~procps~procps~:process_data
1537 readlink:coreutils~coreutils~coreutils~:
1538 sed:sed~sed~sed~:string_replace
1539 tr:coreutils~coreutils~coreutils~:character_replace
1540 uname:uname~coreutils~coreutils~:kernel_data
1541 uptime:procps~procps~procps~:
1542 wc:coreutils~coreutils~coreutils~:word_character_count
1544 local x_recommends='
1545 glxinfo:mesa-utils~mesa-demos~glx-utils~:-G_glx_info
1546 xdpyinfo:X11-utils~xorg-xdpyinfo~xorg-x11-utils~:-G_multi_screen_resolution
1547 xprop:X11-utils~xorg-xprop~x11-utils~:-S_desktop_data
1548 xrandr:x11-xserver-utils~xrandr~x11-server-utils~:-G_single_screen_resolution
1550 local recommended_apps='
1551 file:file~file~file~:-o_unmounted_file_system
1552 hddtemp:hddtemp~hddtemp~hddtemp~:-Dx_show_hdd_temp
1553 ifconfig:net-tools~net-tools~net-tools~:-i_ip_lan-deprecated
1554 ip:iproute~iproute2~iproute~:-i_ip_lan
1555 sensors:lm-sensors~lm_sensors~lm-sensors~:-s_sensors_output
1556 lsusb:usbutils~usbutils~usbutils~:-A_usb_audio;-N_usb_networking
1557 modinfo:module-init-tools~module-init-tools~module-init-tools~:-Ax,-Nx_module_version
1558 runlevel:sysvinit~sysvinit~systemd~:-I_runlevel
1559 sudo:sudo~sudo~sudo~:-Dx_hddtemp-user;-o_file-user
1561 local recommended_dirs='
1562 /sys/class/dmi/id:-M_system,_motherboard,_bios
1563 /dev:-l,-u,-o,-p,-P,-D_disk_partition_data
1564 /dev/disk/by-label:-l,-o,-p,-P_partition_labels
1565 /dev/disk/by-uuid:-u,-o,-p,-P_partition_uuid
1570 item_list=$required_dirs
1571 item_string='Required file system'
1572 missing_string='system directories'
1576 item_list=$required_apps
1577 item_string='Required application'
1578 missing_string='applications, and their corresponding packages,'
1582 item_list=$x_recommends
1583 item_string='Recommended X application'
1584 missing_string='applications, and their corresponding packages,'
1588 item_list=$recommended_apps
1589 item_string='Recommended application'
1590 missing_string='applications, and their corresponding packages,'
1594 item_list=$recommended_dirs
1595 item_string='System directory'
1596 missing_string='system directories'
1600 # great trick from: http://ideatrash.net/2011/01/bash-string-padding-with-sed.html
1601 # left pad: sed -e :a -e 's/^.\{1,80\}$/& /;ta'
1602 # right pad: sed -e :a -e 's/^.\{1,80\}$/ &/;ta'
1603 # center pad: sed -e :a -e 's/^.\{1,80\}$/ & /;ta'
1605 for item in $item_list
1607 if [[ $( awk -F ":" '{print NF-1}' <<< $item ) -eq 0 ]];then
1612 elif [[ $( awk -F ":" '{print NF-1}' <<< $item ) -eq 1 ]];then
1613 application=$( cut -d ':' -f 1 <<< $item )
1615 feature=$( cut -d ':' -f 2 <<< $item )
1618 application=$( cut -d ':' -f 1 <<< $item )
1619 package=$( cut -d ':' -f 2 <<< $item )
1620 location=$( type -p $application )
1621 if [[ $( awk -F ":" '{print NF-1}' <<< $item ) -eq 2 ]];then
1622 feature=$( cut -d ':' -f 3 <<< $item )
1627 if [[ -n $feature ]];then
1628 print_string="$item_string: $application (info: $( sed 's/_/ /g' <<< $feature ))"
1630 print_string="$item_string: $application"
1632 starter="$( sed -e :a -e 's/^.\{1,75\}$/&./;ta' <<< $print_string )"
1633 if [[ -z $( grep '^/' <<< $application ) && -n $location ]] || [[ -d $application ]];then
1634 if [[ -n $location ]];then
1635 finisher=" $location"
1641 missing_items="$missing_items$separator$application:$package"
1645 echo "$starter$finisher"
1648 if [[ -n $missing_items ]];then
1649 echo "The following $type are missing from your system:"
1650 for item in $missing_items
1652 application=$( cut -d ':' -f 1 <<< $item )
1653 if [[ $type == 'applications' ]];then
1654 # echo '--------------------------------------------------------'
1656 package=$( cut -d ':' -f 2 <<< $item )
1657 package_deb=$( cut -d '~' -f 1 <<< $package )
1658 package_pacman=$( cut -d '~' -f 2 <<< $package )
1659 package_rpm=$( cut -d '~' -f 3 <<< $package )
1660 echo "Application: $application"
1661 echo "To add to your system, install the proper distribution package for your system:"
1662 echo "Debian/Ubuntu: $package_deb :: Arch Linux: $package_pacman :: Redhat/Fedora/Suse: $package_rpm"
1664 echo "Directory: $application"
1667 if [[ $item_string == 'System directory' ]];then
1668 echo "These directories are created by the kernel, so don't worry if they are not present."
1671 echo "All the $( cut -d ' ' -f 1 <<< $item_string | sed -e 's/Re/re/' -e 's/Sy/sy/' ) $type are present."
1676 #### -------------------------------------------------------------------
1677 #### print / output cleaners
1678 #### -------------------------------------------------------------------
1680 # inxi speaks through here. When run by Konversation script alias mode, uses DCOP
1681 # for dcop to work, must use 'say' operator, AND colors must be evaluated by echo -e
1682 # note: dcop does not seem able to handle \n so that's being stripped out and replaced with space.
1683 print_screen_output()
1686 # the double quotes are needed to avoid losing whitespace in data when certain output types are used
1687 local print_data="$( echo -e "$1" )"
1689 # just using basic debugger stuff so you can tell which thing is printing out the data. This
1690 # should help debug kde 4 konvi issues when that is released into sid, we'll see. Turning off
1691 # the redundant debugger output which as far as I can tell does exactly nothing to help debugging.
1692 if [[ $DEBUG -gt 5 ]];then
1693 if [[ $KONVI -eq 1 ]];then
1694 # konvi doesn't seem to like \n characters, it just prints them literally
1695 # print_data="$( tr '\n' ' ' <<< "$print_data" )"
1696 # dcop "$DCPORT" "$DCOPOBJ" say "$DCSERVER" "$DCTARGET" "konvi='$KONVI' saying : '$print_data'"
1697 print_data="KP-$KONVI: $print_data"
1698 elif [[ $KONVI -eq 2 ]];then
1699 # echo "konvi='$KONVI' saying : '$print_data'"
1700 print_data="KP-$KONVI: $print_data"
1702 # echo "printing out: '$print_data'"
1703 print_data="P: $print_data"
1707 if [[ $KONVI -eq 1 && $B_DCOP == 'true' ]]; then ## dcop Konversation (<= 1.1 (qt3))
1708 # konvi doesn't seem to like \n characters, it just prints them literally
1709 $print_data="$( tr '\n' ' ' <<< "$print_data" )"
1710 dcop "$DCPORT" "$DCOPOBJ" say "$DCSERVER" "$DCTARGET" "$print_data"
1712 elif [[ $KONVI -eq 3 && $B_QDBUS == 'true' ]]; then ## dbus Konversation (> 1.2 (qt4))
1713 qdbus org.kde.konversation /irc say "$DCSERVER" "$DCTARGET" "$print_data"
1715 # elif [[ $IRC_CLIENT == 'X-Chat' ]]; then
1716 # qdbus org.xchat.service print "$print_data\n"
1719 # the -n is needed to avoid double spacing of output in terminal
1720 echo -ne "$print_data\n"
1725 ## this handles all verbose line construction with indentation/line starter
1726 ## args: $1 - null (, actually: " ") or line starter; $2 - line content
1730 printf "${C1}%-${INDENT}s${C2} %s" "$1" "$2"
1734 # this removes newline and pipes.
1735 # args: $1 - string to clean
1736 remove_erroneous_chars()
1739 ## RS is input record separator
1740 ## gsub is substitute;
1746 gsub(/\n$/,"") ## (newline; end of string) with (nothing)
1747 gsub(/\n/," "); ## (newline) with (space)
1748 gsub(/^ *| *$/, "") ## (pipe char) with (nothing)
1749 gsub(/ +/, " ") ## ( +) with (space)
1750 gsub(/ [ ]+/, " ") ## ([ ]+) with (space)
1751 gsub(/^ +| +$/, "") ## (pipe char) with (nothing)
1753 }' "$1" ## prints (returns) cleaned input
1757 #### -------------------------------------------------------------------
1758 #### parameter handling, print usage functions.
1759 #### -------------------------------------------------------------------
1761 # Get the parameters. Note: standard options should be lower case, advanced or testing, upper
1762 # args: $1 - full script startup args: $@
1766 local opt='' wget_test='' update_flags='U!:' debug_data_type=''
1767 local use_short='true' # this is needed to trigger short output, every v/d/F/line trigger sets this false
1769 # If distro maintainers want to not allow updates, turn off that option for users
1770 if [[ $B_ALLOW_UPDATE == 'false' ]];then
1773 if [[ $1 == '--version' ]];then
1776 elif [[ $1 == '--help' ]];then
1779 elif [[ $1 == '--recommends' ]];then
1782 # the short form only runs if no args output args are used
1783 # no need to run through these if there are no args
1784 # reserved for future use: -g for extra Graphics; -m for extra Machine; -d for extra Disk
1785 elif [[ -n $1 ]];then
1786 while getopts Abc:CdDfFGhHiIlMnNopPrsSt:uv:VxzZ%@:${update_flags} opt
1789 A) B_SHOW_AUDIO='true'
1792 b) use_short='false'
1793 B_SHOW_BASIC_CPU='true'
1794 B_SHOW_DISK_TOTAL='true'
1795 B_SHOW_GRAPHICS='true'
1797 B_SHOW_MACHINE='true'
1798 B_SHOW_NETWORK='true'
1799 B_SHOW_SYSTEM='true'
1801 c) if [[ -n $( grep -E '^[0-9][0-9]?$' <<< $OPTARG ) ]];then
1804 B_RUN_COLOR_SELECTOR='true'
1805 COLOR_SELECTION='global'
1808 B_RUN_COLOR_SELECTOR='true'
1809 COLOR_SELECTION='irc-console'
1812 B_RUN_COLOR_SELECTOR='true'
1813 COLOR_SELECTION='irc-virtual-terminal'
1816 B_RUN_COLOR_SELECTOR='true'
1817 COLOR_SELECTION='irc'
1820 B_RUN_COLOR_SELECTOR='true'
1821 COLOR_SELECTION='virtual-terminal'
1824 B_RUN_COLOR_SELECTOR='true'
1825 COLOR_SELECTION='console'
1828 B_COLOR_SCHEME_SET='true'
1829 ## note: not sure about this, you'd think user values should be overridden, but
1830 ## we'll leave this for now
1831 if [[ -z $COLOR_SCHEME ]];then
1832 set_color_scheme "$OPTARG"
1837 error_handler 3 "$OPTARG"
1840 C) B_SHOW_CPU='true'
1843 d) B_SHOW_DISK='true'
1844 B_SHOW_FULL_OPTICAL='true'
1846 # error_handler 20 "-d has been replaced by -b"
1848 D) B_SHOW_DISK='true'
1851 f) B_SHOW_CPU='true'
1852 B_CPU_FLAGS_FULL='true'
1855 F) # B_EXTRA_DATA='true'
1856 B_SHOW_ADVANCED_NETWORK='true'
1858 # B_SHOW_BASIC_OPTICAL='true'
1861 B_SHOW_GRAPHICS='true'
1863 B_SHOW_MACHINE='true'
1864 B_SHOW_NETWORK='true'
1865 B_SHOW_PARTITIONS='true'
1866 B_SHOW_SENSORS='true'
1867 B_SHOW_SYSTEM='true'
1870 G) B_SHOW_GRAPHICS='true'
1874 B_SHOW_NETWORK='true'
1875 B_SHOW_ADVANCED_NETWORK='true'
1878 I) B_SHOW_INFO='true'
1881 l) B_SHOW_LABELS='true'
1882 B_SHOW_PARTITIONS='true'
1885 M) B_SHOW_MACHINE='true'
1888 n) B_SHOW_ADVANCED_NETWORK='true'
1889 B_SHOW_NETWORK='true'
1892 N) B_SHOW_NETWORK='true'
1895 o) B_SHOW_UNMOUNTED_PARTITIONS='true'
1898 p) B_SHOW_PARTITIONS_FULL='true'
1899 B_SHOW_PARTITIONS='true'
1902 P) B_SHOW_PARTITIONS='true'
1905 r) B_SHOW_REPOS='true'
1908 s) B_SHOW_SENSORS='true'
1911 S) B_SHOW_SYSTEM='true'
1914 t) if [[ -n $( grep -E '^(c|m|cm|mc)([1-9]|1[0-9]|20)?$' <<< $OPTARG ) ]];then
1916 if [[ -n $( grep -E '[0-9]+' <<< $OPTARG ) ]];then
1917 PS_COUNT=$( grep -Eo '[0-9]+' <<< $OPTARG )
1919 if [[ -n $( grep 'c' <<< $OPTARG ) ]];then
1920 B_SHOW_PS_CPU_DATA='true'
1922 if [[ -n $( grep 'm' <<< $OPTARG ) ]];then
1923 B_SHOW_PS_MEM_DATA='true'
1926 error_handler 13 "$OPTARG"
1929 u) B_SHOW_UUIDS='true'
1930 B_SHOW_PARTITIONS='true'
1933 v) if [[ -n $( grep -E "^[0-9][0-9]?$" <<< $OPTARG ) && $OPTARG -le $VERBOSITY_LEVELS ]];then
1934 if [[ $OPTARG -ge 1 ]];then
1936 B_SHOW_BASIC_CPU='true'
1937 B_SHOW_DISK_TOTAL='true'
1938 B_SHOW_GRAPHICS='true'
1940 B_SHOW_SYSTEM='true'
1942 if [[ $OPTARG -ge 2 ]];then
1943 B_SHOW_BASIC_DISK='true'
1944 B_SHOW_MACHINE='true'
1945 B_SHOW_NETWORK='true'
1947 if [[ $OPTARG -ge 3 ]];then
1948 B_SHOW_ADVANCED_NETWORK='true'
1952 if [[ $OPTARG -ge 4 ]];then
1954 B_SHOW_PARTITIONS='true'
1956 if [[ $OPTARG -ge 5 ]];then
1958 B_SHOW_BASIC_OPTICAL='true'
1959 B_SHOW_SENSORS='true'
1960 B_SHOW_LABELS='true'
1963 if [[ $OPTARG -ge 6 ]];then
1964 B_SHOW_FULL_OPTICAL='true'
1965 B_SHOW_PARTITIONS_FULL='true'
1966 B_SHOW_UNMOUNTED_PARTITIONS='true'
1968 if [[ $OPTARG -ge 7 ]];then
1969 B_EXTRA_EXTRA_DATA='true'
1973 error_handler 4 "$OPTARG"
1976 U) script_self_updater "$SCRIPT_DOWNLOAD" 'svn server'
1978 V) print_version_info
1981 # this will trigger either with xx or with Fx but not with xF
1982 x) if [[ $B_EXTRA_DATA == 'true' ]];then
1983 B_EXTRA_EXTRA_DATA='true'
1987 z) B_OUTPUT_FILTER='true'
1989 Z) B_OVERRIDE_FILTER='true'
1994 H) show_options 'full'
1997 ## debuggers and testing tools
1998 %) B_HANDLE_CORRUPT_DATA='true'
2000 @) if [[ -n $( grep -E "^([1-9]|1[0-4])$" <<< $OPTARG ) ]];then
2002 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
2003 B_UPLOAD_DEBUG_DATA='true'
2006 # switch on logging only for -@ 8-10
2009 if [[ $OPTARG -eq 10 ]];then
2011 elif [[ $OPTARG -eq 9 ]];then
2012 B_LOG_FULL_DATA='true'
2014 B_USE_LOGGING='true'
2015 # pack the logging data for evals function start/end
2018 create_rotate_logfiles # create/rotate logfiles before we do anything else
2023 debug_data_type='sys'
2026 debug_data_type='xorg'
2029 debug_data_type='disk'
2032 debug_data_type='all'
2035 initialize_script_data
2036 debug_data_collector $debug_data_type
2040 error_handler 9 "$OPTARG"
2043 !) # test for various supported methods
2045 1) B_TESTING_1='true'
2047 2) B_TESTING_2='true'
2049 3) B_TESTING_1='true'
2053 script_self_updater "$SCRIPT_DOWNLOAD_DEV" 'dev server'
2056 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_1" 'svn: branch one server'
2059 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_2" 'svn: branch two server'
2062 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_3" 'svn: branch three server'
2065 script_self_updater "$SCRIPT_DOWNLOAD_BRANCH_4" 'svn: branch four server'
2068 ALTERNATE_FTP="$OPTARG"
2071 script_self_updater "$OPTARG" 'alt server'
2073 *) error_handler 11 "$OPTARG"
2077 *) error_handler 7 "$1"
2082 ## this must occur here so you can use the debugging flag to show errors
2083 ## Reroute all error messages to the bitbucket (if not debugging)
2084 if [[ $DEBUG -eq 0 ]];then
2087 #((DEBUG)) && exec 2>&1 # This is for debugging konversation
2089 # after all the args have been processed, if no long output args used, run short output
2090 if [[ $use_short == 'true' ]];then
2091 B_SHOW_SHORT_OUTPUT='true'
2093 # just in case someone insists on using -zZ
2094 if [[ $B_OVERRIDE_FILTER == 'true' ]];then
2095 B_OUTPUT_FILTER='false'
2100 ## print out help menu, not including Testing or Debugger stuff because it's not needed
2103 local color_scheme_count=$(( ${#A_COLOR_SCHEMES[@]} - 1 ))
2105 if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
2106 print_screen_output "Sorry, you can't run the help option in an IRC client."
2109 print_screen_output "$SCRIPT_NAME supports the following options. You can combine them, or list them"
2110 print_screen_output "one by one: Examples: $SCRIPT_NAME -v4 -c6 OR $SCRIPT_NAME -bDc 6"
2111 print_screen_output " "
2112 print_screen_output "If you start $SCRIPT_NAME with no arguments, it will show the short form."
2113 print_screen_output "The following options if used without -F, -b, or -v will show just the complete line(s):"
2114 print_screen_output "A,C,D,G,I,M,N,P,S,f,i,n,o,p,l,u,r,s,t - you can use these alone or together to show"
2115 print_screen_output "just the line(s) you want to see."
2116 print_screen_output "If you use them with -v [level], -b or -F, it will show the full output for that line "
2117 print_screen_output "along with the output for the chosen verbosity level."
2118 print_screen_output "- - - - - - - - - - - - - - - - - - - - - - - - - - - - -"
2119 print_screen_output "Output Control Options:"
2120 print_screen_output "-A Show Audio/sound card information."
2121 print_screen_output "-b Shows basic output, short form (previously -d). Same as: $SCRIPT_NAME -v 2"
2122 print_screen_output "-c Available color schemes. Scheme number is required. Color selectors run a color selector option"
2123 print_screen_output " prior to $SCRIPT_NAME starting which lets you set the config file value for the selection."
2124 print_screen_output " Supported color schemes: 0-$color_scheme_count Example: $SCRIPT_NAME -c 11"
2125 print_screen_output " Color selectors for each type display (NOTE: irc and global only show safe color set):"
2126 print_screen_output " 94 - Console, out of X"
2127 print_screen_output " 95 - Terminal, running in X - like xTerm"
2128 print_screen_output " 96 - Gui IRC, running in X - like Xchat, Quassel, Konversation etc."
2129 print_screen_output " 97 - Console IRC running in X - like irssi in xTerm"
2130 print_screen_output " 98 - Console IRC not in X"
2131 print_screen_output " 99 - Global - Overrides/removes all settings. Setting specific removes global."
2132 print_screen_output "-C Show full CPU output, including per CPU clockspeed."
2133 print_screen_output "-d Shows optical drive data. Same as -Dd. With -x, adds features line to output. -xx adds a few more features."
2134 print_screen_output "-D Show full hard Disk info, not only model, ie: /dev/sda ST380817AS 80.0GB."
2135 print_screen_output "-f Show all cpu flags used, not just the short list. Not shown with -F to avoid spamming."
2136 print_screen_output "-F Show Full output for $SCRIPT_NAME. Includes all Upper Case line letters, plus -s and -n."
2137 print_screen_output " Does not show extra verbose options like -x -d -f -u -l -o -p -t -r unless you use that argument."
2138 print_screen_output "-G Show Graphic card information (card, x type, resolution, glx renderer, version)."
2139 print_screen_output "-i Show Wan IP address, and shows local interfaces (requires ifconfig network tool). Same as -Nni"
2140 print_screen_output " Not shown with -F for user security reasons, you shouldn't paste your local/wan IP."
2141 print_screen_output "-I Show Information: processes, uptime, memory, irc client, inxi version."
2142 print_screen_output "-l Show partition labels. Default: short partition -P. For full -p output, use: -pl (or -plu)."
2143 print_screen_output "-M Show machine data. Motherboard, Bios, and if present, System Builder (Like Lenovo)."
2144 print_screen_output " Older systems/kernels without the required /sys data can use dmidecode instead, run as root."
2145 print_screen_output "-n Show Advanced Network card information. Same as -Nn. Shows interface, speed, mac id, state, etc."
2146 print_screen_output "-N Show Network card information. With -x, shows PCI BusID, Port number."
2147 print_screen_output "-o Show unmounted partition information (includes UUID and LABEL if available)."
2148 print_screen_output " Shows file system type if you have file installed, if you are root OR if you have"
2149 print_screen_output " added to /etc/sudoers (sudo v. 1.7 or newer): <username> ALL = NOPASSWD: /usr/bin/file (sample)"
2150 print_screen_output "-p Show full partition information (-P plus all other detected partitions)."
2151 print_screen_output "-P Show Partition information (shows what -v 4 would show, but without extra data)."
2152 print_screen_output " Shows, if detected: / /boot /home /tmp /usr /var. Use -p to see all mounted partitions."
2153 print_screen_output "-r Show distro repository data. Currently supported repo types: APT; PACMAN; PISI; YUM."
2154 print_screen_output "-s Show sensors output (if sensors installed/configured): mobo/cpu/gpu temp; detected fan speeds."
2155 print_screen_output " Gpu temp only for Fglrx/Nvidia drivers. Nvidia shows screen number for > 1 screens."
2156 print_screen_output "-S Show System information: host name, kernel, desktop environment (if in X), distro"
2157 print_screen_output "-t Show processes. Requires extra options: c (cpu) m (memory) cm (cpu+memory). If followed by numbers 1-20,"
2158 print_screen_output " shows that number of processes for each type (default: $PS_COUNT; if in irc, max: 5): -t cm10"
2159 print_screen_output " Make sure to have no space between letters and numbers (-t cm10 -right, -t cm 10 -wrong)."
2160 print_screen_output "-u Show partition UUIDs. Default: short partition -P. For full -p output, use: -pu (or -plu)."
2161 print_screen_output "-v Script verbosity levels. Verbosity level number is required. Should not be used with -b or -F"
2162 print_screen_output " Supported levels: 0-${VERBOSITY_LEVELS} Example: $SCRIPT_NAME -v 4"
2163 print_screen_output " 0 - Short output, same as: $SCRIPT_NAME"
2164 print_screen_output " 1 - Basic verbose, -S + basic CPU + -G + basic Disk + -I."
2165 print_screen_output " 2 - Adds networking card (-N), Machine (-M) data, and shows basic hard disk data (names only)."
2166 print_screen_output " Same as: $SCRIPT_NAME -b"
2167 print_screen_output " 3 - Adds advanced CPU (-C), network (-n) data, and switches on -x advanced data option."
2168 print_screen_output " 4 - Adds partition size/filled data (-P) for (if present):/, /home, /var/, /boot"
2169 print_screen_output " Shows full disk data (-D)"
2170 print_screen_output " 5 - Adds audio card (-A); sensors (-s), partion label (-l) and UUID (-u), short form of optical drives."
2171 print_screen_output " 6 - Adds full partition data (-p), unmounted partition data (-o), optical drive data (-d)."
2172 print_screen_output " 7 - Adds network IP data (-i); triggers -xx."
2173 print_screen_output "-x Show extra data (only works with verbose or line output, not short form): "
2174 print_screen_output " -C - bogomips on Cpu;"
2175 print_screen_output " -d - Adds items to features line of optical drive; adds rev version to optical drive."
2176 print_screen_output " -D - Hdd temp with disk data if you have hddtemp installed, if you are root OR if you have added to"
2177 print_screen_output " /etc/sudoers (sudo v. 1.7 or newer): <username> ALL = NOPASSWD: /usr/sbin/hddtemp (sample)"
2178 print_screen_output " -G - Direct rendering status for Graphics (in X)."
2179 print_screen_output " -G - (for single gpu, nvidia driver) screen number gpu is running on."
2180 print_screen_output " -i - Show IPv6 as well for LAN interface (IF) devices."
2181 print_screen_output " -I - Show system GCC, default. With -xx, also show other installed GCC versions."
2182 print_screen_output " -N -A - Adds version/port(s)/driver version (if available) for Network/Audio;"
2183 print_screen_output " -N -A -G - Network, audio, graphics, shows PCI Bus ID/Usb ID number of card;"
2184 print_screen_output " -S - Desktop toolkit if avaliable (GNOME/XFCE/KDE only); Kernel gcc version"
2185 print_screen_output " -t - Adds memory use output to cpu (-xt c), and cpu use to memory (-xt m)."
2186 print_screen_output "-xx Show extra, extra data (only works with verbose or line output, not short form): "
2187 print_screen_output " -I - Adds other detected installed gcc versions to primary gcc output (if present)."
2188 print_screen_output " -M - Adds chassis information, if any data for that is available."
2189 print_screen_output " -xx -@ <11-14> - Automatically uploads debugger data tar.gz file to ftp.techpatterns.com."
2190 print_screen_output "-z Adds security filters for IP addresses, Mac, and user home directory name. Default on for irc clients."
2191 print_screen_output "-Z Absolute override for output filters. Useful for debugging networking issues in irc for example."
2192 print_screen_output " "
2193 print_screen_output "Additional Options:"
2194 print_screen_output "-h --help This help menu."
2195 print_screen_output "-H This help menu, plus developer options. Do not use dev options in normal operation!"
2196 print_screen_output "--recommends Checks $SCRIPT_NAME application dependencies + recommends, and directories, then shows"
2197 print_screen_output " what package(s) you need to install to add support for that feature."
2198 if [[ $B_ALLOW_UPDATE == 'true' ]];then
2199 print_screen_output "-U Auto-update script. Note: if you installed as root, you"
2200 print_screen_output " must be root to update, otherwise user is fine."
2202 print_screen_output "-V --version $SCRIPT_NAME version information. Prints information then exits."
2203 print_screen_output " "
2204 print_screen_output "Debugging Options:"
2205 print_screen_output "-% Overrides defective or corrupted data."
2206 print_screen_output "-@ Triggers debugger output. Requires debugging level 1-14 (8-10 - logging of data)."
2207 print_screen_output " Less than 8 just triggers $SCRIPT_NAME debugger output on screen."
2208 print_screen_output " 1-7 - On screen debugger output"
2209 print_screen_output " 8 - Basic logging"
2210 print_screen_output " 9 - Full file/sys info logging"
2211 print_screen_output " 10 - Color logging."
2212 print_screen_output " The following create a tar.gz file of system data, plus collecting the inxi output to file:"
2213 print_screen_output " To automatically upload debugger data tar.gz file to ftp.techpatterns.com: inxi -xx@ <11-14>"
2214 print_screen_output " For alternate ftp upload locations: Example: inxi -! ftp.yourserver.com/incoming -xx@ 14"
2215 print_screen_output " 11 - With data file of xiin read of /sys."
2216 print_screen_output " 12 - With xorg conf and log data, xrandr, xprop, xdpyinfo, glxinfo etc."
2217 print_screen_output " 13 - With data from dev, disks, partitions, etc., plus xiin data file."
2218 print_screen_output " 14 - Everything, full data collection."
2219 if [[ $1 == 'full' ]];then
2220 print_screen_output " "
2221 print_screen_output "Developer and Testing Options (Advanced):"
2222 print_screen_output "-! 1 - Sets testing flag B_TESTING_1='true' to trigger testing condition 1."
2223 print_screen_output "-! 2 - Sets testing flag B_TESTING_2='true' to trigger testing condition 2."
2224 print_screen_output "-! 3 - Sets flags B_TESTING_1='true' and B_TESTING_2='true'."
2225 print_screen_output "-! 10 - Triggers an update from the primary dev download server instead of svn."
2226 print_screen_output "-! 11 - Triggers an update from svn branch one - if present, of course."
2227 print_screen_output "-! 12 - Triggers an update from svn branch two - if present, of course."
2228 print_screen_output "-! 13 - Triggers an update from svn branch three - if present, of course."
2229 print_screen_output "-! 14 - Triggers an update from svn branch four - if present, of course."
2230 print_screen_output "-! <http://......> - Triggers an update from whatever server you list."
2231 print_screen_output "-! <ftp.......> - Changes debugging data ftp upload location to whatever you enter here."
2232 print_screen_output " Only used together with -xx@ 11-14, and must be used in front of that."
2233 print_screen_output " Example: inxi -! ftp.yourserver.com/incoming -xx@ 14"
2234 print_screen_output " "
2236 print_screen_output " "
2239 ## print out version information for -V/--version
2240 print_version_info()
2242 local last_modified=$( grep -im 1 'date:' $SCRIPT_PATH/$SCRIPT_NAME | gawk '{print $3,$4,$5}' )
2244 print_screen_output "$SCRIPT_NAME - the universal, portable, system info script for console and irc."
2245 print_screen_output "Version: $SCRIPT_VERSION_NUMBER-$SCRIPT_PATCH_NUMBER"
2246 print_screen_output "Script Last Modified: $last_modified"
2247 print_screen_output "Script Location: $SCRIPT_PATH"
2248 print_screen_output " "
2249 print_screen_output "Tested in Irssi, Xchat, Konversation, BitchX, KSirc, ircII,"
2250 print_screen_output "Gaim/Pidgin, Weechat, KVIrc, Quassel, Kopete, and others."
2251 print_screen_output " "
2252 print_screen_output "This script is a fork of Infobash 3.02, which is:"
2253 print_screen_output "Copyright (C) 2005-2007 Michiel de Boer a.k.a. locsmif"
2254 print_screen_output "Subsequent changes and modifications (after Infobash 3.02) are:"
2255 print_screen_output "Copyright (C) 2008-$(date +%y) Scott Rogers, Harald Hope, aka trash80 & h2"
2256 print_screen_output " "
2257 print_screen_output "This program is free software; you can redistribute it and/or modify"
2258 print_screen_output "it under the terms of the GNU General Public License as published by"
2259 print_screen_output "the Free Software Foundation; either version 3 of the License, or"
2260 print_screen_output "(at your option) any later version."
2263 ########################################################################
2265 ########################################################################
2267 #### -------------------------------------------------------------------
2268 #### initial startup stuff
2269 #### -------------------------------------------------------------------
2271 # Determine where inxi was run from, set IRC_CLIENT and IRC_CLIENT_VERSION
2275 local irc_client_path='' irc_client_path_lower='' non_native_konvi='' i=''
2276 local b_non_native_app='false' pppid='' app_working_name=''
2277 local b_qt4_konvi='false'
2279 if [[ $B_RUNNING_IN_SHELL == 'true' ]];then
2281 unset IRC_CLIENT_VERSION
2282 elif [[ -n $PPID && -f /proc/$PPID/exe ]];then
2283 if [[ $B_OVERRIDE_FILTER != 'true' ]];then
2284 B_OUTPUT_FILTER='true'
2286 irc_client_path=$( readlink /proc/$PPID/exe )
2287 irc_client_path_lower=$( tr '[:upper:]' '[:lower:]' <<< $irc_client_path )
2288 app_working_name=$( basename $irc_client_path_lower )
2289 # handles the xchat/sh/bash/dash cases, and the konversation/perl cases, where clients
2290 # report themselves as perl or unknown shell. IE: when konversation starts inxi
2291 # from inside itself, as a script, the parent is konversation/xchat, not perl/bash etc
2292 # note: perl can report as: perl5.10.0, so it needs wildcard handling
2293 case $app_working_name in
2294 bash|dash|sh|python*|perl*) # We want to know who wrapped it into the shell or perl.
2295 pppid="$( ps -p $PPID -o ppid --no-headers | sed 's/ //g' )"
2296 if [[ -n $pppid && -f /proc/$pppid/exe ]];then
2297 irc_client_path="$( readlink /proc/$pppid/exe )"
2298 irc_client_path_lower="$( tr '[:upper:]' '[:lower:]' <<< $irc_client_path )"
2299 app_working_name=$( basename $irc_client_path_lower )
2300 b_non_native_app='true'
2304 # replacing loose detection with tight detection, bugs will be handled with app names
2306 case $app_working_name in
2307 # check for shell first
2309 unset IRC_CLIENT_VERSION
2310 IRC_CLIENT="Shell wrapper"
2312 # now start on irc clients, alphabetically
2314 IRC_CLIENT_VERSION=" $( $irc_client_path -v | gawk '
2317 gsub(/[()]|bitchx-/,"",a)
2327 B_CONSOLE_IRC='true'
2331 IRC_CLIENT_VERSION=" $( $irc_client_path -v | gawk 'NR == 1 {
2334 B_CONSOLE_IRC='true'
2338 IRC_CLIENT_VERSION=" $( $irc_client_path -v | gawk 'NR == 1 {
2344 IRC_CLIENT_VERSION=" $( $irc_client_path -v | gawk 'NR == 1 {
2347 B_CONSOLE_IRC='true'
2351 IRC_CLIENT_VERSION=" $( $irc_client_path -v | gawk 'NR == 1 {
2354 B_CONSOLE_IRC='true'
2357 konversation) ## konvi < 1.2 (qt4)
2358 # this is necessary to avoid the dcop errors from starting inxi as a /cmd started script
2359 if [[ $b_non_native_app == 'true' ]];then ## true negative is confusing
2361 else # if native app
2364 IRC_CLIENT_VERSION=" $( $irc_client_path -v | gawk '
2366 for ( i=2; i<=NF; i++ ) {
2377 T=($IRC_CLIENT_VERSION)
2378 if [[ ${T[0]} == *+* ]];then
2379 # < Sho_> locsmif: The version numbers of SVN versions look like this:
2380 # "<version number of last release>+ #<build number", i.e. "1.0+ #3177" ...
2381 # for releases we remove the + and build number, i.e. "1.0" or soon "1.0.1"
2382 IRC_CLIENT_VERSION=" CVS $IRC_CLIENT_VERSION"
2385 IRC_CLIENT_VERSION=" ${T[0]}"
2388 # Remove any dots except the first, and make sure there are no trailing zeroes,
2389 T2=$( echo "$T2" | gawk '{
2395 # Since Konversation 1.0, the DCOP interface has changed a bit: dcop "$DCPORT" Konversation ..etc
2396 # becomes : dcop "$DCPORT" default ... or dcop "$DCPORT" irc ..etc. So we check for versions smaller
2397 # than 1 and change the DCOP parameter/object accordingly.
2398 if [[ ${T2} -lt 1 ]];then
2399 DCOPOBJ="Konversation"
2401 IRC_CLIENT="Konversation"
2404 IRC_CLIENT_VERSION=" $( kopete -v | gawk '
2412 IRC_CLIENT_VERSION=" $( $irc_client_path -v 2>&1 | gawk '{
2413 for ( i=2; i<=NF; i++) {
2426 IRC_CLIENT_VERSION=" $( $irc_client_path -v | gawk 'NR == 1 {
2432 # sample: quassel -v
2434 # KDE: 4.2.65 (KDE 4.2.65 (KDE 4.3 >= 20090226))
2435 # Quassel IRC: v0.4.0 [+60] (git-22effe5)
2436 # note: early < 0.4.1 quassels do not have -v
2437 IRC_CLIENT_VERSION=" $( $irc_client_path -v 2>/dev/null | gawk -F ': ' '
2446 # this handles pre 0.4.1 cases with no -v
2447 if ( clientVersion == "" ) {
2448 clientVersion = "(pre v0.4.1)"
2452 # now handle primary, client, and core. quasselcore doesn't actually
2453 # handle scripts with exec, but it's here just to be complete
2454 case $app_working_name in
2456 IRC_CLIENT="Quassel [M]"
2459 IRC_CLIENT="Quassel"
2462 IRC_CLIENT="Quassel (core)"
2467 IRC_CLIENT_VERSION=" $( $irc_client_path -v ) "
2468 B_CONSOLE_IRC='true'
2469 IRC_CLIENT="Weechat"
2472 IRC_CLIENT_VERSION=" $( $irc_client_path -v | gawk 'NR == 1 {
2475 IRC_CLIENT="X-Chat-Gnome"
2478 IRC_CLIENT_VERSION=" $( $irc_client_path -v | gawk 'NR == 1 {
2483 # then do some perl type searches, do this last since it's a wildcard search
2485 unset IRC_CLIENT_VERSION
2486 # KSirc is one of the possibilities now. KSirc is a wrapper around dsirc, a perl client
2488 for (( i=0; i <= $CMDL_MAX; i++ ))
2490 case ${A_CMDL[i]} in
2493 # Dynamic runpath detection is too complex with KSirc, because KSirc is started from
2494 # kdeinit. /proc/<pid of the grandparent of this process>/exe is a link to /usr/bin/kdeinit
2495 # with one parameter which contains parameters separated by spaces(??), first param being KSirc.
2496 # Then, KSirc runs dsirc as the perl irc script and wraps around it. When /exec is executed,
2497 # dsirc is the program that runs inxi, therefore that is the parent process that we see.
2498 # You can imagine how hosed I am if I try to make inxi find out dynamically with which path
2499 # KSirc was run by browsing up the process tree in /proc. That alone is straightjacket material.
2500 # (KSirc sucks anyway ;)
2501 IRC_CLIENT_VERSION=" $( ksirc -v | gawk '
2510 B_CONSOLE_IRC='true'
2511 set_perl_python_konvi "$app_working_name"
2514 # B_CONSOLE_IRC='true' # are there even any python type console irc clients? check.
2515 set_perl_python_konvi "$app_working_name"
2517 # then unset, set unknown data
2519 IRC_CLIENT="Unknown : ${irc_client_path##*/}"
2520 unset IRC_CLIENT_VERSION
2523 if [[ $SHOW_IRC -lt 2 ]];then
2524 unset IRC_CLIENT_VERSION
2527 ## lets look to see if qt4_konvi is the parent. There is no direct way to tell, so lets infer it.
2528 ## because $PPID does not work with qt4_konvi, the above case does not work
2529 if [[ $B_OVERRIDE_FILTER != 'true' ]];then
2530 B_OUTPUT_FILTER='true'
2532 b_qt4_konvi=$( is_this_qt4_konvi )
2533 if [[ $b_qt4_konvi == 'true' ]];then
2535 IRC_CLIENT='Konversation'
2536 IRC_CLIENT_VERSION=" $( konversation -v | gawk '
2538 for ( i=2; i<=NF; i++ ) {
2549 IRC_CLIENT="PPID=\"$PPID\" - empty?"
2550 unset IRC_CLIENT_VERSION
2554 log_function_data "IRC_CLIENT: $IRC_CLIENT :: IRC_CLIENT_VERSION: $IRC_CLIENT_VERSION :: PPID: $PPID"
2557 # args: $1 - app_working_name
2558 set_perl_python_konvi()
2560 if [[ -z $IRC_CLIENT_VERSION ]];then
2561 # this is a hack to try to show konversation if inxi is running but started via /cmd
2562 if [[ -n $( ps aux | grep -i 'konversation' | grep -v 'grep' ) && $B_RUNNING_IN_X == 'true' ]];then
2563 IRC_CLIENT='Konversation'
2564 IRC_CLIENT_VERSION=" $( konversation --version 2>/dev/null | gawk '/^Konversation/ {print $2}' )"
2565 B_CONSOLE_IRC='false'
2567 IRC_CLIENT="Unknown $1 client"
2572 ## try to infer the use of Konversation >= 1.2, which shows $PPID improperly
2573 ## no known method of finding Kovni >= 1.2 as parent process, so we look to see if it is running,
2574 ## and all other irc clients are not running.
2577 local konvi_qt4_client='' konvi_dbus_exist='' konvi_pid='' konvi_home_dir=''
2578 local konvi='' konvi_qt4_ver='' b_is_qt4=''
2580 # fringe cases can throw error, always if untested app, use 2>/dev/null after testing if present
2581 if [[ $B_QDBUS == 'true' ]];then
2582 konvi_dbus_exist=$( qdbus 2>/dev/null | grep "org.kde.konversation" )
2585 if [[ -n $konvi_dbus_exist && -e /usr/share/kde4/apps/konversation ]]; then
2586 konvi_pid=$( ps -A | grep -i 'konversation' )
2587 konvi_pid=$( echo $konvi_pid | gawk '{ print $1 }' )
2588 konvi_home_dir=$( readlink /proc/$konvi_pid/exe )
2589 konvi=$( echo $konvi_home_dir | sed "s/\// /g" )
2592 if [[ ${konvi[2]} == 'konversation' ]];then
2593 konvi_qt4_ver=$( konversation -v | grep -i 'konversation' )
2594 # note: we need to change this back to a single dot number, like 1.3, not 1.3.2
2595 konvi_qt4_client=$( echo "$konvi_qt4_ver" | gawk '{ print $2 }' | cut -d '.' -f 1,2 )
2597 if [[ $konvi_qt4_client > 1.1 ]]; then
2605 log_function_data "b_is_qt4: $b_is_qt4"
2607 ## for testing this module
2608 #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]}"
2611 # This needs some cleanup and comments, not quite understanding what is happening, although generally output is known
2612 # Parse the null separated commandline under /proc/<pid passed in $1>/cmdline
2619 if [[ ! -e /proc/$ppid/cmdline ]];then
2623 ##print_screen_output "Marker"
2624 ##print_screen_output "\$ppid='$ppid' -=- $(< /proc/$ppid/cmdline)"
2626 ## note: need to figure this one out, and ideally clean it up and make it readable
2627 while read -d $'\0' L && [[ $i -lt 32 ]]
2629 A_CMDL[i++]="$L" ## note: make sure this is valid - What does L mean? ##
2630 done < /proc/$ppid/cmdline
2631 ##print_screen_output "\$i='$i'"
2632 if [[ $i -eq 0 ]];then
2633 A_CMDL[0]=$(< /proc/$ppid/cmdline)
2634 if [[ -n ${A_CMDL[0]} ]];then
2639 log_function_data "CMDL_MAX: $CMDL_MAX"
2643 #### -------------------------------------------------------------------
2645 #### -------------------------------------------------------------------
2646 ## create array of sound cards installed on system, and if found, use asound data as well
2650 local i='' alsa_data='' alsa_driver='' device_count='' temp_array=''
2653 # this first step handles the drivers for cases where the second step fails to find one
2654 device_count=$( echo "$Lspci_Data" | grep -iEc '(multimedia audio controller|audio device)' )
2655 if [[ $device_count -eq 1 ]] && [[ $B_ASOUND_DEVICE_FILE == 'true' ]];then
2656 alsa_driver=$( gawk -F ']: ' '
2660 # filtering out modems and usb devices like webcams, this might get a
2661 # usb audio card as well, this will take some trial and error
2662 $0 !~ /modem|usb|webcam/ {
2663 driver=gensub( /^(.+)( - )(.+)$/, "\\1", 1, $2 )
2664 gsub(/^ +| +$/,"",driver)
2665 if ( driver != "" ){
2668 }' $FILE_ASOUND_DEVICE )
2669 log_function_data 'cat' "$FILE_ASOUND_DEVICE"
2672 # this is to safeguard against line breaks from results > 1, which if inserted into following
2673 # array will create a false array entry. This is a hack, not a permanent solution.
2674 alsa_driver=$( echo $alsa_driver )
2675 # now we'll build the main audio data, card name, driver, and port. If no driver is found,
2676 # and if the first method above is not null, and one card is found, it will use that instead.
2677 A_AUDIO_DATA=( $( echo "$Lspci_Data" | gawk -F ': ' -v alsaDriver="$alsa_driver" '
2681 /multimedia audio controller|audio device/ {
2682 audioCard=gensub(/^[0-9a-f:\.]+ [^:]+: (.+)$/,"\\1","g",$0)
2683 # The doublequotes are necessary because of the pipes in the variable.
2684 gsub(/'"$BAN_LIST_NORMAL"'/, "", audioCard)
2685 gsub(/,/, " ", audioCard)
2686 gsub(/^ +| +$/, "", audioCard)
2687 gsub(/ [ \t]+/, " ", audioCard)
2688 aPciBusId[audioCard] = gensub(/(^[0-9a-f:\.]+) [^:]+: .+$/,"\\1","g",$0)
2691 # loop until you get to the end of the data block
2692 while (getline && !/^$/) {
2694 if (/driver in use/) {
2695 drivers[audioCard] = drivers[audioCard] gensub( /(.*): (.*)/ ,"\\2", "g" ,$0 ) ""
2697 else if (/kernel modules:/) {
2698 modules[audioCard] = modules[audioCard] gensub( /(.*): (.*)/ ,"\\2" ,"g" ,$0 ) ""
2701 portsTemp = gensub(/\t*I\/O ports at (.*) \[.*\]/,"\\1","g",$0)
2702 ports[audioCard] = ports[audioCard] portsTemp " "
2717 if (drivers[i] != "") {
2718 useDrivers=drivers[i]
2723 # little trick here to try to catch the driver if there is
2724 # only one card and it was null, from the first test of asound/cards
2725 if (drivers[i] != "") {
2726 useDrivers=drivers[i]
2728 else if ( alsaDriver != "" ) {
2729 useDrivers=alsaDriver
2732 if (ports[i] != "") {
2735 if (modules[i] != "" ) {
2736 useModules = modules[i]
2738 if ( aPciBusId[i] != "" ) {
2739 usePciBusId = aPciBusId[i]
2741 # create array primary item for master array
2742 sub( / $/, "", usePorts ) # clean off trailing whitespace
2743 print a[j] "," useDrivers "," usePorts "," useModules "," usePciBusId
2748 # in case of failure of first check do this instead
2749 if [[ ${#A_AUDIO_DATA[@]} -eq 0 ]] && [[ $B_ASOUND_DEVICE_FILE == 'true' ]];then
2750 A_AUDIO_DATA=( $( gawk -F ']: ' '
2754 $1 !~ /modem/ && $2 !~ /modem/ {
2755 card=gensub( /^(.+)( - )(.+)$/, "\\3", 1, $2 )
2756 driver=gensub( /^(.+)( - )(.+)$/, "\\1", 1, $2 )
2760 }' $FILE_ASOUND_DEVICE ) )
2764 # handle cases where card detection fails, like in PS3, where lspci gives no output, or headless boxes..
2765 if [[ ${#A_AUDIO_DATA[@]} -eq 0 ]];then
2766 A_AUDIO_DATA[0]='Failed to Detect Sound Card!'
2768 temp_array=${A_AUDIO_DATA[@]}
2769 log_function_data "A_AUDIO_DATA: $temp_array"
2773 # alsa usb detection by damentz
2775 get_audio_usb_data()
2778 local usb_proc_file='' array_count='' usb_data='' usb_id='' lsusb_path='' lsusb_data=''
2782 lsusb_path=$( type -p lsusb )
2783 if [[ -n $lsusb_path ]];then
2784 lsusb_data=$( $lsusb_path 2>/dev/null )
2786 log_function_data 'raw' "usb_data:\n$lsusb_data"
2787 if [[ -n $lsusb_data ]];then
2788 # for every sound card symlink in /proc/asound - display information about it
2789 for usb_proc_file in /proc/asound/*
2791 # If the file is a symlink, and contains an important usb exclusive file: continue
2792 if [[ -L $usb_proc_file && -e $usb_proc_file/usbid ]]; then
2793 # find the contents of usbid in lsusb and print everything after the 7th word on the
2794 # corresponding line. Finally, strip out commas as they will change the driver :)
2795 usb_id=$( cat $usb_proc_file/usbid )
2796 usb_data=$( grep "$usb_id" <<< "$lsusb_data" )
2797 if [[ -n $usb_data && -n $usb_id ]];then
2805 gsub( /,/, " ", $0 )
2806 gsub(/'"$BAN_LIST_NORMAL"'/, "", $0)
2807 gsub(/ [ \t]+/, " ", $0)
2808 for ( i=7; i<= NF; i++ ) {
2809 string = string separator $i
2813 print string ",USB Audio,,," $6
2815 }' <<< "$usb_data" )
2817 # this method is interesting, it shouldn't work but it does
2818 #A_AUDIO_DATA=( "${A_AUDIO_DATA[@]}" "$usb_data,USB Audio,," )
2819 # but until we learn why the above worked, I'm using this one, which is safer
2820 if [[ -n $usb_data ]];then
2821 array_count=${#A_AUDIO_DATA[@]}
2822 A_AUDIO_DATA[$array_count]="$usb_data"
2828 temp_array=${A_AUDIO_DATA[@]}
2829 log_function_data "A_AUDIO_DATA: $temp_array"
2834 get_audio_alsa_data()
2837 local alsa_data='' temp_array=''
2839 # now we'll get the alsa data if the file exists
2840 if [[ $B_ASOUND_VERSION_FILE == 'true' ]];then
2849 # some alsa strings have the build date in (...)
2850 # remove trailing . and remove possible second line if compiled by user
2852 gsub( /Driver | [(].*[)]|\.$/,"",$0 )
2854 gsub(/^ +| +$/, "", $0)
2855 gsub(/ [ \t]+/, " ", $0)
2856 sub(/Advanced Linux Sound Architecture/, "ALSA", $0)
2857 if ( $1 == "ALSA" ){
2861 print alsa "," version
2862 }' $FILE_ASOUND_VERSION
2865 log_function_data 'cat' "$FILE_ASOUND_VERSION"
2867 temp_array=${A_ALSA_DATA[@]}
2868 log_function_data "A_ALSA_DATA: $temp_array"
2872 get_console_irc_tty()
2876 if [[ -n ${IRC_CLIENT} ]];then
2877 tty_number=$( ps aux | gawk '
2882 gsub(/[^0-9]/, "", $7)
2886 log_function_data "tty_number: $tty_number"
2891 ## create A_CPU_CORE_DATA, currently with two values: integer core count; core string text
2892 ## return value cpu core count string, this helps resolve the multi redundant lines of old style output
2893 get_cpu_core_count()
2896 if [[ $B_CPUINFO_FILE == 'true' ]]; then
2897 # load the A_CPU_TYPE_PCNT_CCNT core data array
2898 get_cpu_ht_multicore_smp_data
2899 ## Because of the upcoming release of cpus with core counts over 6, a count of cores is given after Deca (10)
2900 # count the number of processors given
2901 local cpu_physical_count=${A_CPU_TYPE_PCNT_CCNT[1]}
2902 local cpu_core_count=${A_CPU_TYPE_PCNT_CCNT[2]}
2903 local cpu_type=${A_CPU_TYPE_PCNT_CCNT[0]}
2905 # match the numberic value to an alpha value
2906 case $cpu_core_count in
2907 1) cpu_alpha_count='Single';;
2908 2) cpu_alpha_count='Dual';;
2909 3) cpu_alpha_count='Triple';;
2910 4) cpu_alpha_count='Quad';;
2911 5) cpu_alpha_count='Penta';;
2912 6) cpu_alpha_count='Hexa';;
2913 7) cpu_alpha_count='Hepta';;
2914 8) cpu_alpha_count='Octa';;
2915 9) cpu_alpha_count='Ennea';;
2916 10) cpu_alpha_count='Deca';;
2917 *) cpu_alpha_count='Multi';;
2919 # create array, core count integer; core count string
2920 # A_CPU_CORE_DATA=( "$cpu_core_count" "$cpu_alpha_count Core$cpu_type" )
2921 A_CPU_CORE_DATA=( "$cpu_physical_count" "$cpu_alpha_count" "$cpu_type" "$cpu_core_count" )
2923 temp_array=${A_CPU_CORE_DATA[@]}
2924 log_function_data "A_CPU_CORE_DATA: $temp_array"
2928 ## main cpu data collector
2932 local i='' j='' cpu_array_nu='' a_cpu_working='' multi_cpu='' bits='' temp_array=''
2934 if [[ $B_CPUINFO_FILE == 'true' ]];then
2935 # stop script for a bit to let cpu slow down before parsing cpu /proc file
2938 A_CPU_DATA=( $( gawk -F': ' '
2942 # TAKE STRONGER NOTE: \t+ does NOT always work, MUST be [ \t]+
2943 # TAKE NOTE: \t+ will work for $FILE_CPUINFO, but SOME ARBITRARY FILE used for TESTING might contain SPACES!
2944 # Therefore PATCH to use [ \t]+ when TESTING!
2945 /^processor[ \t]+:/ {
2949 /^model name|^cpu\t+:/ {
2950 gsub(/'"$BAN_LIST_NORMAL"'/, "", $NF )
2951 gsub(/'"$BAN_LIST_CPU"'/, "", $NF )
2953 gsub(/^ +| +$/, "", $NF)
2954 gsub(/ [ \t]+/, " ", $NF)
2955 cpu[nr, "model"] = $NF
2958 /^cpu MHz|^clock\t+:/ {
2971 gsub(/MHZ/,"",$NF) ## clears out for cell cpu
2972 gsub(/.00[0]+$/,".00",$NF) ## clears out excessive zeros
2973 cpu[nr, "speed"] = $NF
2977 cpu[nr, "cache"] = $NF
2981 cpu[nr, "flags"] = $NF
2985 cpu[nr, "bogomips"] = $NF
2989 gsub(/genuine|authentic/,"",$NF)
2990 cpu[nr, "vendor"] = tolower( $NF )
2994 #if (!nr) { print ",,,"; exit } # <- should this be necessary or should bash handle that
2995 for ( i = 0; i <= nr; i++ ) {
2996 print cpu[i, "model"] "," cpu[i, "speed"] "," cpu[i, "cache"] "," cpu[i, "flags"] "," cpu[i, "bogomips"] "," cpu[nr, "vendor"]
3003 printf("Min:%s%s Max:%s%s\n", min, "Mhz", max, "Mhz")
3006 printf("%s %s\n", max, "Mhz")
3008 }' $FILE_CPUINFO ) )
3009 log_function_data 'cat' "$FILE_CPUINFO"
3012 temp_array=${A_CPU_DATA[@]}
3013 log_function_data "A_CPU_DATA: $temp_array"
3016 # echo getMainCpu: ${[@]}
3019 ## this is for counting processors and finding HT types
3020 get_cpu_ht_multicore_smp_data()
3026 if [[ $B_CPUINFO_FILE == 'true' ]]; then
3027 A_CPU_TYPE_PCNT_CCNT=( $(
3033 num_of_processors = 0
3042 # array of logical processors, both HT and physical
3044 processor_id[iter] = $NF
3046 # array of physical cpus ids
3055 # this will be used to fix an intel glitch if needed, cause, intel
3056 # sometimes reports core id as the same number for each core, 0
3057 # so if cpu cores shows greater value than number of cores, use this
3059 cpu_core_count = $NF
3062 ## Look thru the array and filter same numbers.
3063 ## only unique numbers required
3064 ## this is to get an accurate count
3065 ## we are only concerned with array length
3068 ## count unique processors ##
3069 # note, this fails for intel cpus at times
3070 for ( i in processor_id ) {
3071 procHolder[processor_id[i]] = 1
3073 for ( i in procHolder ) {
3078 ## count unique physical cpus ##
3079 for ( i in cpu_id ) {
3080 cpuHolder[cpu_id[i]] = 1
3082 for ( i in cpuHolder ) {
3087 ## count unique cores ##
3088 for ( i in core_id ) {
3089 coreHolder[core_id[i]] = 1
3091 for ( i in coreHolder ) {
3094 # final check, override the num of cores value if it clearly is wrong
3095 # and use the raw core count and synthesize the total instead of real count
3096 if ( ( num_of_cores == 1 ) && ( cpu_core_count * num_of_cpus > 1 ) ) {
3097 num_of_cores = cpu_core_count * num_of_cpus
3100 ####################################################################
3102 # if > 1 processor && processor id (physical id) == core id then Hyperthreaded (HT)
3103 # if > 1 processor && processor id (physical id) != core id then Multi-Core Processors (MCP)
3104 # if > 1 processor && processor ids (physical id) > 1 then Multiple Processors (SMP)
3105 # if = 1 processor then single core/processor Uni-Processor (UP)
3106 if ( num_of_processors > 1 )
3109 if ( num_of_processors == (num_of_cores * 2))
3113 # non-HT multi-core or HT multi-core
3114 if (( num_of_processors == num_of_cores) ||
3115 ( num_of_cpus < num_of_cores))
3119 # >1 cpu sockets active
3120 if ( num_of_cpus > 1 )
3128 print type " " num_of_cpus " " num_of_cores
3133 temp_array=${A_CPU_TYPE_PCNT_CCNT[@]}
3134 log_function_data "A_CPU_TYPE_PCNT_CCNT: $temp_array"
3138 # Detect desktop environment in use, initial rough logic from: compiz-check
3139 # http://forlong.blogage.de/entries/pages/Compiz-Check
3140 get_desktop_environment()
3144 # set the default, this function only runs in X, if null, don't print data out
3145 local desktop_environment='' xprop_root='' ps_aux=''
3146 local version='' version_data='' toolkit=''
3148 # note, GNOME_DESKTOP_SESSION_ID is deprecated so we'll see how that works out
3149 # https://bugzilla.gnome.org/show_bug.cgi?id=542880
3150 if [[ -n $GNOME_DESKTOP_SESSION_ID ]]; then
3151 version=$( get_de_app_version 'gnome-about' 'gnome' '3' )
3152 if [[ $B_EXTRA_DATA == 'true' ]];then
3153 # this is a hack, and has to be changed with every toolkit version change
3154 toolkit=$( pkg-config --modversion gtk+-3.0 2>/dev/null )
3155 if [[ -z $toolkit ]];then
3156 toolkit=$( pkg-config --modversion gtk+-2.0 2>/dev/null )
3158 if [[ -n $toolkit ]];then
3159 version="$version (Gtk $toolkit)"
3162 desktop_environment="Gnome"
3163 # assume 5 will id the same, why not, no need to update in future
3164 elif [[ $KDE_SESSION_VERSION == '5' ]]; then
3165 version_data=$( kded5 --version 2>/dev/null )
3166 version=$( grep -si '^KDE Development Platform:' <<< "$version_data" | gawk '{print $4}' )
3167 if [[ -z $version ]];then
3170 if [[ $B_EXTRA_DATA == 'true' ]];then
3171 toolkit=$( grep -si '^Qt:' <<< "$version_data" | gawk '{print $2}' )
3172 if [[ -n $toolkit ]];then
3173 version="$version (Qt $toolkit)"
3176 desktop_environment="KDE"
3177 elif [[ $KDE_SESSION_VERSION == '4' ]]; then
3178 version_data=$( kded4 --version 2>/dev/null )
3179 version=$( grep -si '^KDE Development Platform:' <<< "$version_data" | gawk '{print $4}' )
3180 if [[ -z $version ]];then
3183 if [[ $B_EXTRA_DATA == 'true' ]];then
3184 toolkit=$( grep -si '^Qt:' <<< "$version_data" | gawk '{print $2}' )
3185 if [[ -n $toolkit ]];then
3186 version="$version (Qt $toolkit)"
3189 desktop_environment="KDE"
3190 # KDE_FULL_SESSION property is only available since KDE 3.5.5.
3191 # src: http://humanreadable.nfshost.com/files/startkde
3192 elif [[ $KDE_FULL_SESSION == 'true' ]]; then
3193 version_data=$( kded --version 2>/dev/null )
3194 version=$( grep -si '^KDE:' <<< "$version_data" | gawk '{print $2}' )
3195 # version=$( get_de_app_version 'kded' '^KDE:' '2' )
3196 if [[ -z $version ]];then
3199 if [[ $B_EXTRA_DATA == 'true' ]];then
3200 toolkit=$( grep -si '^Qt:' <<< "$version_data" | gawk '{print $2}' )
3201 if [[ -n $toolkit ]];then
3202 version="$version (Qt $toolkit)"
3205 desktop_environment="KDE"
3206 # now that the primary ones have been handled, next is to find the ones with unique
3207 # xprop detections possible
3209 ps_aux="$( ps aux )"
3210 if [[ -n $( type -p xprop ) ]];then
3211 xprop_root="$( xprop -root 2>/dev/null )"
3212 # String: "This is xfdesktop version 4.2.12"
3213 if [[ -n $( grep -Eis '\"xfce4\"' <<< "$xprop_root" ) ]];then
3214 version=$( get_de_app_version 'xfdesktop' 'xfdesktop[[:space:]]version' '5' )
3215 if [[ -z $version ]];then
3218 if [[ $B_EXTRA_DATA == 'true' ]];then
3219 toolkit=$( get_de_app_version 'xfdesktop' 'Built[[:space:]]with[[:space:]]GTK' '4' )
3220 if [[ -n $toolkit ]];then
3221 version="$version (Gtk $toolkit)"
3224 desktop_environment="Xfce"
3225 # when 5 is released, the string may need updating
3226 elif [[ -n $( grep -is '\"xfce5\"' <<< "$xprop_root" ) ]];then
3227 version=$( get_de_app_version 'xfdesktop' 'xfdesktop[[:space:]]version' '5' )
3228 if [[ -z $version ]];then
3231 if [[ $B_EXTRA_DATA == 'true' ]];then
3232 toolkit=$( get_de_app_version 'xfdesktop' 'Built[[:space:]]with[[:space:]]GTK' '4' )
3233 if [[ -n $toolkit ]];then
3234 version="$version (Gtk $toolkit)"
3237 desktop_environment="Xfce"
3238 elif [[ -n $( grep -is 'BLACKBOX_PID' <<< "$xprop_root" ) ]];then
3239 if [[ -n $( grep -is 'fluxbox' <<< "$ps_aux" | grep -v 'grep' ) ]];then
3240 version=$( get_de_app_version 'fluxbox' '^fluxbox' '2' )
3241 desktop_environment='Fluxbox'
3243 desktop_environment='Blackbox'
3245 elif [[ -n $( grep -is 'OPENBOX_PID' <<< "$xprop_root" ) ]];then
3246 version=$( get_de_app_version 'openbox' '^openbox' '2' )
3247 if [[ -n $( grep -is 'lxde' <<< "$ps_aux" | grep -v 'grep' ) ]];then
3248 if [[ -n $version ]];then
3249 version="(Openbox $version)"
3251 desktop_environment='LXDE'
3253 desktop_environment='Openbox'
3255 elif [[ -n $( grep -is 'ICEWM' <<< "$xprop_root" ) ]];then
3256 version=$( get_de_app_version 'icewm' '^icewm' '2' )
3257 desktop_environment='IceWM'
3258 elif [[ -n $( grep -is 'ENLIGHTENMENT' <<< "$xprop_root" ) ]];then
3259 # no -v or --version but version is in xprop -root
3260 # ENLIGHTENMENT_VERSION(STRING) = "Enlightenment 0.16.999.49898"
3261 version=$( grep -is 'ENLIGHTENMENT_VERSION' <<< "$xprop_root" | cut -d '"' -f 2 | gawk '{print $2}' )
3262 desktop_environment='Enlightenment'
3265 # a few manual hacks for things that don't id with xprop, these are just good guesses
3266 # note that gawk is going to exit after first occurance of search string, so no need for extra
3267 if [[ -z $desktop_environment ]];then
3268 if [[ -n $( grep -is 'fvwm-crystal' <<< "$ps_aux" | grep -v 'grep' ) ]];then
3269 version=$( get_de_app_version 'fvwm' '^fvwm' '2' )
3270 desktop_environment='FVWM-Crystal'
3271 elif [[ -n $( grep -is 'fvwm' <<< "$ps_aux" | grep -v 'grep' ) ]];then
3272 version=$( get_de_app_version 'fvwm' '^fvwm' '2' )
3273 desktop_environment='FVWM'
3274 elif [[ -n $( grep -is 'pekwm' <<< "$ps_aux" | grep -v 'grep' ) ]];then
3275 version=$( get_de_app_version 'pekwm' '^pekwm' '3' )
3276 desktop_environment='pekwm'
3277 elif [[ -n $( grep -is 'awesome' <<< "$ps_aux" | grep -v 'grep' ) ]];then
3278 version=$( get_de_app_version 'awesome' '^awesome' '2' )
3279 desktop_environment='Awesome'
3280 elif [[ -n $( grep -is 'scrotwm' <<< "$ps_aux" | grep -v 'grep' ) ]];then
3281 version=$( get_de_app_version 'scrotwm' '^welcome.*scrotwm' '4' )
3282 desktop_environment='Scrotwm' # no --version for this one
3283 elif [[ -n $( grep -Eis '([[:space:]]|/)twm' <<< "$ps_aux" | grep -v 'grep' ) ]];then
3284 desktop_environment='Twm' # no --version for this one
3285 elif [[ -n $( grep -Eis '([[:space:]]|/)dwm' <<< "$ps_aux" | grep -v 'grep' ) ]];then
3286 version=$( get_de_app_version 'dwm' '^dwm' '1' )
3287 desktop_environment='dwm'
3288 elif [[ -n $( grep -is 'wmii' <<< "$ps_aux" | grep -v 'grep' ) ]];then
3289 version=$( get_de_app_version 'wmii' '^wmii' '1' )
3290 desktop_environment='wmii'
3291 elif [[ -n $( grep -Eis '([[:space:]]|/)jwm' <<< "$ps_aux" | grep -v 'grep' ) ]];then
3292 version=$( get_de_app_version 'jwm' '^jwm' '2' )
3293 desktop_environment='JWM'
3297 if [[ -n $version ]];then
3300 echo "$desktop_environment${version}"
3304 # note: gawk doesn't support white spaces in search string, gave errors, so use [[:space:]] instead
3305 # args: $1 - desktop command for --version; $2 - search string; $3 - gawk print number
3306 get_de_app_version()
3308 local version_data='' version='' get_version='--version'
3315 # note, some wm send version info to stderr instead of stdout
3318 version_data="$( $1 $get_version 2>&1 )"
3321 version_data="$( $1 $get_version 2>/dev/null )"
3325 if [[ -n $version_data ]];then
3331 # sample: dwm-5.8.2, ©.. etc, why no space? who knows. Also get rid of v in number string
3332 # xfce, and other, output has , in it, so dump all commas
3333 gsub(/(,|dwm-|wmii-|v|V)/, "",$'$3')
3335 exit # quit after first match prints
3336 }' <<< "$version_data" )
3341 # for more on distro id, please reference this python thread: http://bugs.python.org/issue1322
3342 ## return distro name/id if found
3346 local i='' j='' distro='' distro_file='' a_distro_glob=''
3348 # get the wild carded array of release/version /etc files if present
3351 a_distro_glob=(*[-_]{release,version})
3355 if [[ ${#a_distro_glob[@]} -eq 1 ]];then
3356 distro_file="${a_distro_glob}"
3357 # use the file if it's in the known good lists
3358 elif [[ ${#a_distro_glob[@]} -gt 1 ]];then
3359 for i in $DISTROS_DERIVED $DISTROS_PRIMARY
3361 # Only echo works with ${var[@]}, not print_screen_output() or script_debugger()
3362 # This is a known bug, search for the word "strange" inside comments
3363 # echo "i='$i' a_distro_glob[@]='${a_distro_glob[@]}'"
3364 if [[ " ${a_distro_glob[@]} " == *" $i "* ]];then
3365 # Now lets see if the distro file is in the known-good working-lsb-list
3366 # if so, use lsb-release, if not, then just use the found file
3367 # this is for only those distro's with self named release/version files
3368 # because Mint does not use such, it must be done as below
3369 ## this if statement requires the spaces and * as it is, else it won't work
3371 if [[ " $DISTROS_LSB_GOOD " == *" ${i} "* ]] && [[ $B_LSB_FILE == 'true' ]];then
3372 distro_file='lsb-release'
3380 log_function_data "distro_file: $distro_file"
3381 # first test for the legacy antiX distro id file
3382 if [[ -e /etc/antiX ]];then
3383 distro="$( grep -Eoi 'antix.*\.iso' <<< $( remove_erroneous_chars '/etc/antiX' ) | sed 's/\.iso//' )"
3384 # this handles case where only one release/version file was found, and it's lsb-release. This would
3385 # never apply for ubuntu or debian, which will filter down to the following conditions. In general
3386 # if there's a specific distro release file available, that's to be preferred, but this is a good backup.
3387 elif [[ -n $distro_file && -f $FILE_LSB_RELEASE && " $DISTROS_LSB_GOOD" == *" $distro_file "* ]];then
3388 distro=$( get_distro_lsb_data )
3389 elif [[ $distro_file == 'lsb-release' ]];then
3390 distro=$( get_distro_lsb_data )
3391 # then if the distro id file was found and it's not in the exluded primary distro file list, read it
3392 elif [[ -n $distro_file && -s /etc/$distro_file && " $DISTROS_EXCLUDE_LIST " != *" $distro_file "* ]];then
3393 distro=$( remove_erroneous_chars "/etc/$distro_file" )
3394 # otherwise try the default debian/ubuntu /etc/issue file
3395 elif [[ -f /etc/issue ]];then
3396 # lsb gives more manageable and accurate output than issue, but mint should use issue for now
3397 # some bashism, boolean must be in parenthesis to work correctly, ie [[ $(boolean) ]] not [[ $boolean ]]
3398 if [[ $B_LSB_FILE == 'true' ]] && [[ -z $( grep -i 'mint' /etc/issue ) ]];then
3399 distro=$( get_distro_lsb_data )
3409 gsub(/ [ \t]+/, " ")
3415 if [[ ${#distro} -gt 80 ]] && [[ $B_HANDLE_CORRUPT_DATA != 'true' ]];then
3416 distro="${RED}/etc/${distro_file} corrupted, use -% to override${NORMAL}"
3418 ## note: would like to actually understand the method even if it's not used
3419 # : ${distro:=Unknown distro o_O}
3420 ## test for /etc/lsb-release as a backup in case of failure, in cases where > one version/release file
3421 ## were found but the above resulted in null distro value
3422 if [[ -z $distro ]] && [[ $B_LSB_FILE == 'true' ]];then
3423 distro=$( get_distro_lsb_data )
3425 # now some final null tries
3426 if [[ -z $distro ]];then
3427 # if the file was null but present, which can happen in some cases, then use the file name itself to
3428 # set the distro value. Why say unknown if we have a pretty good idea, after all?
3429 if [[ -n $distro_file ]] && [[ " $DISTROS_DERIVED $DISTROS_PRIMARY " == *" $distro_file "* ]];then
3430 distro=$( sed -E -e 's/[-_]//' -e 's/(release|version)//' <<< $distro_file | sed -E 's/^([a-z])/\u\1/' )
3432 ## finally, if all else has failed, give up
3433 if [[ -z $distro ]];then
3438 # this handles an arch bug where /etc/arch-release is empty and /etc/issue is corrupted
3439 if [[ -n $( grep -i 'arch linux' <<< $distro ) ]];then
3444 log_function_data "distro: $distro"
3448 # args: $1 - optional, app, uses the app test, not being used now
3449 get_distro_lsb_data()
3454 if [[ $B_LSB_FILE == 'true' ]] && [[ $1 != 'app' ]];then
3455 distro=$( gawk -F '=' '
3459 # note: adding the spacing directly to variable to make sure distro output is null if not found
3461 gsub(/^ +| +$/, "", $NF)
3462 # this is needed because grep for "arch" is too loose to be safe
3463 if ( $NF == "arch" ) {
3464 distroId = "Arch Linux"
3466 else if ( $NF != "n/a" ) {
3470 /^DISTRIB_RELEASE/ {
3471 gsub(/^ +| +$/, "", $NF)
3472 if ( $NF != "n/a" ) {
3473 distroRelease = $NF " "
3476 /^DISTRIB_CODENAME/ {
3477 gsub(/^ +| +$/, "", $NF)
3478 if ( $NF != "n/a" ) {
3479 distroCodename = $NF " "
3482 # sometimes some distros cannot do their lsb-release files correctly, so here is
3483 # one last chance to get it right.
3484 /^DISTRIB_DESCRIPTION/ {
3485 gsub(/^ +| +$/, "", $0)
3486 if ( $NF != "n/a" ) {
3487 # slice out the part inside "", like: DISTRIB_DESCRIPTION="Arch Linux"
3488 gsub(/DISTRIB_DESCRIPTION=|"/,"",$0)
3489 distroDescription = $0
3494 if ( distroId == "" && distroRelease == "" && distroCodename == "" && distroDescription != "" ){
3495 fullString = distroDescription
3498 fullString = distroId distroRelease distroCodename
3502 ' $FILE_LSB_RELEASE )
3503 log_function_data 'cat' "$FILE_LSB_RELEASE"
3505 # this is HORRIBLY slow, but I don't know why, it runs fast in shell
3506 # if [[ -n $( type -p lsb_release ) && $1 == 'app' ]];then
3507 # distro=$( echo "$( lsb_release -irc )" | gawk '
3509 # /^Distributor ID/ {
3510 # gsub(/^ +| +$/, "", $NF)
3514 # gsub(/^ +| +$/, "", $NF)
3515 # distroRelease = $NF
3518 # gsub(/^ +| +$/, "", $NF)
3519 # distroCodename = $NF
3522 # print distroId " " distroRelease " (" distroCodename ")"
3527 log_function_data "distro: $distro"
3531 get_gcc_kernel_version()
3533 # note that we use gawk to get the last part because beta, alpha, git versions can be non-numeric
3534 local gccVersion=$( grep -Eio 'gcc[[:space:]]*version[[:space:]]*([^ \t]*)' /proc/version 2>/dev/null | gawk '{print $3}' )
3538 get_gcc_system_version()
3541 local separator='' gcc_installed='' gcc_list='' gcc_others='' temp_array=''
3542 local gcc_version=$(
3543 gcc --version 2>/dev/null | sed -E 's/\([^\)]*\)//g' | gawk '
3553 # can't use xargs -l basename because not all systems support thats
3554 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
3555 gcc_others=$( ls /usr/bin/gcc-* 2>/dev/null )
3556 if [[ -n $gcc_others ]];then
3557 for item in $gcc_others
3559 gcc_installed=$( basename $item | gawk -F '-' '
3563 if [[ -n $gcc_installed && -z $( grep "^$gcc_installed" <<< $gcc_version ) ]];then
3564 gcc_list=$gcc_list$separator$gcc_installed
3570 if [[ -n $gcc_version ]];then
3571 A_GCC_VERSIONS=( "$gcc_version" $gcc_list )
3573 temp_array=${A_GCC_VERSIONS[@]}
3574 log_function_data "A_GCC_VERSIONS: $temp_array"
3579 local gpu_temp='' gpu_fan='' screens='' screen_nu='' gpu_temp_looper=''
3581 # we'll try for nvidia/ati, then add if more are shown
3582 if [[ -n $( type -p nvidia-settings ) ]];then
3583 # first get the number of screens
3584 screens=$( nvidia-settings -q screens | gawk '
3586 screens=screens gensub(/(.*)(:[0-9]\.[0-9])(.*)/, "\\2", "1", $0) " "
3592 # now we'll get the gpu temp for each screen discovered. The print out function
3593 # will handle removing screen data for single gpu systems
3594 for screen_nu in $screens
3596 gpu_temp_looper=$( nvidia-settings -c $screen_nu -q GPUCoreTemp | gawk -F ': ' '
3602 /Attribute (.*)[0-9]+\.$/ {
3604 if ( $2 ~ /^[0-9]+$/ ) {
3605 gpuTemp=gpuTemp $2 "C "
3612 screen_nu=$( cut -d ':' -f 2 <<< $screen_nu )
3613 gpu_temp="$gpu_temp$screen_nu:$gpu_temp_looper "
3615 elif [[ -n $( type -p aticonfig ) ]];then
3616 # gpu_temp=$( aticonfig --adapter=0 --od-gettemperature | gawk -F ': ' '
3617 gpu_temp=$( aticonfig --adapter=all --od-gettemperature | gawk -F ': ' '
3623 /Sensor (.*)[0-9\.]+ / {
3624 gpuTempWorking=gensub(/(.*) ([0-9\.]+) (.*)/, "\\2", "1", $2)
3625 if ( gpuTempWorking ~ /^[0-9\.]+$/ ) {
3626 gpuTemp=gpuTemp gpuTempWorking "C "
3633 # this handles some newer cases of free driver temp readouts, will require modifications as
3634 # more user data appears.
3635 elif [[ -n $Sensors_Data ]];then
3643 /^('"$SENSORS_GPU_SEARCH"')-pci/ {
3644 while ( getline && !/^$/ ) {
3646 sub(/^[[:alnum:]]*.*:/, "", $0 ) # clear out everything to the :
3647 gsub(/[\+ \t°]/, "", $1) # ° is a special case, like a space for gawk
3648 gpuTemp=gpuTemp separator $1
3655 }' <<< "$Sensors_Data"
3659 if [[ -n $gpu_temp ]];then
3664 ## for possible future data, not currently used
3665 get_graphics_agp_data()
3670 if [[ $B_MODULES_FILE == 'true' ]];then
3671 ## not used currently
3672 agp_module=$( gawk '
3673 /agp/ && !/agpgart/ && $3 > 0 {
3674 print(gensub(/(.*)_agp.*/,"\\1","g",$1))
3676 log_function_data 'cat' "$FILE_MODULES"
3678 log_function_data "agp_module: $agp_module"
3682 ## create array of gfx cards installed on system
3683 get_graphics_card_data()
3686 local i='' temp_array=''
3689 A_GFX_CARD_DATA=( $( gawk -F': ' '
3694 /vga compatible controller/ {
3695 gsub(/'"$BAN_LIST_NORMAL"'/, "", $NF)
3697 gsub(/^ +| +$/, "", $NF)
3698 gsub(/ [ \t]+/, " ", $NF)
3699 busId=gensub(/^([0-9a-f:\.]+) (.+)$/,"\\1","",$1)
3701 }' <<< "$Lspci_Data" ) )
3703 # for (( i=0; i < ${#A_GFX_CARD_DATA[@]}; i++ ))
3705 # A_GFX_CARD_DATA[i]=$( sanitize_characters BAN_LIST_NORMAL "${A_GFX_CARD_DATA[i]}" )
3708 # GFXMEM is UNUSED at the moment, because it shows AGP aperture size, which is not necessarily equal to GFX memory..
3709 # GFXMEM="size=[$(echo "$Lspci_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]"
3710 temp_array=${A_GFX_CARD_DATA[@]}
3711 log_function_data "A_GFX_CARD_DATA: $temp_array"
3715 get_graphics_driver()
3719 # list is from sgfxi plus non-free drivers
3720 local driver_list='apm|ark|ati|chips|cirrus|cyrix|fbdev|fglrx|glint|i128|i740|intel|i810|imstt|mach64|mga|neomagic|nsc|nv|nvidia|openchrome|nouveau|radeon|radeonhd|rendition|s3|s3virge|savage|siliconmotion|sis|sisusb|tdfx|tga|trident|tseng|unichrome|vboxvideo|vesa|vga|via|voodoo|vmware|v4l'
3721 local driver='' driver_string='' xorg_log_data='' status='' temp_array=''
3723 if [[ $B_XORG_LOG == 'true' ]];then
3724 A_GRAPHIC_DRIVERS=( $(
3729 /[[:space:]]Loading.*('"$driver_list"')_drv.so$/ {
3730 driver=gensub(/.*[[:space:]]Loading.*('"$driver_list"')_drv.so/, "\\1", 1, $0 )
3731 # we get all the actually loaded drivers first, we will use this to compare the
3732 # failed/unloaded, which have not always actually been truly loaded
3733 aDrivers[driver]="loaded"
3735 /Unloading[[:space:]].*('"$driver_list"')(|_drv.so)$/ {
3736 driver=gensub(/(.*)Unloading[[:space:]].*('"$driver_list"')(|_drv.so)$/, "\\2", 1, $0 )
3737 # we need to make sure that the driver has already been truly loaded, not just discussed
3738 if ( driver in aDrivers ) {
3739 aDrivers[driver]="unloaded"
3742 /Failed.*('"$driver_list"')_drv.so|Failed.*\"('"$driver_list"')\"/ {
3743 driver=gensub(/(.*)Failed.*('"$driver_list"')_drv.so/, "\\2", 1, $0 )
3744 if ( driver == $0 ) {
3745 driver=gensub(/(.*)Failed.*\"('"$driver_list"')\".*|fred/, "\\2", 1, $0 )
3747 # we need to make sure that the driver has already been truly loaded, not just discussed
3748 if ( driver != $0 && driver in aDrivers ) {
3749 aDrivers[driver]="failed"
3753 for ( driver in aDrivers ) {
3754 print driver "," aDrivers[driver]
3759 temp_array=${A_GRAPHIC_DRIVERS[@]}
3760 log_function_data "A_GRAPHIC_DRIVERS: $temp_array"
3765 ## create array of glx data
3766 get_graphics_glx_data()
3770 if [[ $B_SHOW_X_DATA == 'true' && $B_ROOT != 'true' ]];then
3772 A_GLX_DATA=( $( glxinfo | gawk -F ': ' '
3773 # note: function declarations go before BEGIN? It appears so, confirm.
3774 # the real question here though is why this function is even here, seems
3775 # just to be a complicated way to pack/print a variable, but maybe the
3776 # original idea was to handle > 1 cases of detections I guess
3777 function join( arr, sep ) {
3793 gsub(/'"$BAN_LIST_NORMAL"'/, "", $2)
3794 gsub(/ [ \t]+/, " ", $2) # get rid of the created white spaces
3795 gsub(/^ +| +$/, "", $2)
3796 if ( $2 ~ /mesa/ ) {
3798 # if ( $2 ~ / r[3-9][0-9][0-9] / ) {
3800 # this counter failed in one case, a bug, and is not needed now
3808 # dropping all conditions from this test to just show full mesa information
3809 # there is a user case where not f and mesa apply, atom mobo
3810 # /opengl version/ && ( f || $2 !~ /mesa/ ) {
3812 # fglrx started appearing with this extra string, does not appear to communicate anything of value
3813 sub(/Compatibility Profile Context/, "- CPC", $2 )
3814 gsub(/ [ \t]+/, " ", $2) # get rid of the created white spaces
3815 gsub(/^ +| +$/, "", $2)
3818 /direct rendering/ {
3822 printf( "%s\n%s\n%s\n", join( a, ", " ), join( b, ", " ), join( c, ", " ) )
3826 # GLXR=$(glxinfo | gawk -F ': ' 'BEGIN {IGNORECASE=1} /opengl renderer/ && $2 !~ /mesa/ {seen[$2]++} END {for (i in seen) {printf("%s ",i)}}')
3827 # GLXV=$(glxinfo | gawk -F ': ' 'BEGIN {IGNORECASE=1} /opengl version/ && $2 !~ /mesa/ {seen[$2]++} END {for (i in seen) {printf("%s ",i)}}')
3829 temp_array=${A_GLX_DATA[@]}
3830 log_function_data "A_GLX_DATA: $temp_array"
3834 ## return screen resolution / tty resolution
3835 get_graphics_res_data()
3838 local screen_resolution='' xdpy_data='' screens_count=0
3840 if [[ $B_SHOW_X_DATA == 'true' && $B_ROOT != 'true' ]];then
3841 # Added the two ?'s , because the resolution is now reported without spaces around the 'x', as in
3842 # 1400x1050 instead of 1400 x 1050. Change as of X.org version 1.3.0
3843 xdpy_data="$( xdpyinfo )"
3844 xdpy_count=$( grep -c 'dimensions' <<< "$xdpy_data" )
3845 # we get a bit more info from xrandr than xdpyinfo, but xrandr fails to handle
3846 # multiple screens from different video cards
3847 if [[ $xdpy_count -eq 1 ]];then
3848 screen_resolution=$( xrandr | gawk '
3850 res[++m] = gensub(/^.* ([0-9]+) ?x ?([0-9]+)[_ ].* ([0-9\.]+)\*.*$/,"\\1x\\2@\\3hz","g",$0)
3854 if (res[n] ~ /^[[:digit:]]+x[[:digit:]]+/) {
3855 line = line ? line ", " res[n] : res[n]
3863 if [[ -z $screen_resolution || $xdpy_count -gt 1 ]];then
3864 screen_resolution=$( gawk '
3871 screens = screens separator # first time, this is null, next, has comma last
3872 screens = screens $2 # then tack on the new value for nice comma list
3877 }' <<< "$xdpy_data" )
3880 screen_resolution=$( stty -F $( readlink /proc/$PPID/fd/0 ) size | gawk '{
3884 echo "$screen_resolution"
3885 log_function_data "screen_resolution: $screen_resolution"
3889 ## create array of x vendor/version data
3890 get_graphics_x_data()
3893 local x_vendor='' x_version='' temp_array='' xdpy_info='' a_x_working=''
3895 if [[ $B_SHOW_X_DATA == 'true' && $B_ROOT != 'true' ]];then
3896 # X vendor and version detection.
3897 # new method added since radeon and X.org and the disappearance of <X server name> version : ...etc
3898 # Later on, the normal textual version string returned, e.g. like: X.Org version: 6.8.2
3899 # A failover mechanism is in place. (if $x_version is empty, the release number is parsed instead)
3900 # xdpy_info="$( xdpyinfo )"
3902 a_x_working=( $( xdpyinfo | gawk -F': +' '
3910 gsub(/the|inc|foundation|project|corporation/, "", $2)
3912 gsub(/^ +| +$/, "", $2)
3913 gsub(/ [ \t]+/, " ", $2)
3919 /vendor release number/ {
3925 print vendorString "," version "," vendorRelease
3927 x_vendor=${a_x_working[0]}
3928 x_version=${a_x_working[1]}
3930 # this gives better output than the failure last case, which would only show:
3931 # for example: X.org: 1.9 instead of: X.org: 1.9.0
3932 if [[ -z $x_version ]];then
3933 x_version=$( get_graphics_x_version )
3935 if [[ -z $x_version ]];then
3936 x_version=${a_x_working[2]}
3939 # some distros, like fedora, report themselves as the xorg vendor, so quick check
3940 # here to make sure the vendor string includes Xorg in string
3941 if [[ -z $( grep -E '(X|xorg|x\.org)' <<< $x_vendor ) ]];then
3942 x_vendor="$x_vendor X.org"
3945 A_X_DATA[0]="$x_vendor"
3946 A_X_DATA[1]="$x_version"
3948 x_version=$( get_graphics_x_version )
3949 if [[ -n $x_version ]];then
3951 A_X_DATA[0]="$x_vendor"
3952 A_X_DATA[1]="$x_version"
3955 temp_array=${A_X_DATA[@]}
3956 log_function_data "A_X_DATA: $temp_array"
3960 # if other tests fail, try this one, this works for root, out of X also
3961 get_graphics_x_version()
3964 local x_version='' x_data=''
3965 # note that some users can have /usr/bin/Xorg but not /usr/bin/X
3966 if [[ -n $( type -p X ) ]];then
3967 # note: MUST be this syntax: X -version 2>&1
3968 # otherwise X -version overrides everything and this comes out null.
3969 # two knowns id strings: X.Org X Server 1.7.5 AND X Window System Version 1.7.5
3970 #X -version 2>&1 | gawk '/^X Window System Version/ { print $5 }'
3971 x_data="$( X -version 2>&1 )"
3972 elif [[ -n $( type -p Xorg ) ]];then
3973 x_data="$( Xorg -version 2>&1)"
3975 if [[ -n $x_data ]];then
3985 /^X Window System Version/ {
3992 log_function_data " x_version: $x_version"
3996 # this gets just the raw data, total space/percent used and disk/name/per disk capacity
3997 get_hdd_data_basic()
4000 local hdd_used='' temp_array=''
4001 local hdd_data="$( df -P --exclude-type=aufs --exclude-type=squashfs --exclude-type=unionfs --exclude-type=devtmpfs --exclude-type=tmpfs --exclude-type=iso9660 )"
4002 log_function_data 'raw' "hdd_data:\n$hdd_data"
4004 hdd_used=$( echo "$hdd_data" | gawk '
4005 # also handles odd dm-1 type, from lvm
4006 /^\/dev\/(mapper\/|[hsv]d[a-z][0-9]+|dm[-]?[0-9]+)/ {
4007 # this handles the case where the first item is too long
4008 # and makes df wrap output to next line, so here we advance
4009 # it to the next line for that single case. Using df -P should
4010 # make this unneeded but leave it in just in case
4011 if ( NF < 5 && $0 !~ /.*%/ ) {
4014 # if the first item caused a wrap, use one less than standard
4015 # testing for the field with % in it, ie: 34%, then go down from there
4016 # this also protects against cases where the mount point has a space in the
4017 # file name, thus breaking going down from $NF directly.
4021 # otherwise use standard
4022 else if ( $5 ~ /.*%/ ) {
4025 # and if this is not detected, give up, we need user data to debug
4034 if [[ -z $hdd_used ]];then
4037 log_function_data "hdd_used: $hdd_used"
4038 # create the initial array strings:
4039 # disk-dev, capacity, name, usb or not
4040 # final item is the total of the disk
4043 if [[ $B_PARTITIONS_FILE == 'true' ]];then
4045 gawk -v hddused="$hdd_used" '
4047 driveSize = $(NF - 1)*1024/1000**3
4048 gsub(/,/, " ", driveSize)
4049 gsub(/^ +| +$/, "", driveSize)
4050 printf( $NF",%.1fGB,,\n", driveSize )
4052 # See http://lanana.org/docs/device-list/devices-2.6+.txt for major numbers used below
4053 # $1 ~ /^(3|22|33|8)$/ && $2 % 16 == 0 {
4056 # special case from this data: 8 0 156290904 sda
4057 $1 ~ /^(3|22|33|8)$/ && $NF ~ /[hsv]d[a-z]$/ && ( $2 % 16 == 0 || $2 % 16 == 8 ) {
4062 size = size*1024/1000**3 # calculate size in GB size
4063 workingUsed = hddused*1024/1000**3 # calculate workingUsed in GB used
4064 # this handles a special case with livecds where no hdd_used is detected
4065 if ( size > 0 && hddused == "na" ) {
4066 size = sprintf( "%.1f", size )
4069 else if ( size > 0 && workingUsed > 0 ) {
4070 diskUsed = workingUsed*100/size # calculate used percentage
4071 diskUsed = sprintf( "%.1f", diskUsed )
4072 size = sprintf( "%.1f", size )
4073 print size "GB," diskUsed "% used"
4076 print "NA,-" # print an empty array, this will be further handled in the print out function
4078 }' $FILE_PARTITIONS ) )
4079 log_function_data 'cat' "$FILE_PARTITIONS"
4082 temp_array=${A_HDD_DATA[@]}
4083 log_function_data "A_HDD_DATA: $temp_array"
4087 ## fills out the A_HDD_DATA array with disk names
4088 get_hard_drive_data_advanced()
4091 local a_temp_working='' a_temp_scsi='' temp_holder='' temp_name='' i='' j=''
4092 local sd_ls_by_id='' ls_disk_by_id='' usb_exists='' temp_array=''
4094 ## check for all ide type drives, non libata, only do it if hdx is in array
4095 ## this is now being updated for new /sys type paths, this may handle that ok too
4096 if [[ -n $( grep -E 'hd[a-z]' <<< ${A_HDD_DATA[@]} ) ]];then
4097 # remember, we're using the last array item to store the total size of disks
4098 for (( i=0; i < ${#A_HDD_DATA[@]} - 1; i++ ))
4101 a_temp_working=( ${A_HDD_DATA[i]} )
4103 if [[ -n $( grep -E '^hd[a-z]' <<< ${a_temp_working[0]} ) ]];then
4104 if [[ -e /proc/ide/${a_temp_working[0]}/model ]];then
4105 a_temp_working[2]="$( remove_erroneous_chars /proc/ide/${a_temp_working[0]}/model )"
4107 a_temp_working[2]="Name n/a"
4109 # these loops are to easily extend the cpu array created in the gawk script above with more fields per cpu.
4110 for (( j=0; j < ${#a_temp_working[@]}; j++ ))
4112 if [[ $j -gt 0 ]];then
4113 A_HDD_DATA[i]="${A_HDD_DATA[i]},${a_temp_working[$j]}"
4115 A_HDD_DATA[i]="${a_temp_working[$j]}"
4122 ## then handle libata names
4123 # first get the ata device names, put them into an array
4125 if [[ $B_SCSI_FILE == 'true' ]]; then
4126 a_temp_scsi=( $( gawk '
4136 if (b[i] ~ / *type: *direct-access.*/) {
4137 #c=gensub(/^ *vendor: (.+) +model: (.+) +rev: (.+)$/,"\\1 \\2 \\3","g",a[i])
4138 #c=gensub( /^ *vendor: (.+) +model: (.+) +rev:.*$/,"\\1 \\2","g",a[i] )
4139 # the vendor: string is useless, and is a bug, ATA is not a vendor for example
4140 c=gensub( /^ *vendor: (.+) +model: (.+) +rev:.*$/, "\\2", "g", a[i] )
4142 gsub(/^ +| +$/, "", c)
4143 gsub(/ [ \t]+/, " ", c)
4145 # we actually want this data, so leaving this off for now
4146 # if (c ~ /\<flash\>|\<pendrive\>|memory stick|memory card/) {
4153 log_function_data 'cat' "$FILE_SCSI"
4157 ## then we'll loop through that array looking for matches.
4158 if [[ -n $( grep -E 'sd[a-z]' <<< ${A_HDD_DATA[@]} ) ]];then
4159 # first pack the main ls variable so we don't have to keep using ls /dev...
4160 ls_disk_by_id="$( ls -l /dev/disk/by-id )"
4161 for (( i=0; i < ${#A_HDD_DATA[@]} - 1; i++ ))
4163 if [[ -n $( grep -E '^sd[a-z]' <<< ${A_HDD_DATA[$i]} ) ]];then
4165 a_temp_working=( ${A_HDD_DATA[$i]} )
4167 # /sys/block/[sda,hda]/device/model
4168 # this is handles the new /sys data types first
4169 if [[ -e /sys/block/${a_temp_working[0]}/device/model ]];then
4170 temp_name="$( remove_erroneous_chars /sys/block/${a_temp_working[0]}/device/model )"
4171 temp_name=$( tr ' ' '_' <<< $temp_name | cut -d '-' -f 1 )
4172 elif [[ ${#a_temp_scsi[@]} -gt 0 ]];then
4173 for (( j=0; j < ${#a_temp_scsi[@]}; j++ ))
4175 ## ok, ok, it's incomprehensible, search /dev/disk/by-id for a line that contains the
4176 # discovered disk name AND ends with the correct identifier, sdx
4177 # get rid of whitespace for some drive names and ids, and extra data after - in name
4178 temp_name=$( tr ' ' '_' <<< ${a_temp_scsi[$j]} | cut -d '-' -f 1 )
4179 sd_ls_by_id=$( grep -Em1 ".*$temp_name.*${a_temp_working[0]}$" <<< "$ls_disk_by_id" )
4181 if [[ -n $sd_ls_by_id ]];then
4182 temp_name=${a_temp_scsi[$j]}
4185 # test to see if we can get a better name output when null
4186 if [[ -n $temp_name ]];then
4187 temp_name=$temp_name
4193 if [[ -z $temp_name ]];then
4194 temp_name="Name n/a"
4196 usb_exists=$( grep -Em1 "usb-.*$temp_name.*${a_temp_working[0]}$" <<< "$ls_disk_by_id" )
4197 if [[ -n $usb_exists ]];then
4198 a_temp_working[3]='USB'
4201 a_temp_working[2]=$temp_name
4202 # these loops are to easily extend the cpu array created in the gawk script above with more fields per cpu.
4203 for (( j=0; j < ${#a_temp_working[@]}; j++ ))
4205 if [[ $j -gt 0 ]];then
4206 A_HDD_DATA[i]="${A_HDD_DATA[i]},${a_temp_working[$j]}"
4208 A_HDD_DATA[i]="${a_temp_working[$j]}"
4213 unset ls_disk_by_id # and then let's dump the data we don't need
4215 temp_array=${A_HDD_DATA[@]}
4216 log_function_data "A_HDD_DATA: $temp_array"
4220 # a few notes, normally hddtemp requires root, but you can set user rights in /etc/sudoers.
4221 # args: $1 - /dev/<disk> to be tested for
4225 local hdd_temp='' sudo_command=''
4227 if [[ $B_HDDTEMP_TESTED != 'true' ]];then
4228 B_HDDTEMP_TESTED='true'
4229 HDDTEMP_PATH=$( type -p hddtemp )
4231 if [[ $B_SUDO_TESTED != 'true' ]];then
4232 B_SUDO_TESTED='true'
4233 SUDO_PATH=$( type -p sudo )
4236 if [[ -n $HDDTEMP_PATH && -n $1 ]];then
4237 # only use sudo if not root, -n option requires sudo -V 1.7 or greater. sudo will just error out
4238 # which is the safest course here for now, otherwise that interactive sudo password thing is too annoying
4239 # important: -n makes it non interactive, no prompt for password
4240 if [[ $B_ROOT != 'true' && -n $SUDO_PATH ]];then
4241 sudo_command='sudo -n '
4243 # this will fail if regular user and no sudo present, but that's fine, it will just return null
4244 hdd_temp=$( eval $sudo_command $HDDTEMP_PATH -nq -u C $1 )
4245 if [[ -n $hdd_temp && -n $( grep -E '^([0-9\.]+)$' <<< $hdd_temp ) ]];then
4255 local lspci_data="$( lspci -v | gawk '{
4256 gsub(/\(prog-if[^)]*\)/,"")
4257 sub(/^0000:/, "", $0) # seen case where the 0000: is prepended, rare, but happens
4262 log_function_data 'raw' "lspci_data:\n$lspci_data"
4269 local temp_array='' separator='' id_file='' file_data='' array_string=''
4270 local id_dir='/sys/class/dmi/id/' dmi_name='' dmi_data=''
4271 local machine_files="
4272 sys_vendor product_name product_version product_serial product_uuid
4273 board_vendor board_name board_version board_serial
4274 bios_vendor bios_version bios_date
4277 system-manufacturer system-product-name system-version system-serial-number system-uuid
4278 baseboard-manufacturer baseboard-product-name baseboard-version baseboard-serial-number
4279 bios-vendor bios-version bios-release-date
4281 if [[ $B_EXTRA_EXTRA_DATA == 'true' ]];then
4282 machine_files="$machine_files
4283 chassis_vendor chassis_type chassis_version chassis_serial
4285 dmi_names="$dmi_names
4286 chassis-manufacturer chassis-type chassis-version chassis-serial-number
4289 if [[ -d $id_dir ]];then
4290 for id_file in $machine_files
4293 if [[ -r $id_dir$id_file ]];then
4299 gsub(/'"$BAN_LIST_NORMAL"'/, "", $0)
4301 # yes, there is a typo in a user data set, unknow
4302 # Base Board Version|Base Board Serial Number
4303 # Chassis Manufacturer|Chassis Version|Chassis Serial Number
4304 # System manufacturer|System Product Name|System Version
4305 # To Be Filled By O.E.M.
4306 sub(/^Base Board .*|^Chassis .*|.*O\.E\.M\..*|.*OEM.*|^Not .*|^System .*|.*unknow.*|.*N\/A.*|none|^To be filled.*/, "", $0)
4307 gsub(/bios|acpi/, "", $0)
4308 sub(/http:\/\/www.abit.com.tw\//, "Abit", $0)
4309 gsub(/^ +| +$/, "", $0)
4310 gsub(/ [ \t]+/, " ", $0)
4312 }' < $id_dir$id_file
4315 array_string="$array_string$separator$file_data"
4319 if [[ -n $( type -p dmidecode 2>/dev/null ) && -n $( dmidecode 2>/dev/null ) ]];then
4320 if [[ $B_ROOT == 'true' ]];then
4321 # this handles very old systems, like Lenny 2.6.26, with dmidecode, but no data
4322 if [[ -z $( dmidecode 2>/dev/null | grep -i 'no smbios or dmi' ) ]];then
4323 array_string='dmidecode-no-smbios-dmi-data'
4325 for dmi_name in $dmi_names
4327 # echo "$dmi_name" >&2
4329 dmi_data=$( dmidecode -s $dmi_name | gawk '
4334 gsub(/'"$BAN_LIST_NORMAL"'/, "", $0)
4336 # yes, there is a typo in a user data set, unknow
4337 # Base Board Version|Base Board Serial Number
4338 # Chassis Manufacturer|Chassis Version|Chassis Serial Number
4339 # System manufacturer|System Product Name|System Version
4340 # To Be Filled By O.E.M.
4341 sub(/^Base Board .*|^Chassis .*|.*O\.E\.M\..*|.*OEM.*|^Not .*|^System .*|.*unknow.*|.*N\/A.*|none|^To be filled.*/, "", $0)
4342 gsub(/bios|acpi/, "", $0)
4343 sub(/http:\/\/www.abit.com.tw\//, "Abit", $0)
4344 gsub(/^ +| +$/, "", $0)
4345 gsub(/ [ \t]+/, " ", $0)
4348 array_string="$array_string$separator$dmi_data"
4353 array_string='dmidecode-non-root-user'
4358 A_MACHINE_DATA=( $array_string )
4360 temp_array=${A_MACHINE_DATA[@]}
4361 log_function_data "A_MACHINE_DATA: $temp_array"
4365 ## return memory used/installed
4370 if [[ $B_MEMINFO_FILE == 'true' ]];then
4375 /^(MemFree|Buffers|Cached):/ {
4380 printf("%.1f/%.1fMB\n", used/1024, tot/1024)
4382 log_function_data 'cat' "$FILE_MEMINFO"
4385 log_function_data "memory: $memory"
4389 # process and return module version data
4390 get_module_version_number()
4393 local module_version=''
4395 if [[ $B_MODINFO_TESTED != 'true' ]];then
4396 B_MODINFO_TESTED='true'
4397 MODINFO_PATH=$( type -p modinfo )
4400 if [[ -n $MODINFO_PATH ]];then
4401 module_version=$( $MODINFO_PATH $1 2>/dev/null | gawk '
4407 gsub(/^ +| +$/, "", $2)
4408 gsub(/ [ \t]+/, " ", $2)
4414 echo "$module_version"
4415 log_function_data "module_version: $module_version"
4419 ## create array of network cards
4420 get_networking_data()
4424 local B_USB_NETWORKING='false' temp_array=''
4428 echo "$Lspci_Data" | gawk '
4431 counter=0 # required to handle cases of > 1 instance of the same chipset
4433 /^[0-9a-f:\.]+ (ethernet|network) (controller|bridge)/ || /^[0-9a-f:\.]+ [^:]+: .*(ethernet|network).*$/ {
4434 nic=gensub(/^[0-9a-f:\.]+ [^:]+: (.+)$/,"\\1","g",$0)
4435 gsub(/realtek semiconductor/, "Realtek", nic)
4436 gsub(/davicom semiconductor/, "Davicom", nic)
4437 # The doublequotes are necessary because of the pipes in the variable.
4438 gsub(/'"$BAN_LIST_NORMAL"'/, "", nic)
4440 gsub(/^ +| +$/, "", nic)
4441 gsub(/ [ \t]+/, " ", nic)
4442 # construct a unique string ending for each chipset detected, this allows for
4443 # multiple instances of the same exact chipsets, ie, dual gigabit
4444 nic = nic "~~" counter++
4445 aPciBusId[nic] = gensub(/(^[0-9a-f:\.]+) [^:]+: .+$/,"\\1","g",$0)
4446 # I do not understand why incrementing a string index makes sense?
4448 while ( getline && !/^$/ ) {
4451 ports[nic] = ports[nic] $4 " "
4453 if ( /driver in use/ ) {
4454 drivers[nic] = drivers[nic] gensub( /(.*): (.*)/ ,"\\2" ,"g" ,$0 ) ""
4456 else if ( /kernel modules/ ) {
4457 modules[nic] = modules[nic] gensub( /(.*): (.*)/ ,"\\2" ,"g" ,$0 ) ""
4470 a[j] = eth[i] "x " i
4475 ## note: this loses the plural ports case, is it needed anyway?
4476 if ( ports[i] != "" ) {
4479 if ( drivers[i] != "" ) {
4480 useDrivers = drivers[i]
4482 if ( modules[i] != "" ) {
4483 useModules = modules[i]
4485 if ( aPciBusId[i] != "" ) {
4486 usePciBusId = aPciBusId[i]
4488 # create array primary item for master array
4489 # and strip out the counter again, this handled dual cards with same chipset
4490 sub( /~~[0-9]+$/, "", a[j] )
4491 sub( / $/, "", usePorts ) # clean off trailing whitespace
4492 print a[j] "," useDrivers "," usePorts "," useModules, "," usePciBusId
4498 get_networking_usb_data
4499 if [[ $B_SHOW_ADVANCED_NETWORK == 'true' || $B_USB_NETWORKING == 'true' ]];then
4500 get_network_advanced_data
4502 temp_array=${A_NETWORK_DATA[@]}
4503 log_function_data "A_NETWORK_DATA: $temp_array"
4508 get_network_advanced_data()
4511 local a_network_adv_working='' if_path='' working_path='' working_uevent_path='' dir_path=''
4512 local if_id='' speed='' duplex='' mac_id='' oper_state=''
4513 local usb_data='' usb_vendor='' usb_product='' product_path='' driver_test=''
4515 for (( i=0; i < ${#A_NETWORK_DATA[@]}; i++ ))
4518 a_network_adv_working=( ${A_NETWORK_DATA[i]} )
4519 # reset these every go round
4527 if [[ -z $( grep '^usb-' <<< ${a_network_adv_working[4]} ) ]];then
4528 # note although this may exist technically don't use it, it's a virtual path
4529 # and causes weird cat errors when there's a missing file as well as a virtual path
4530 # /sys/bus/pci/devices/0000:02:02.0/net/eth1
4531 # real paths are: /sys/devices/pci0000:00/0000:00:1e/0/0000:02:02.0/net/eth1/uevent
4532 # and on older debian kernels: /sys/devices/pci0000:00/0000:02:02.0/net:eth1/uevent
4533 # but broadcom shows this sometimes:
4534 # /sys/devices/pci0000:00/0000:00:03.0/0000:03:00.0/ssb0:0/uevent:['DRIVER=b43', 'MODALIAS=ssb:v4243id0812rev0D']:
4535 working_path="/sys/bus/pci/devices/0000:${a_network_adv_working[4]}"
4536 # now we want the real one, that xiin also displays, without symbolic links.
4537 if [[ -e $working_path ]];then
4538 working_path=$( readlink -f $working_path 2>/dev/null )
4539 # sometimes there is another directory between the path and /net
4540 if [[ ! -e $working_path/net ]];then
4541 # using find here, probably will need to also use it in usb part since the grep
4542 # method seems to not be working now. Slice off the rest, which leaves the basic path
4543 working_path=$( find $working_path/*/net/*/uevent 2>/dev/null | \
4547 # working_path=$( ls /sys/devices/pci*/*/0000:${a_network_adv_working[4]}/net/*/uevent )
4549 # slice off the usb- part
4550 usb_data=$( cut -d '-' -f 2-4 <<< ${a_network_adv_working[4]} )
4551 usb_vendor=$( cut -d ':' -f 1 <<< $usb_data )
4552 usb_product=$( cut -d ':' -f 2 <<< $usb_data )
4553 # this grep returns the path plus the contents of the file, with a colon separator, so slice that off
4554 # /sys/devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/idVendor
4555 working_path=$( grep -s "$usb_vendor" /sys/devices/pci*/*/usb*/*/*/idVendor | \
4556 sed -e "s/idVendor:$usb_vendor//" -e '/driver/d' )
4557 # try an alternate path if first one doesn't work
4558 # /sys/devices/pci0000:00/0000:00:0b.1/usb1/1-1/idVendor
4559 if [[ -z $working_path ]];then
4560 working_path=$( grep -s "$usb_vendor" /sys/devices/pci*/*/usb*/*/idVendor | \
4561 sed -e "s/idVendor:$usb_vendor//" -e '/driver/d' )
4562 product_path=$( grep -s "$usb_product" /sys/devices/pci*/*/usb*/*/idProduct | \
4563 sed -e "s/idProduct:$usb_product//" -e '/driver/d' )
4565 product_path=$( grep -s "$usb_product" /sys/devices/pci*/*/usb*/*/*/idProduct | \
4566 sed -e "s/idProduct:$usb_product//" -e '/driver/d' )
4569 # make sure it's the right product/vendor match here, it will almost always be but let's be sure
4570 if [[ -n $working_path && -n $product_path ]] && [[ $working_path == $product_path ]];then
4571 #if [[ -n $working_path ]];then
4572 # now ls that directory and get the numeric starting sub directory and that should be the full path
4573 # to the /net directory part
4574 dir_path=$( ls ${working_path} 2>/dev/null | grep -sE '^[0-9]' )
4575 working_uevent_path="${working_path}${dir_path}"
4578 # /sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2/2-1.2:1.0/uevent grep for DRIVER=
4579 # /sys/devices/pci0000:00/0000:00:0b.1/usb1/1-1/1-1:1.0/uevent
4580 if [[ -n $usb_data ]];then
4581 driver_test=$( grep -si 'DRIVER=' $working_uevent_path/uevent | cut -d '=' -f 2 )
4582 if [[ -n $driver_test ]];then
4583 a_network_adv_working[1]=$driver_test
4586 log_function_data "PRE: working_path: $working_path\nworking_uevent_path: $working_uevent_path"
4588 # this applies in two different cases, one, default, standard, two, for usb, this is actually
4589 # the short path, minus the last longer numeric directory name, ie:
4590 # from debian squeeze 2.6.32-5-686:
4591 # /sys/devices/pci0000:00/0000:00:0b.1/usb1/1-1/net/wlan0/address
4592 if [[ -e $working_path/net ]];then
4593 if_path=$( ls $working_path/net 2>/dev/null )
4595 working_path=$working_path/net/$if_path
4596 # this is the normal usb detection if the first one didn't work
4597 elif [[ -n $usb_data && -e $working_uevent_path/net ]];then
4598 if_path=$( ls $working_uevent_path/net 2>/dev/null )
4600 working_path=$working_uevent_path/net/$if_path
4601 # 2.6.32 debian lenny kernel shows not: /net/eth0 but /net:eth0
4603 if_path=$( ls $working_path 2>/dev/null | grep 'net:' )
4604 if_id=$( cut -d ':' -f 2 <<< "$if_path" )
4605 working_path=$working_path/$if_path
4607 log_function_data "POST: working_path: $working_path\nif_path: $if_path - if_id: $if_id"
4609 if [[ -n $if_path ]];then
4610 if [[ -r $working_path/speed ]];then
4611 speed=$( cat $working_path/speed 2>/dev/null )
4613 if [[ -r $working_path/duplex ]];then
4614 duplex=$( cat $working_path/duplex 2>/dev/null )
4616 if [[ -r $working_path/address ]];then
4617 mac_id=$( cat $working_path/address 2>/dev/null )
4619 if [[ -r $working_path/operstate ]];then
4620 oper_state=$( cat $working_path/operstate 2>/dev/null )
4624 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
4631 get_networking_usb_data()
4634 local lsusb_path='' lsusb_data='' a_usb='' array_count=''
4636 # now we'll check for usb wifi, a work in progress
4637 # USB_NETWORK_SEARCH
4638 # alsa usb detection by damentz
4639 # for every sound card symlink in /proc/asound - display information about it
4640 lsusb_path=$( type -p lsusb )
4641 # if lsusb exists, the file is a symlink, and contains an important usb exclusive file: continue
4642 if [[ -n $lsusb_path ]]; then
4643 # send error messages of lsusb to /dev/null as it will display a bunch if not a super user
4644 lsusb_data="$( $lsusb_path 2>/dev/null )"
4645 # also, find the contents of usbid in lsusb and print everything after the 7th word on the
4646 # corresponding line. Finally, strip out commas as they will change the driver :)
4647 if [[ -n $lsusb_data ]];then
4656 /'"$USB_NETWORK_SEARCH"'/ && !/bluetooth| hub|keyboard|mouse|printer| ps2|reader|scan|storage/ {
4658 gsub( /,/, " ", $0 )
4659 gsub(/'"$BAN_LIST_NORMAL"'/, "", $0)
4660 gsub(/ [ \t]+/, " ", $0)
4661 sub(/realtek semiconductor/, "Realtek", $0)
4662 sub(/davicom semiconductor/, "Davicom", $0)
4663 sub(/Belkin Components/, "Belkin", $0)
4664 for ( i=7; i<= NF; i++ ) {
4665 string = string separator $i
4669 print string ",,,,usb-" $6
4671 }' <<< "$lsusb_data"
4674 if [[ ${#a_usb[@]} -gt 0 ]];then
4675 array_count=${#A_NETWORK_DATA[@]}
4676 for (( i=0; i < ${#a_usb[@]}; i++ ))
4678 A_NETWORK_DATA[$array_count]=${a_usb[i]}
4681 # need this to get the driver data for -N regular output, but no need
4682 # to run the advanced stuff unless required
4683 B_USB_NETWORKING='true'
4687 # echo $B_USB_NETWORKING
4691 get_networking_wan_ip_data()
4696 # get ip using wget redirect to stdout. This is a clean, text only IP output url.
4697 ip=$( wget -q -O - http://smxi.org/opt/ip.php | gawk -F 'is: ' '{
4702 if [[ -z $ip ]];then
4706 log_function_data "ip: $ip"
4710 get_networking_local_ip_data()
4714 local ip_tool_command=$( type -p ip )
4715 local temp_array='' ip_tool='ip' ip_tool_data=''
4716 # the chances for all new systems to have ip by default are far higher than
4717 # the deprecated ifconfig. Only try for ifconfig if ip is not present in system
4718 if [[ -z $ip_tool_command ]];then
4719 ip_tool_command=$( type -p ifconfig )
4722 ip_tool_command="$ip_tool_command addr"
4724 if [[ -n "$ip_tool_command" ]];then
4725 if [[ $ip_tool == 'ifconfig' ]];then
4726 ip_tool_data="$( $ip_tool_command )"
4727 # note, ip addr does not have proper record separation, so creating new lines explicitly here at start
4728 # of each IF record item. Also getting rid of the unneeded numeric line starters, now it can be parsed
4729 # like ifconfig more or less
4730 elif [[ $ip_tool == 'ip' ]];then
4731 ip_tool_data="$( eval ${ip_tool_command} | sed 's/^[0-9]\+:[[:space:]]\+/\n/' )"
4734 if [[ -z $ip_tool_command ]];then
4735 A_INTERFACES_DATA=( "Interfaces program 'ip' missing. Please check: $SCRIPT_NAME --recommends" )
4736 elif [[ -n "$ip_tool_data" ]];then
4737 IFS=$'\n' # $ip_tool_command
4738 A_INTERFACES_DATA=( $(
4739 gawk -v ipTool=$ip_tool '
4747 # skip past the lo item
4749 while (getline && !/^$/ ) {
4750 # do nothing, just get past this entry item
4754 # not clear on why inet is coming through, but this gets rid of it
4755 # as first line item.
4757 gsub(/^ +| +$/, "", $0)
4758 gsub(/ [ \t]+/, " ", $0)
4760 # prep this this for ip addr: eth0:
4761 sub(/:/, "", interface)
4765 aInterfaces[interface]++
4767 while (getline && !/^$/ ) {
4768 if ( ipTool == "ifconfig" ) {
4770 ifIp = gensub( /addr:([0-9\.]+)/, "\\1", "g", $2 )
4772 ifMask = gensub( /mask:([0-9\.]+)/, "\\1", "g", $NF )
4775 if (/inet6 addr:/) {
4779 else if ( ipTool == "ip" ) {
4780 if ( $1 == "inet" ) {
4783 if ( $1 == "inet6" ) {
4788 # slice off the digits that are sometimes tacked to the end of the address,
4790 sub(/\/[0-9]+/, "", ifIp)
4791 sub(/\/[0-9]+/, "", ifIpV6)
4792 ipAddresses[interface] = ifIp "," ifMask "," ifIpV6
4796 for (i in aInterfaces) {
4799 if (ipAddresses[i] != "") {
4800 ifData = ipAddresses[i]
4802 # create array primary item for master array
4803 # tested needed to avoid bad data from above, if null it is garbage
4804 # this is the easiest way to handle junk I found, improve if you want
4805 if ( ifData != "" ) {
4806 print a[j] "," ifData
4810 }' <<< "$ip_tool_data"
4814 A_INTERFACES_DATA=( "Interfaces program $ip_tool present but created no data. " )
4816 temp_array=${A_INTERFACES_DATA[@]}
4817 log_function_data "A_INTERFACES_DATA: $temp_array"
4820 # get_networking_local_ip_data;exit
4822 # get_networking_local_ip_data;exit
4823 get_optical_drive_data()
4827 local temp_array='' sys_uevent_path='' proc_cdrom='' link_list=''
4828 local separator='' linked='' disk='' item_string='' proc_info_string=''
4829 local dev_disks_links="$( ls /dev/dvd* /dev/cd* /dev/scd* 2>/dev/null )"
4830 # get the actual disk dev location, first try default which is easier to run, need to preserve line breaks
4831 local dev_disks_real="$( echo "$dev_disks_links" | xargs -l readlink 2>/dev/null | sort -u )"
4832 # Some systems don't support xargs -l so we need to do it manually
4833 if [[ -z $dev_disks_real ]];then
4834 for linked in $dev_disks_links
4836 disk=$( readlink $linked 2>/dev/null )
4837 if [[ -n $disk ]];then
4838 disk=$( basename $disk ) # puppy shows this as /dev/sr0, not sr0
4839 if [[ -z $dev_disks_real || -z $( grep $disk <<< $dev_disks_real ) ]];then
4840 # need line break IFS for below, no white space
4841 dev_disks_real="$dev_disks_real$separator$disk"
4846 dev_disks_real="$( sort -u <<< "$dev_disks_real" )"
4852 # A_OPTICAL_DRIVE_DATA indexes: not going to use all these, but it's just as easy to build the full
4853 # data array and use what we need from it as to update it later to add features or items
4854 # 0 - true dev path, ie, sr0, hdc
4855 # 1 - dev links to true path
4856 # 2 - device vendor - for hdx drives, vendor model are one string from proc
4858 # 4 - device rev version
4860 # 6 - multisession support
4870 if [[ -n $dev_disks_real ]];then
4871 if [[ $B_SHOW_FULL_OPTICAL == 'true' ]];then
4872 proc_cdrom="$( cat /proc/sys/dev/cdrom/info 2>/dev/null )"
4875 A_OPTICAL_DRIVE_DATA=( $(
4876 for disk in $dev_disks_real
4878 for linked in $dev_disks_links
4880 if [[ -n $( readlink $linked | grep $disk ) ]];then
4881 linked=$( basename $linked )
4882 link_list="$link_list$separator$linked"
4886 item_string="$disk,$link_list"
4896 # this is only for new sd type paths in /sys, otherwise we'll use /proc/ide
4897 if [[ -z $( grep '^hd' <<< $disk ) ]];then
4898 sys_path=$( ls /sys/devices/pci*/*/host*/target*/*/block/$disk/uevent 2>/dev/null | sed "s|/block/$disk/uevent||" )
4899 # no need to test for errors yet, probably other user systems will require some alternate paths though
4900 if [[ -n $sys_path ]];then
4901 vendor=$( cat $sys_path/vendor 2>/dev/null )
4902 model=$( cat $sys_path/model 2>/dev/null | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/,//g' )
4903 state=$( cat $sys_path/state 2>/dev/null | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/,//g' )
4904 rev_number=$( cat $sys_path/rev 2>/dev/null | sed 's/^[[:space:]]*//;s/[[:space:]]*$//;s/,//g' )
4906 elif [[ -e /proc/ide/$disk/model ]];then
4907 vendor=$( cat /proc/ide/$disk/model 2>/dev/null )
4909 if [[ -n $vendor ]];then
4915 gsub(/'"$BAN_LIST_NORMAL"'/, "", $0)
4916 sub(/TSSTcorp/, "TSST ", $0) # seen more than one of these weird ones
4918 gsub(/^[[:space:]]*|[[:space:]]*$/, "", $0)
4919 gsub(/ [[:space:]]+/, " ", $0)
4924 # this needs to run no matter if there's proc data or not to create the array comma list
4925 if [[ $B_SHOW_FULL_OPTICAL == 'true' ]];then
4926 proc_info_string=$( gawk -v diskId=$disk '
4940 # first get the position of the device name from top field
4941 # we will use this to get all the other data for that column
4943 for ( position=3; position <= NF; position++ ) {
4944 if ( $position == diskId ) {
4952 /Can read multisession:/ {
4953 multisession=$( position + 1 )
4956 mcn=$( position + 1 )
4959 audio=$( position + 1 )
4962 cdr=$( position + 1 )
4964 /Can write CD-RW:/ {
4965 cdrw=$( position + 1 )
4968 dvd=$( position + 1 )
4970 /Can write DVD-R:/ {
4971 dvdr=$( position + 1 )
4973 /Can write DVD-RAM:/ {
4974 dvdram=$( position + 1 )
4977 print speed "," multisession "," mcn "," audio "," cdr "," cdrw "," dvd "," dvdr "," dvdram
4982 item_string="$item_string,$vendor,$model,$rev_number,$proc_info_string,$state"
4988 temp_array=${A_OPTICAL_DRIVE_DATA[@]}
4989 log_function_data "A_OPTICAL_DRIVE_DATA: $temp_array"
4993 get_partition_data()
4997 local a_partition_working='' dev_item='' temp_array=''
4998 #local excluded_file_types='--exclude-type=aufs --exclude-type=tmpfs --exclude-type=iso9660'
4999 # df doesn't seem to work in script with variables like at the command line
5000 # added devfs linprocfs sysfs fdescfs which show on debian kfreebsd kernel output
5001 local main_partition_data="$( 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 )"
5002 local swap_data="$( swapon -s )"
5003 # set dev disk label/uuid data globals
5004 get_partition_uuid_label_data 'label'
5005 get_partition_uuid_label_data 'uuid'
5007 log_function_data 'raw' "main_partition_data:\n$main_partition_data\n\nswap_data:\n$swap_data"
5009 # new kernels/df have rootfs and / repeated, creating two entries for the same partition
5010 # so check for two string endings of / then slice out the rootfs one, I could check for it
5011 # before slicing it out, but doing that would require the same action twice re code execution
5012 if [[ $( grep -cs '[[:space:]]/$' <<< "$main_partition_data" ) -gt 1 ]];then
5013 main_partition_data="$( grep -vs '^rootfs' <<< "$main_partition_data" )"
5015 log_function_data 'raw' "main_partition_data_post_rootfs:\n$main_partition_data\n\nswap_data:\n$swap_data"
5017 # sample line: /dev/sda2 ext3 15G 8.9G 4.9G 65% /home
5018 # $NF = partition name; $(NF - 4) = partition size; $(NF - 3) = used, in gB; $(NF - 1) = percent used
5019 ## note: by subtracting from the last field number NF, we avoid a subtle issue with LVM df output, where if
5020 ## the first field is too long, it will occupy its own line, this way we are getting only the needed data
5021 A_PARTITION_DATA=( $( echo "$main_partition_data" | gawk '
5025 # this has to be nulled for every iteration so it does not retain value from last iteration
5027 # this is required because below we are subtracting from NF, so it has to be > 5
5028 # the real issue is long file system names that force the wrap of df output: //fileserver/main
5029 # but we still need to handle more dynamically long space containing file names, but later.
5030 # Using df -P should fix this, ie, no wrapping of line lines, but leaving this for now
5031 ( NF < 6 ) && ( $0 !~ /[0-9]+%/ ) {
5032 # set the dev location here for cases of wrapped output
5034 devBase=gensub( /^(\/dev\/)(.+)$/, "\\2", 1, $1 )
5038 # next set devBase if it didn not get set above here
5039 ( $1 ~ /^\/dev\// ) && ( devBase == "" ) {
5040 devBase=gensub( /^(\/dev\/)(.+)$/, "\\2", 1, $1 )
5042 # this handles yet another fredforfaen special case where a mounted drive
5043 # has the search string in its name
5044 $NF ~ /^\/$|^\/boot$|^\/var$|^\/home$|^\/tmp$|^\/usr$/ {
5045 print $NF "," $(NF - 4) "," $(NF - 3) "," $(NF - 1) ",main," $(NF - 5) "," devBase
5047 # skip all these, including the first, header line. Use the --exclude-type
5048 # to handle new filesystems types we do not want listed here
5049 $NF !~ /^\/$|^\/boot$|^\/var$|^\/home$|^\/tmp$|^\/usr$|^filesystem/ {
5050 # this is to avoid file systems with spaces in their names, that will make
5051 # the test show the wrong data in each of the fields, if no x%, then do not use
5052 # using 3 cases, first default, standard, 2nd, 3rd, handles one and two spaces in name
5053 if ( $(NF - 1) ~ /[0-9]+%/ ) {
5054 print $NF "," $(NF - 4) "," $(NF - 3) "," $(NF - 1) ",secondary," $(NF - 5) "," devBase
5056 # these two cases construct the space containing name
5057 else if ( $(NF - 2) ~ /[0-9]+%/ ) {
5058 print $(NF - 1) " " $NF "," $(NF - 5) "," $(NF - 4) "," $(NF - 2) ",secondary," $(NF - 6) "," devBase
5060 else if ( $(NF - 3) ~ /[0-9]+%/ ) {
5061 print $(NF - 2) " " $(NF - 1) " " $NF "," $(NF - 6) "," $(NF - 5) "," $(NF - 3) ",secondary," $(NF - 7) "," devBase
5066 # now add the swap partition data, don't want to show swap files, just partitions,
5067 # though this can include /dev/ramzswap0. Note: you can also use /proc/swaps for this
5068 # data, it's the same exact output as swapon -s
5069 $( echo "$swap_data" | gawk '
5074 size = sprintf( "%.2f", $3*1024/1000**3 )
5075 devBase = gensub( /^(\/dev\/)(.+)$/, "\\2", 1, $1 )
5076 used = sprintf( "%.2f", $4*1024/1000**3 )
5077 percentUsed = sprintf( "%.0f", ( $4/$3 )*100 )
5078 print "swap-" swapCounter "," size "GB," used "GB," percentUsed "%,main," "swap," devBase
5079 swapCounter = ++swapCounter
5083 temp_array=${A_PARTITION_DATA[@]}
5084 log_function_data "1: A_PARTITION_DATA:\n$temp_array"
5086 # now we'll handle some fringe cases where irregular df -hT output shows /dev/disk/.. instead of
5087 # /dev/h|sdxy type data for column 1, . A_PARTITION_DATA[6]
5088 # Here we just search for the uuid/label and then grab the end of the line to get the right dev item.
5089 for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
5092 a_partition_working=( ${A_PARTITION_DATA[i]} )
5094 dev_item='' # reset each loop
5095 # note: for swap this will already be set
5096 if [[ -n $( grep -E '(by-uuid|by-label)' <<< ${a_partition_working[6]} ) ]];then
5097 if [[ -n $DEV_DISK_UUID ]];then
5098 dev_item=$( echo "$DEV_DISK_UUID" | gawk '
5099 /'$( basename ${a_partition_working[6]} )'/ {
5100 item=gensub( /..\/..\/(.+)/, "\\1", 1, $NF )
5104 # if we didn't find anything for uuid try label
5105 if [[ -z $dev_item && -n $DEV_DISK_LABEL ]];then
5106 dev_item=$( echo "$DEV_DISK_LABEL" | gawk '
5107 /'$( basename ${a_partition_working[6]} )'/ {
5108 item=gensub( /..\/..\/(.+)/, "\\1", 1, $NF )
5112 if [[ -n $dev_item ]];then
5113 # assemble everything we could get for dev/h/dx, label, and uuid
5115 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
5120 temp_array=${A_PARTITION_DATA[@]}
5121 log_function_data "2: A_PARTITION_DATA:\n$temp_array"
5122 if [[ $B_SHOW_LABELS == 'true' || $B_SHOW_UUIDS == 'true' ]];then
5123 get_partition_data_advanced
5128 # first get the locations of the mount points for label/uuid detection
5129 get_partition_data_advanced()
5132 local a_partition_working='' dev_partition_data=''
5133 local dev_item='' dev_label='' dev_uuid='' temp_array=''
5134 local mount_point=''
5135 # set dev disk label/uuid data globals
5136 get_partition_uuid_label_data 'label'
5137 get_partition_uuid_label_data 'uuid'
5139 if [[ $B_MOUNTS_FILE == 'true' ]];then
5140 for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
5143 a_partition_working=( ${A_PARTITION_DATA[i]} )
5146 # note: for swap this will already be set
5147 if [[ -z ${a_partition_working[6]} ]];then
5148 mount_point=$( sed 's|/|\\/|g' <<< ${a_partition_working[0]} )
5149 #echo mount_point $mount_point
5150 dev_partition_data=$( gawk '
5156 # trying to handle space in name
5157 # gsub( /\\040/, " ", $0 )
5158 /[ \t]'$mount_point'[ \t]/ && $1 != "rootfs" {
5159 # initialize the variables
5163 # slice out the /dev
5164 partition=gensub( /^(\/dev\/)(.+)$/, "\\2", 1, $1 )
5165 # label and uuid can occur for root, set partition to null now
5166 if ( partition ~ /by-label/ ) {
5167 label=gensub( /^(\/dev\/disk\/by-label\/)(.+)$/, "\\2", 1, $1 )
5170 if ( partition ~ /by-uuid/ ) {
5171 uuid=gensub( /^(\/dev\/disk\/by-uuid\/)(.+)$/, "\\2", 1, $1 )
5175 # handle /dev/root for / id
5176 if ( partition == "root" ) {
5177 # if this works, great, otherwise, just set this to null values
5178 partTemp="'$( readlink /dev/root 2>/dev/null )'"
5179 if ( partTemp != "" ) {
5180 if ( partTemp ~ /[hsv]d[a-z][0-9]{1,2}/ ) {
5181 partition=gensub( /^(\/dev\/)(.+)$/, "\\2", 1, partTemp )
5183 else if ( partTemp ~ /by-uuid/ ) {
5184 uuid=gensub( /^(\/dev\/disk\/by-uuid\/)(.+)$/, "\\2", 1, partTemp )
5185 partition="" # set null to let real location get discovered
5187 else if ( partTemp ~ /by-label/ ) {
5188 label=gensub( /^(\/dev\/disk\/by-label\/)(.+)$/, "\\2", 1, partTemp )
5189 partition="" # set null to let real location get discovered
5198 print partition "," label "," uuid
5201 # assemble everything we could get for dev/h/dx, label, and uuid
5203 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
5206 ## now we're ready to proceed filling in the data
5208 a_partition_working=( ${A_PARTITION_DATA[i]} )
5211 dev_item=${a_partition_working[6]}
5212 dev_label=${a_partition_working[7]}
5213 dev_uuid=${a_partition_working[8]}
5215 # then if dev data/uuid is incomplete, try to get missing piece
5216 # it's more likely we'll get a uuid than a label. But this should get the
5217 # dev item set no matter what, so then we can get the rest of any missing data
5218 # first we'll get the dev_item if it's missing
5219 if [[ -z $dev_item ]];then
5220 if [[ -n $DEV_DISK_UUID && -n $dev_uuid ]];then
5221 dev_item=$( echo "$DEV_DISK_UUID" | gawk '
5223 item=gensub( /..\/..\/(.+)/, "\\1", 1, $NF )
5226 elif [[ -n $DEV_DISK_LABEL && -n $dev_label ]];then
5227 dev_item=$( echo "$DEV_DISK_LABEL" | gawk '
5228 # first we need to change space x20 in by-label back to a real space
5229 #gsub( /x20/, " ", $0 )
5230 # then we can see if the string is there
5232 item=gensub( /..\/..\/(.+)/, "\\1", 1, $NF )
5237 # this can trigger all kinds of weird errors if it is a non /dev path, like: remote:/machine/name
5238 if [[ -n $dev_item && -z $( grep -E '(^//|:/)' <<< $dev_item ) ]];then
5239 if [[ -n $DEV_DISK_UUID && -z $dev_uuid ]];then
5240 dev_uuid=$( echo "$DEV_DISK_UUID" | gawk '
5245 if [[ -n $DEV_DISK_LABEL && -z $dev_label ]];then
5246 dev_label=$( echo "$DEV_DISK_LABEL" | gawk '
5253 # assemble everything we could get for dev/h/dx, label, and uuid
5255 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
5258 log_function_data 'cat' "$FILE_MOUNTS"
5260 temp_array=${A_PARTITION_DATA[@]}
5261 log_function_data "3-advanced: A_PARTITION_DATA:\n$temp_array"
5265 # args: $1 - uuid/label
5266 get_partition_uuid_label_data()
5270 # only run these tests once per directory to avoid excessive queries to fs
5273 if [[ $B_LABEL_SET != 'true' ]];then
5274 if [[ -d /dev/disk/by-label ]];then
5275 DEV_DISK_LABEL="$( ls -l /dev/disk/by-label )"
5281 if [[ $B_UUID_SET != 'true' ]];then
5282 if [[ -d /dev/disk/by-uuid ]];then
5283 DEV_DISK_UUID="$( ls -l /dev/disk/by-uuid )"
5289 log_function_data 'raw' "DEV_DISK_LABEL:\n$DEV_DISK_LABEL\n\nDEV_DISK_UUID:\n$DEV_DISK_UUID"
5290 # debugging section, uncomment to insert user data
5300 get_patch_version_string()
5302 local script_patch_number=$( sed 's/^[0]\+//' <<< $SCRIPT_PATCH_NUMBER )
5303 if [[ -n $script_patch_number ]];then
5304 script_patch_number="-$script_patch_number"
5306 echo $script_patch_number
5309 # args: $1 - type cpu/mem
5313 local array_length='' reorder_temp='' i=0 head_tail='' sort_type=''
5315 # bummer, have to make it more complex here because of reverse sort
5316 # orders in output, pesky lack of support of +rss in old systems
5328 # throttle potential irc abuse
5329 if [[ $B_RUNNING_IN_SHELL != 'true' && $PS_COUNT -gt 5 ]];then
5330 PS_THROTTLED=$PS_COUNT
5335 # note that inxi can use a lot of cpu, and can actually show up here as the script runs
5336 A_PS_DATA=( $( ps aux --sort $sort_type | grep -Ev "($SCRIPT_NAME|%CPU|[[:space:]]ps[[:space:]])" | $head_tail -n $PS_COUNT | gawk '
5354 rss=sprintf( "%.2f", $6/1024 )
5355 # have to get rid of [,],(,) eg: [lockd] which break the printout function compare in bash
5356 gsub(/\[|\]|\(|\)/,"~", $0 )
5365 appStarterName=gensub( /(\/.*\/)(.*)/, "\\2", "1", appStarterPath )
5366 appName=gensub( /(\/.*\/)(.*)/, "\\2", "1", appPath )
5367 print appName "," appPath "," appStarterName "," appStarterPath "," cpu "," mem "," pid "," rss "," user
5370 # make the array ordered highest to lowest so output looks the way we expect it to
5371 # this isn't necessary for -rss, and we can't make %cpu ordered the other way, so
5372 # need to reverse it here. -rss is used because on older systems +rss is not supported
5373 if [[ $1 == 'cpu' ]];then
5374 array_length=${#A_PS_DATA[@]};
5375 while (( $i < $array_length/2 ))
5377 reorder_temp=${A_PS_DATA[i]}f
5378 A_PS_DATA[i]=${A_PS_DATA[$array_length-$i-1]}
5379 A_PS_DATA[$array_length-$i-1]=$reorder_temp
5386 # echo ${A_PS_DATA[@]}
5390 # Repos will be added as we get distro package manager data to create the repo data.
5391 # This method will output the file name also, which is useful to create output that's
5392 # neat and readable.
5396 local repo_file='' repo_data_working='' repo_data_working2='' repo_line=''
5397 local apt_file='/etc/apt/sources.list' yum_repo_dir='/etc/yum.repos.d/' yum_conf='/etc/yum.conf'
5398 local pacman_conf='/etc/pacman.conf' pacman_repo_dir='/etc/pacman.d/' pisi_dir='/etc/pisi/'
5400 # apt - debian, buntus
5401 if [[ -f $apt_file || -d $apt_file.d ]];then
5402 REPO_DATA="$( grep -Esv '(^[[:space:]]*$|^[[:space:]]*#)' $apt_file $apt_file.d/*.list )"
5403 REPO_FILE_ID='apt sources'
5404 # yum - fedora, redhat, centos, etc
5405 elif [[ -d $yum_repo_dir || -f $yum_conf ]];then
5406 # older redhats put their yum data in /etc/yum.conf
5407 for repo_file in $( ls $yum_repo_dir*.repo $yum_conf 2>/dev/null )
5409 repo_data_working="$( gawk -v repoFile=$repo_file '
5410 # construct the string for the print function to work with, file name: data
5411 function print_line( fileName, repoId, repoUrl ){
5412 print fileName ":" repoId repoUrl
5421 # this is a hack, assuming that each item has these fields listed, we collect the 3
5422 # items one by one, then when the url/enabled fields are set, we print it out and
5423 # reset the data. Not elegant but it works. Note that if enabled was not present
5424 # we assume it is enabled then, and print the line, reset the variables. This will
5425 # miss the last item, so it is printed if found in END
5427 if ( urlData != "" && repoTitle != "" ){
5428 print_line( repoFile, repoTitle, urlData )
5433 gsub( /\[|\]/, "", $1 ) # strip out the brackets
5434 repoTitle = $1 " ~ "
5436 /^(mirrorlist|baseurl)/ {
5437 sub( /(mirrorlist|baseurl)=/, "", $1 ) # strip out the field starter
5443 # print out the line if all 3 values are found, otherwise if a new
5444 # repoTitle is hit above, it will print out the line there instead
5446 if ( urlData != "" && enabledStatus != "" && repoTitle != "" ){
5447 if ( enabledStatus !~ /enabled=0/ ){
5448 print_line( repoFile, repoTitle, urlData )
5456 # print the last one if there is data for it
5457 if ( urlData != "" && repoTitle != "" ){
5458 print_line( repoFile, repoTitle, urlData )
5463 # then load the global for each file as it gets filled
5464 if [[ -n $repo_data_working ]];then
5465 if [[ -z $REPO_DATA ]];then
5466 REPO_DATA="$repo_data_working"
5468 REPO_DATA="$REPO_DATA
5471 repo_data_working=''
5474 REPO_FILE_ID='yum repos'
5476 elif [[ -d $pisi_dir && -n $( type -p pisi ) ]];then
5477 REPO_DATA="$( pisi list-repo )"
5478 # now we need to create the structure: repo info: repo path
5479 # we do that by looping through the lines of the output and then
5480 # putting it back into the <data>:<url> format print repos expects to see
5481 while read repo_line
5485 # need to dump leading/trailing spaces and clear out color codes for irc output
5486 sub(/^[[:space:]]+|[[:space:]]+$/,"",$0)
5487 # gsub(/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]/,"",$0) # leaving this pattern in case need it
5488 gsub(/
\e\[([0-9];)?[0-9]+m/,"",$0)
5491 if [[ -n $( grep '://' <<< $repo_line ) ]];then
5492 repo_data_working="$repo_data_working:$repo_line\n"
5494 repo_data_working="$repo_data_working$repo_line"
5496 done <<< "$REPO_DATA"
5497 # echo and execute the line breaks inserted
5498 REPO_DATA="$( echo -e $repo_data_working )"
5499 REPO_FILE_ID='pisi repo'
5500 # pacman - archlinux
5501 elif [[ -f $pacman_conf ]];then
5502 # get list of mirror include files, trim white space off ends
5503 repo_data_working="$( gawk '
5508 /^[[:space:]]*Include/ {
5509 sub(/^[[:space:]]+|[[:space:]]+$/,"",$2)
5513 # sort into unique paths only, to be used to search for server = data
5514 repo_data_working=$( sort -bu <<< "$repo_data_working" | uniq )
5515 repo_data_working="$repo_data_working $pacman_conf"
5516 for repo_file in $repo_data_working
5518 if [[ -f $repo_file ]];then
5519 # inserting a new line after each found / processed match
5520 repo_data_working2="$repo_data_working2$( gawk -v repoFile=$repo_file '
5525 /^[[:space:]]*Server/ {
5526 sub(/^[[:space:]]+|[[:space:]]+$/,"",$2)
5527 print repoFile ":" $2 "\\n"
5531 echo "Error: file listed in $pacman_conf does not exist - $repo_file"
5534 # execute line breaks
5535 REPO_DATA="$( echo -e $repo_data_working2 )"
5536 REPO_FILE_ID='arch repo servers'
5545 local runlevel_path=$( type -p runlevel )
5546 if [[ -n $runlevel_path ]];then
5547 runlvl="$( $runlevel_path | gawk '{ print $2 }' )"
5561 if [[ -n $Sensors_Data ]];then
5562 # note: non-configured sensors gives error message, which we need to redirect to stdout
5563 # also, -F ':' no space, since some cases have the data starting right after,like - :1287
5565 gawk -F ':' -v userCpuNo="$SENSORS_CPU_NO" '
5568 core0Temp="" # only if all else fails...
5572 indexCountaFanMain=0
5573 indexCountaFanDefault=0
5583 tempFanType="" # set to 1 or 2
5588 # new data arriving: gpu temp in sensors, have to skip that
5589 /^('"$SENSORS_GPU_SEARCH"')-pci/ {
5590 while ( getline && !/^$/ ) {
5591 # do nothing, just skip it
5594 # dumping the extra + signs after testing for them, nobody has negative temps.
5595 # also, note gawk treats ° as a space, so we have to get the C/F data
5596 # there are some guesses here, but with more sensors samples it will get closer.
5597 # note: using arrays starting at 1 for all fan arrays to make it easier overall
5598 # more validation because gensub if fails to get match returns full string, so
5599 # we have to be sure we are working with the actual real string before assiging
5600 # data to real variables and arrays. Extracting C/F degree unit as well to use
5601 # when constructing temp items for array.
5602 # note that because of charset issues, no tempUnit="°" tempWorkingUnit degree sign
5603 # used, but it is required in testing regex to avoid error.
5604 /^(M\/B|MB|SIO|SYS)(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
5605 moboTemp=gensub( /[ \t]+\+([0-9\.]*)(.*)/, "\\1", 1, $2 )
5606 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
5607 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
5608 tempUnit=tempWorkingUnit
5611 /^CPU(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
5612 cpuTemp=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
5613 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
5614 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
5615 tempUnit=tempWorkingUnit
5618 /^(P\/S|Power)(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
5619 psuTemp=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
5620 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
5621 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
5622 tempUnit=tempWorkingUnit
5625 $1 ~ /^temp1$/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
5626 tempWorking=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
5627 if ( temp1 == "" || tempWorking > 0 ) {
5630 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
5631 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
5632 tempUnit=tempWorkingUnit
5635 $1 ~ /^temp2$/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
5636 tempWorking=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
5637 if ( temp2 == "" || tempWorking > 0 ) {
5640 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
5641 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
5642 tempUnit=tempWorkingUnit
5646 # final fallback if all else fails, funtoo user showed sensors putting
5647 # temp on wrapped second line, not handled
5648 /^(core0|core 0)(.*)\+([0-9]+)(.*)[ \t°](C|F)/ && $2 ~ /^[ \t]*\+([0-9]+)/ {
5649 tempWorking=gensub( /[ \t]+\+([0-9\.]+)(.*)/, "\\1", 1, $2 )
5650 if ( core0Temp == "" || tempWorking > 0 ) {
5651 core0Temp=tempWorking
5653 tempWorkingUnit=gensub( /[ \t]+\+([0-9\.]+)[ \t°]+([CF])(.*)/, "\\2", 1, $2 )
5654 if ( tempWorkingUnit ~ /^C|F$/ && tempUnit == "" ){
5655 tempUnit=tempWorkingUnit
5659 # note: can be cpu fan:, cpu fan speed:, etc. Some cases have no space before
5660 # $2 starts (like so :1234 RPM), so skip that space test in regex
5661 /^CPU(.*)[ \t]*([0-9]+)[ \t]RPM/ {
5662 aFanMain[1]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
5664 /^(M\/B|MB|SYS)(.*)[ \t]*([0-9]+)[ \t]RPM/ {
5665 aFanMain[2]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
5667 /(Power|P\/S|POWER)(.*)[ \t]*([0-9]+)[ \t]RPM/ {
5668 aFanMain[3]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
5670 # note that the counters are dynamically set for fan numbers here
5671 # otherwise you could overwrite eg aux fan2 with case fan2 in theory
5672 # note: cpu/mobo/ps are 1/2/3
5673 # NOTE: test: ! i in array does NOT work, this appears to be an awk/gawk bug
5674 /^(AUX(1)? |CASE(1)? |CHASSIS(1)? )(.*)[ \t]*([0-9]+)[ \t]RPM/ {
5675 for ( i = 4; i < 7; i++ ){
5676 if ( i in aFanMain ){
5680 aFanMain[i]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
5685 /^(AUX([2-9]) |CASE([2-9]) |CHASSIS([2-9]) )(.*)[ \t]*([0-9]+)[ \t]RPM/ {
5686 for ( i = 5; i < 30; i++ ){
5687 if ( i in aFanMain ) {
5692 aFanMain[i]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
5697 # in rare cases syntax is like: fan1: xxx RPM
5698 /^(FAN(1)?[ \t:])(.*)[ \t]*([0-9]+)[ \t]RPM/ {
5699 aFanDefault[1]=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
5701 /^FAN([2-9]|1[0-9])(.*)[ \t]*([0-9]+)[ \t]RPM/ {
5702 fanWorking=gensub( /[ \t]*([0-9]+)[ \t]+(.*)/, "\\1", 1, $2 )
5703 sysFanNu=gensub( /fan([0-9]+)/, "\\1", 1, $1 )
5704 if ( sysFanNu ~ /^([0-9]+)$/ ) {
5705 # add to array if array index does not exist OR if number is > existing number
5706 if ( sysFanNu in aFanDefault ) {
5707 if ( fanWorking >= aFanDefault[sysFanNu] ) {
5708 aFanDefault[sysFanNu]=fanWorking
5712 aFanDefault[sysFanNu]=fanWorking
5718 # first we need to handle the case where we have to determine which temp/fan to use for cpu and mobo:
5719 # note, for rare cases of weird cool cpus, user can override in their prefs and force the assignment
5720 if ( temp1 != "" && temp2 != "" ){
5721 if ( userCpuNo != "" && userCpuNo ~ /(1|2)/ ) {
5722 tempFanType=userCpuNo
5725 # first some fringe cases with cooler cpu than mobo: assume which is cpu temp based on fan speed
5726 # but only if other fan speed is 0
5727 if ( temp1 >= temp2 && 1 in aFanDefault && 2 in aFanDefault && aFanDefault[1] == 0 && aFanDefault[2] > 0 ) {
5730 else if ( temp2 >= temp1 && 1 in aFanDefault && 2 in aFanDefault && aFanDefault[2] == 0 && aFanDefault[1] > 0 ) {
5733 # then handle the standard case if these fringe cases are false
5734 else if ( temp1 >= temp2 ) {
5742 # need a case for no temps at all reported, like with old intels
5743 else if ( temp2 == "" && cpuTemp == "" ){
5744 if ( temp1 == "" && moboTemp == "" ){
5747 else if ( temp1 != "" && moboTemp == "" ){
5750 else if ( temp1 != "" && moboTemp != "" ){
5755 # then get the real cpu temp, best guess is hottest is real
5756 if ( cpuTemp != "" ){
5759 else if ( tempFanType != "" ){
5760 if ( tempFanType == 1 ){
5770 # if all else fails, use core0 temp if it is present and cpu is null
5771 if ( cpuTempReal == "" && core0Temp != "" ) {
5772 cpuTempReal=core0Temp
5775 # then the real mobo temp
5776 if ( moboTemp != "" ){
5777 moboTempReal=moboTemp
5779 else if ( tempFanType != "" ){
5780 if ( tempFanType == 1 ) {
5790 # then set the cpu fan speed
5791 if ( aFanMain[1] == "" ) {
5792 # note, you cannot test for aFanDefault[1] or [2] != ""
5793 # because that creates an array item in gawk just by the test itself
5794 if ( tempFanType == 1 && 1 in aFanDefault ) {
5795 aFanMain[1]=aFanDefault[1]
5798 else if ( tempFanType == 2 && 2 in aFanDefault ) {
5799 aFanMain[1]=aFanDefault[2]
5804 # then we need to get the actual numeric max array count for both fan arrays
5805 for (i = 0; i <= 29; i++) {
5806 if ( i in aFanMain && i > indexCountaFanMain ) {
5807 indexCountaFanMain=i
5810 for (i = 0; i <= 14; i++) {
5811 if ( i in aFanDefault && i > indexCountaFanDefault ) {
5812 indexCountaFanDefault=i
5816 # clear out any duplicates. Primary fan real trumps fan working always if same speed
5817 for (i = 1; i <= indexCountaFanMain; i++) {
5818 if ( i in aFanMain && aFanMain[i] != "" && aFanMain[i] != 0 ) {
5819 for (j = 1; j <= indexCountaFanDefault; j++) {
5820 if ( j in aFanDefault && aFanMain[i] == aFanDefault[j] ) {
5827 # now see if you can find the fast little mobo fan, > 5000 rpm and put it as mobo
5828 # note that gawk is returning true for some test cases when aFanDefault[j] < 5000
5829 # which has to be a gawk bug, unless there is something really weird with arrays
5830 # note: 500 > aFanDefault[j] < 1000 is the exact trigger, and if you manually
5831 # assign that value below, the > 5000 test works again, and a print of the value
5832 # shows the proper value, so the corruption might be internal in awk.
5833 # Note: gensub is the culprit I think, assigning type string for range 501-1000 but
5834 # type integer for all others, this triggers true for >
5835 for (j = 1; j <= indexCountaFanDefault; j++) {
5836 if ( j in aFanDefault && int( aFanDefault[j] ) > 5000 && aFanMain[2] == "" ) {
5837 aFanMain[2] = aFanDefault[j]
5839 # then add one if required for output
5840 if ( indexCountaFanMain < 2 ) {
5841 indexCountaFanMain = 2
5846 # then construct the sys_fan string for echo, note that iteration 1
5847 # makes: fanDefaultString separator null, ie, no space or ,
5848 for (j = 1; j <= indexCountaFanDefault; j++) {
5849 fanDefaultString = fanDefaultString separator aFanDefault[j]
5852 separator="" # reset to null for next loop
5853 # then construct the sys_fan string for echo
5854 for (j = 1; j <= indexCountaFanMain; j++) {
5855 fanMainString = fanMainString separator aFanMain[j]
5859 # and then build the temps:
5860 if ( moboTempReal != "" ) {
5861 moboTempReal = moboTempReal tempUnit
5863 if ( cpuTempReal != "" ) {
5864 cpuTempReal = cpuTempReal tempUnit
5867 # if they are ALL null, print error message. psFan is not used in output currently
5868 if ( cpuTempReal == "" && moboTempReal == "" && aFanMain[1] == "" && aFanMain[2] == "" && aFanMain[3] == "" && fanDefaultString == "" ) {
5869 print "No active sensors found. Have you configured your sensors yet?"
5872 # then build array arrays:
5873 print cpuTempReal "," moboTempReal "," psuTemp
5874 # this is for output, a null print line does NOT create a new array index in bash
5875 if ( fanMainString == "" ) {
5879 print fanDefaultString
5881 }' <<< "$Sensors_Data"
5883 # the error case needs to go here because we are setting special array delimiter ','
5885 A_SENSORS_DATA=( "You do not have the sensors app installed." )
5889 temp_array=${A_SENSORS_DATA[@]}
5890 log_function_data "A_SENSORS_DATA: $temp_array"
5891 # echo "A_SENSORS_DATA: ${A_SENSORS_DATA[@]}"
5895 get_sensors_output()
5897 local sensors_path=$( type -p sensors ) sensors_data=''
5899 if [[ -n $sensors_path ]];then
5900 sensors_data="$( $sensors_path 2>/dev/null )"
5901 if [[ -n "$sensors_data" ]];then
5902 # make sure the file ends in newlines then characters, the newlines are lost in the echo unless
5903 # the data ends in some characters
5904 sensors_data="$sensors_data\n\n###"
5907 echo -e "$sensors_data"
5910 get_unmounted_partition_data()
5913 local a_unmounted_working='' mounted_partitions='' separator='' unmounted_fs=''
5914 local dev_working='' uuid_working='' label_working=''
5916 if [[ $B_PARTITIONS_FILE == 'true' ]];then
5917 # set dev disk label/uuid data globals
5918 get_partition_uuid_label_data 'label'
5919 get_partition_uuid_label_data 'uuid'
5921 # create list for slicing out the mounted partitions
5922 for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
5925 a_unmounted_working=( ${A_PARTITION_DATA[i]} )
5927 if [[ -n ${a_unmounted_working[6]} ]];then
5928 mounted_partitions="$mounted_partitions$separator${a_unmounted_working[6]}"
5933 A_UNMOUNTED_PARTITION_DATA=( $( grep -Ev '('$mounted_partitions')$' $FILE_PARTITIONS | gawk '
5937 # note that size 1 means it is a logical extended partition container
5938 # lvm might have dm-1 type syntax
5939 # need to exclude loop type file systems, squashfs for example
5940 /[a-z][0-9]+$|dm-[0-9]+$/ && $3 != 1 && $NF !~ /loop/ {
5941 size = sprintf( "%.2f", $3*1024/1000**3 )
5942 print $4 "," size "G"
5945 for (( i=0; i < ${#A_UNMOUNTED_PARTITION_DATA[@]}; i++ ))
5948 a_unmounted_working=( ${A_UNMOUNTED_PARTITION_DATA[i]} )
5951 label_working=$( grep -E "${a_unmounted_working[0]}$" <<< "$DEV_DISK_LABEL" | gawk '{
5954 uuid_working=$( grep -E "${a_unmounted_working[0]}$" <<< "$DEV_DISK_UUID" | gawk '{
5957 unmounted_fs=$( get_unmounted_partition_filesystem "/dev/${a_unmounted_working[0]}" )
5960 A_UNMOUNTED_PARTITION_DATA[i]=${a_unmounted_working[0]}","${a_unmounted_working[1]}","$label_working","$uuid_working","$unmounted_fs
5964 # echo "${A_PARTITION_DATA[@]}"
5965 # echo "${A_UNMOUNTED_PARTITION_DATA[@]}"
5969 # a few notes, normally file -s requires root, but you can set user rights in /etc/sudoers.
5970 # list of file systems: http://en.wikipedia.org/wiki/List_of_file_systems
5971 # args: $1 - /dev/<disk><part> to be tested for
5972 get_unmounted_partition_filesystem()
5975 local partition_filesystem='' sudo_command=''
5977 if [[ $B_FILE_TESTED != 'true' ]];then
5978 B_FILE_TESTED='true'
5979 FILE_PATH=$( type -p file )
5982 if [[ $B_SUDO_TESTED != 'true' ]];then
5983 B_SUDO_TESTED='true'
5984 SUDO_PATH=$( type -p sudo )
5987 if [[ -n $FILE_PATH && -n $1 ]];then
5988 # only use sudo if not root, -n option requires sudo -V 1.7 or greater. sudo will just error out
5989 # which is the safest course here for now, otherwise that interactive sudo password thing is too annoying
5990 # important: -n makes it non interactive, no prompt for password
5991 if [[ $B_ROOT != 'true' && -n $SUDO_PATH ]];then
5992 sudo_command='sudo -n '
5994 # this will fail if regular user and no sudo present, but that's fine, it will just return null
5995 # note the hack that simply slices out the first line if > 1 items found in string
5996 # also, if grub/lilo is on partition boot sector, no file system data is available
5997 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 '.*' )
5998 if [[ -n $partition_filesystem ]];then
5999 echo $partition_filesystem
6005 ## return uptime string
6009 ## note: removing gsub(/ /,"",a); to get get space back in there, goes right before print a
6010 local uptime_value="$( uptime | gawk '{
6011 a = gensub(/^.*up *([^,]*).*$/,"\\1","g",$0)
6014 echo "$uptime_value"
6015 log_function_data "uptime_value: $uptime_value"
6019 #### -------------------------------------------------------------------
6020 #### special data handling for specific options and conditions
6021 #### -------------------------------------------------------------------
6023 # args: $1 - string to strip color code characters out of
6024 # returns count of string length minus colors
6025 calculate_line_length()
6028 # ansi:
\e[1;34m irc: \x0312
6029 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 )
6030 count=$( wc -c <<< $string )
6034 ## multiply the core count by the data to be calculated, bmips, cache
6035 # args: $1 - string to handle; $2 - cpu count
6036 calculate_multicore_data()
6039 local string_number=$1 string_data=''
6041 if [[ -n $( grep -Ei '( mb| kb)' <<< $1 ) ]];then
6042 string_data=" $( gawk '{print $2}' <<< $1 )" # add a space for output
6043 string_number=$( gawk '{print $1}' <<< $1 )
6045 # handle weird error cases where it's not a number
6046 if [[ -n $( grep -E '^[0-9\.,]+$' <<< $string_number ) ]];then
6047 string_number=$( echo $string_number $2 | gawk '{
6051 elif [[ $string_number == '' ]];then
6052 string_number='Not Available'
6054 # I believe that the above returns 'unknown' by default so no need for extra text
6055 string_number="$string_number "
6057 echo "$string_number$string_data"
6058 log_function_data "string_numberstring_data: $string_number$string_data"
6062 # prints out shortened list of flags, the main ones of interest
6063 # args: $1 - string of cpu flags to process
6067 # must have a space after last item in list for RS=" "
6068 local cpu_flags_working="$1 "
6070 # nx = AMD stack protection extensions
6071 # lm = Intel 64bit extensions
6072 # sse, sse2, pni = sse1,2,3,4,5 gfx extensions
6073 # svm = AMD pacifica virtualization extensions
6074 # vmx = Intel IVT (vanderpool) virtualization extensions
6076 echo "$cpu_flags_working" | gawk '
6080 i = 1 # start at one because of for increment issue
6083 /^(lm|nx|pni|svm|vmx|(sss|ss)e([2-9])?([a-z])?(_[0-9])?)$/ {
6093 count = asort( a_flags )
6094 # note: why does gawk increment before the loop and not after? weird.
6095 for ( i=0; i <= count; i++ ){
6096 if ( flag_string == "" ) {
6097 flag_string = a_flags[i]
6100 flag_string = flag_string " " a_flags[i]
6107 #grep -oE '\<(nx|lm|sse[0-9]?|pni|svm|vmx)\>' | tr '\n' ' '))
6108 if [[ -z $cpu_flags ]];then
6112 log_function_data "cpu_flags: $cpu_flags"
6116 #### -------------------------------------------------------------------
6117 #### print and processing of output data
6118 #### -------------------------------------------------------------------
6120 #### MASTER PRINT FUNCTION - triggers all line item print functions
6121 ## main function to print out, master for all sub print functions.
6125 # note that print_it_out passes local variable values on to its children,
6126 # and in some cases, their children, with Lspci_Data
6127 local Lspci_Data='' # only for verbose
6129 if [[ $B_SHOW_SHORT_OUTPUT == 'true' ]];then
6132 Lspci_Data="$( get_lspci_data )"
6133 if [[ $B_SHOW_SYSTEM == 'true' ]];then
6136 if [[ $B_SHOW_MACHINE == 'true' ]];then
6139 if [[ $B_SHOW_BASIC_CPU == 'true' || $B_SHOW_CPU == 'true' ]];then
6142 if [[ $B_SHOW_GRAPHICS == 'true' ]];then
6145 if [[ $B_SHOW_AUDIO == 'true' ]];then
6148 if [[ $B_SHOW_NETWORK == 'true' ]];then
6149 print_networking_data
6151 if [[ $B_SHOW_DISK_TOTAL == 'true' || $B_SHOW_BASIC_DISK == 'true' || $B_SHOW_DISK == 'true' ]];then
6152 print_hard_disk_data
6154 if [[ $B_SHOW_PARTITIONS == 'true' ]];then
6155 print_partition_data
6157 if [[ $B_SHOW_UNMOUNTED_PARTITIONS == 'true' ]];then
6158 print_unmounted_partition_data
6160 if [[ $B_SHOW_SENSORS == 'true' ]];then
6163 if [[ $B_SHOW_REPOS == 'true' ]];then
6166 if [[ $B_SHOW_PS_CPU_DATA == 'true' || $B_SHOW_PS_MEM_DATA == 'true' ]];then
6169 if [[ $B_SHOW_INFO == 'true' ]];then
6176 #### SHORT OUTPUT PRINT FUNCTION, ie, verbosity 0
6177 # all the get data stuff is loaded here to keep execution time down for single line print commands
6178 # these will also be loaded in each relevant print function for long output
6182 local current_kernel=$( uname -rm ) # | gawk '{print $1,$3,$(NF-1)}' )
6183 local processes="$(( $( ps aux | wc -l ) - 1 ))"
6184 local short_data='' i='' b_background_black='false'
6185 local memory=$( get_memory_data )
6186 local up_time="$( get_uptime )"
6188 # set A_CPU_CORE_DATA
6190 local cpc_plural='' cpu_count_print='' model_plural=''
6191 local cpu_physical_count=${A_CPU_CORE_DATA[0]}
6192 local cpu_core_count=${A_CPU_CORE_DATA[3]}
6193 local cpu_core_alpha=${A_CPU_CORE_DATA[1]}
6194 local cpu_type=${A_CPU_CORE_DATA[2]}
6196 if [[ $cpu_physical_count -gt 1 ]];then
6199 cpu_count_print="$cpu_physical_count "
6202 local cpu_data_string="${cpu_count_print}${cpu_core_alpha} core"
6203 # local cpu_core_count=${A_CPU_CORE_DATA[0]}
6207 ## note: if hdd_model is declared prior to use, whatever string you want inserted will
6208 ## be inserted first. In this case, it's desirable to print out (x) before each disk found.
6209 local a_hdd_data_count=$(( ${#A_HDD_DATA[@]} - 1 ))
6211 local a_hdd_basic_working=( ${A_HDD_DATA[$a_hdd_data_count]} )
6213 local hdd_capacity=${a_hdd_basic_working[0]}
6214 local hdd_used=${a_hdd_basic_working[1]}
6220 local a_cpu_working=(${A_CPU_DATA[0]})
6222 local cpu_model="${a_cpu_working[0]}"
6223 ## assemble data for output
6224 local cpu_clock="${a_cpu_working[1]}" # old CPU3
6225 # this gets that weird min/max final array item
6226 local min_max_clock_nu=$(( ${#A_CPU_DATA[@]} - 1 ))
6227 local min_max_clock=${A_CPU_DATA[$min_max_clock_nu]}
6228 local script_patch_number=$( get_patch_version_string )
6230 #set_color_scheme 12
6231 if [[ $B_RUNNING_IN_SHELL == 'false' ]];then
6232 for i in $C1 $C2 $CN
6235 "$GREEN"|"$WHITE"|"$YELLOW"|"$CYAN")
6236 b_background_black='true'
6240 if [[ $b_background_black == 'true' ]];then
6243 ## these need to be in quotes, don't know why
6244 if [[ ${!i} == $NORMAL ]];then
6245 declare $i="${!i}15,1"
6247 declare $i="${!i},1"
6250 #C1="${C1},1"; C2="${C2},1"; CN="${CN},1"
6253 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}"
6255 if [[ $SHOW_IRC -gt 0 ]];then
6256 short_data="${short_data}${C1}Client${C2}${SEP1}${IRC_CLIENT}${IRC_CLIENT_VERSION}${SEP2}"
6258 short_data="${short_data}${C1}$SCRIPT_NAME${C2}${SEP1}$SCRIPT_VERSION_NUMBER$script_patch_number${SEP2}${CN}"
6259 if [[ $SCHEME -gt 0 ]];then
6260 short_data="${short_data} $NORMAL"
6262 print_screen_output "$short_data"
6266 #### LINE ITEM PRINT FUNCTIONS
6268 # print sound card data
6272 local i='' card_id='' audio_data='' a_audio_data='' port_data='' pci_bus_id=''
6273 local a_audio_working='' alsa_driver='' alsa_data='' port_plural='' module_version=''
6274 local bus_usb_text='' bus_usb_id='' line_starter='Audio:' alsa='' alsa_version=''
6275 # set A_AUDIO_DATA and get alsa data
6278 # alsa driver data now prints out no matter what
6279 if [[ -n $A_ALSA_DATA ]];then
6281 if [[ -n ${A_ALSA_DATA[0]} ]];then
6282 alsa=${A_ALSA_DATA[0]}
6286 if [[ -n ${A_ALSA_DATA[1]} ]];then
6287 alsa_version=${A_ALSA_DATA[1]}
6291 alsa_data="${C1}Sound:${C2} $alsa ${C1}ver$SEP3${C2} $alsa_version"
6294 # note, error handling is done in the get function, so this will never be null, but
6295 # leaving the test just in case it's changed.
6296 if [[ -n ${A_AUDIO_DATA[@]} ]];then
6297 for (( i=0; i< ${#A_AUDIO_DATA[@]}; i++ ))
6300 a_audio_working=( ${A_AUDIO_DATA[i]} )
6310 if [[ ${#A_AUDIO_DATA[@]} -gt 1 ]];then
6311 card_id="-$(( $i + 1 ))"
6313 if [[ -n ${a_audio_working[3]} && $B_EXTRA_DATA == 'true' ]];then
6314 module_version=$( print_module_version "${a_audio_working[3]}" 'audio' )
6315 elif [[ -n ${a_audio_working[1]} && $B_EXTRA_DATA == 'true' ]];then
6316 module_version=$( print_module_version "${a_audio_working[1]}" 'audio' )
6318 # we're testing for the presence of the 2nd array item here, which is the driver name
6319 if [[ -n ${a_audio_working[1]} ]];then
6320 alsa_driver=" ${C1}driver$SEP3${C2} ${a_audio_working[1]}"
6322 if [[ -n ${a_audio_working[2]} && $B_EXTRA_DATA == 'true' ]];then
6323 if [[ $( wc -w <<< ${a_audio_working[2]} ) -gt 1 ]];then
6326 port_data=" ${C1}port$port_plural$SEP3${C2} ${a_audio_working[2]}"
6328 if [[ -n ${a_audio_working[4]} && $B_EXTRA_DATA == 'true' ]];then
6329 if [[ ${a_audio_working[1]} != 'USB Audio' ]];then
6330 bus_usb_text='bus-ID'
6332 bus_usb_text='usb-ID'
6334 bus_usb_id=${a_audio_working[4]}
6335 pci_bus_id=" ${C1}$bus_usb_text$SEP3${C2} $bus_usb_id"
6337 if [[ -n ${a_audio_working[0]} ]];then
6338 audio_data="${C1}Card$card_id:${C2} ${a_audio_working[0]}$alsa_driver$port_data$pci_bus_id"
6340 # only print alsa on last line if short enough, otherwise print on its own line
6341 if [[ $i -eq 0 ]];then
6342 if [[ -n $alsa_data && $( calculate_line_length "${audio_data}$alsa_data" ) -lt $LINE_MAX ]];then
6343 audio_data="$audio_data $alsa_data"
6347 if [[ -n $audio_data ]];then
6348 audio_data=$( create_print_line "$line_starter" "$audio_data" )
6349 print_screen_output "$audio_data"
6354 if [[ -n $alsa_data ]];then
6355 alsa_data=$( sed 's/ALSA/Advanced Linux Sound Architecture/' <<< $alsa_data )
6356 alsa_data=$( create_print_line "$line_starter" "$alsa_data" )
6357 print_screen_output "$alsa_data"
6365 local cpu_data='' i='' cpu_clock_speed='' cpu_multi_clock_data=''
6366 local bmip_data='' cpu_cache='' cpu_vendor='' cpu_flags=''
6368 ##print_screen_output "A_CPU_DATA[0]=\"${A_CPU_DATA[0]}\""
6369 # Array A_CPU_DATA always has one extra element: max clockfreq found.
6370 # that's why its count is one more than you'd think from cores/cpus alone
6375 local a_cpu_working=(${A_CPU_DATA[0]})
6377 local cpu_model="${a_cpu_working[0]}"
6378 ## assemble data for output
6379 local cpu_clock="${a_cpu_working[1]}"
6381 cpu_vendor=${a_cpu_working[5]}
6383 # set A_CPU_CORE_DATA
6385 local cpc_plural='' cpu_count_print='' model_plural=''
6386 local cpu_physical_count=${A_CPU_CORE_DATA[0]}
6387 local cpu_core_count=${A_CPU_CORE_DATA[3]}
6388 local cpu_core_alpha=${A_CPU_CORE_DATA[1]}
6389 local cpu_type=${A_CPU_CORE_DATA[2]}
6391 if [[ $cpu_physical_count -gt 1 ]];then
6393 cpu_count_print="$cpu_physical_count "
6397 local cpu_data_string="${cpu_count_print}${cpu_core_alpha} core"
6398 # Strange (and also some expected) behavior encountered. If print_screen_output() uses $1
6399 # as the parameter to output to the screen, then passing "<text1> ${ARR[@]} <text2>"
6400 # will output only <text1> and first element of ARR. That "@" splits in elements and "*" _doesn't_,
6401 # is to be expected. However, that text2 is consecutively truncated is somewhat strange, so take note.
6402 # This has been confirmed by #bash on freenode.
6403 # The above mentioned only emerges when using the debugging markers below
6404 ## print_screen_output "a_cpu_working=\"***${a_cpu_working[@]} $hostName+++++++\"----------"
6406 if [[ -z ${a_cpu_working[2]} ]];then
6407 a_cpu_working[2]="unknown"
6410 cpu_data=$( create_print_line "CPU$cpc_plural:" "${C1}${cpu_data_string}${C2} ${a_cpu_working[0]}$model_plural (${cpu_type})" )
6411 if [[ $B_SHOW_CPU == 'true' ]];then
6412 # update for multicore, bogomips x core count.
6413 if [[ $B_EXTRA_DATA == 'true' ]];then
6414 # if [[ $cpu_vendor != 'intel' ]];then
6415 bmip_data=$( calculate_multicore_data "${a_cpu_working[4]}" "$(( $cpu_core_count * $cpu_physical_count ))" )
6417 # bmip_data="${a_cpu_working[4]}"
6419 bmip_data=" ${C1}bmips$SEP3${C2} $bmip_data"
6421 ## note: this handles how intel reports L2, total instead of per core like AMD does
6422 # note that we need to multiply by number of actual cpus here to get true cache size
6423 if [[ $cpu_vendor != 'intel' ]];then
6424 cpu_cache=$( calculate_multicore_data "${a_cpu_working[2]}" "$(( $cpu_core_count * $cpu_physical_count ))" )
6426 cpu_cache=$( calculate_multicore_data "${a_cpu_working[2]}" "$cpu_physical_count" )
6428 # only print shortened list
6429 if [[ $B_CPU_FLAGS_FULL != 'true' ]];then
6430 cpu_flags=$( process_cpu_flags "${a_cpu_working[3]}" )
6431 cpu_flags=" ${C1}flags$SEP3${C2} ($cpu_flags)"
6433 cpu_data="$cpu_data${C2} ${C1}cache$SEP3${C2} $cpu_cache$cpu_flags$bmip_data${CN}"
6435 # we don't this printing out extra line unless > 1 cpu core
6436 if [[ ${#A_CPU_DATA[@]} -gt 2 && $B_SHOW_CPU == 'true' ]];then
6437 cpu_clock_speed='' # null < verbosity level 5
6439 cpu_data="$cpu_data ${C1}clocked at${C2} ${a_cpu_working[1]} MHz${CN}"
6442 cpu_data="$cpu_data $cpu_clock_speed"
6443 print_screen_output "$cpu_data"
6445 # we don't this printing out extra line unless > 1 cpu core
6446 if [[ ${#A_CPU_DATA[@]} -gt 2 && $B_SHOW_CPU == 'true' ]];then
6447 for (( i=0; i < ${#A_CPU_DATA[@]}-1; i++ ))
6450 a_cpu_working=(${A_CPU_DATA[i]})
6452 # note: the first iteration will create a first space, for color code separation below
6453 cpu_multi_clock_data="$cpu_multi_clock_data ${C1}$(( i + 1 )):${C2} ${a_cpu_working[1]} MHz${CN}"
6454 # someone actually appeared with a 16 core system, so going to stop the cpu core throttle
6455 # if this had some other purpose which we can't remember we'll add it back in
6456 #if [[ $i -gt 10 ]];then
6460 if [[ -n $cpu_multi_clock_data ]];then
6461 cpu_multi_clock_data=$( create_print_line " " "${C1}Clock Speeds:${C2}$cpu_multi_clock_data" )
6462 print_screen_output "$cpu_multi_clock_data"
6465 if [[ $B_CPU_FLAGS_FULL == 'true' ]];then
6466 print_cpu_flags_full "${a_cpu_working[3]}"
6471 # takes list of all flags, split them and prints x per line
6472 # args: $1 - cpu flag string
6473 print_cpu_flags_full()
6476 local cpu_flags_full="$1" a_cpu_flags='' line_starter=''
6477 local i=0 counter=0 max_length=18 max_length_add=18 flag='' flag_data=''
6479 # build the flag line array
6480 for flag in $cpu_flags_full
6482 a_cpu_flags[$counter]="${a_cpu_flags[$counter]}$flag "
6483 if [[ $i -ge $max_length ]];then
6485 max_length=$(( $max_length + $max_length_add ))
6490 for (( i=0; i < ${#a_cpu_flags[@]};i++ ))
6492 if [[ $i -eq 0 ]];then
6493 line_starter="${C1}CPU Flags$SEP3${C2} "
6497 flag_data=$( create_print_line " " "$line_starter${a_cpu_flags[$i]}" )
6498 print_screen_output "$flag_data"
6506 local gfx_data='' i='' card_id='' root_alert='' root_x_string='' a_gfx_working=''
6507 local b_is_mesa='false' display_full_string='' gfx_bus_id='' gfx_card_data=''
6508 local res_tty='Resolution' xorg_data='' x_vendor_string=''
6509 local spacer='' x_driver='' x_driver_string='' x_driver_plural='' direct_render_string=''
6510 local separator_loaded='' separator_unloaded='' separator_failed=''
6511 local loaded='' unloaded='' failed=''
6512 local line_starter='Graphics:'
6513 local screen_resolution="$( get_graphics_res_data )"
6514 # set A_GFX_CARD_DATA
6515 get_graphics_card_data
6518 local x_vendor=${A_X_DATA[0]}
6519 local x_version=${A_X_DATA[1]}
6521 get_graphics_glx_data
6522 local glx_renderer="${A_GLX_DATA[0]}"
6523 local glx_version="${A_GLX_DATA[1]}"
6524 # this can contain a long No case debugging message, so it's being sliced off
6525 # note: using grep -ioE '(No|Yes)' <<< ${A_GLX_DATA[2]} did not work in Arch, no idea why
6526 local glx_direct_render=$( gawk '{print $1}' <<< "${A_GLX_DATA[2]}" )
6528 # set A_GRAPHIC_DRIVERS
6531 if [[ ${#A_GRAPHIC_DRIVERS[@]} -eq 0 ]];then
6534 for (( i=0; i < ${#A_GRAPHIC_DRIVERS[@]}; i++ ))
6537 a_gfx_working=( ${A_GRAPHIC_DRIVERS[i]} )
6539 case ${a_gfx_working[1]} in
6541 loaded="$loaded$separator_loaded${a_gfx_working[0]}"
6542 separator_loaded=','
6545 unloaded="$unloaded$separator_unloaded${a_gfx_working[0]}"
6546 separator_unloaded=','
6549 failed="$failed$separator_failed${a_gfx_working[0]}"
6550 separator_failed=','
6555 if [[ -n $loaded ]];then
6556 x_driver="${x_driver} $loaded"
6558 if [[ -n $unloaded ]];then
6559 x_driver="${x_driver} (unloaded: $unloaded)"
6561 if [[ -n $failed ]];then
6562 x_driver="${x_driver} ${RED}FAILED:${C2} $failed"
6565 if [[ ${#A_GRAPHIC_DRIVERS[@]} -gt 1 ]];then
6568 x_driver_string="${C1}driver$x_driver_plural$SEP3${C2}$x_driver "
6570 # some basic error handling:
6571 if [[ -z $screen_resolution ]];then
6572 screen_resolution='N/A'
6574 if [[ -z $x_vendor || -z $x_version ]];then
6575 x_vendor_string="${C1}X-Vendor:${C2} N/A "
6577 x_vendor_string="${C1}$x_vendor$SEP3${C2} $x_version "
6580 if [[ $B_ROOT == 'true' ]];then
6581 root_x_string='for root '
6582 if [[ $B_RUNNING_IN_SHELL == 'true' || $B_CONSOLE_IRC == 'true' ]];then
6586 if [[ $B_RUNNING_IN_X != 'true' ]];then
6587 root_x_string="${root_x_string}out of X"
6591 if [[ -n $root_x_string ]];then
6592 root_x_string="${C1}Advanced Data:${C2} N/A $root_x_string"
6595 display_full_string="$x_vendor_string$x_driver_string${C1}${res_tty}$SEP3${C2} ${screen_resolution} $root_x_string"
6597 if [[ ${#A_GFX_CARD_DATA[@]} -gt 0 ]];then
6598 for (( i=0; i < ${#A_GFX_CARD_DATA[@]}; i++ ))
6601 a_gfx_working=( ${A_GFX_CARD_DATA[i]} )
6604 gfx_card_data=${a_gfx_working[0]}
6605 if [[ $B_EXTRA_DATA == 'true' ]];then
6606 if [[ -n ${a_gfx_working[1]} ]];then
6607 gfx_bus_id=" ${C1}bus-ID$SEP3${C2} ${a_gfx_working[1]}"
6609 gfx_bus_id=" ${C1}bus-ID$SEP3${C2} N/A"
6612 if [[ ${#A_GFX_CARD_DATA[@]} -gt 1 ]];then
6613 card_id="Card-$(($i+1)):"
6617 gfx_data="${C1}$card_id${C2} $gfx_card_data$gfx_bus_id "
6618 if [[ ${#A_GFX_CARD_DATA[@]} -gt 1 ]];then
6619 gfx_data=$( create_print_line "$line_starter" "${gfx_data}" )
6620 print_screen_output "$gfx_data"
6625 # handle cases where card detection fails, like in PS3, where lspci gives no output, or headless boxes..
6627 gfx_data="${C1}Card:${C2} Failed to Detect Video Card! "
6629 if [[ -n $gfx_data && $( calculate_line_length "${gfx_data}$display_full_string" ) -lt $LINE_MAX ]];then
6630 gfx_data=$( create_print_line "$line_starter" "${gfx_data}$display_full_string" )
6632 if [[ -n $gfx_data ]];then
6633 gfx_data=$( create_print_line "$line_starter" "$gfx_data" )
6634 print_screen_output "$gfx_data"
6637 gfx_data=$( create_print_line "$line_starter" "$display_full_string" )
6639 print_screen_output "$gfx_data"
6640 # if [[ -z $glx_renderer || -z $glx_version ]];then
6644 ## note: if glx render or version have no content, then mesa is true
6645 # if [[ $B_SHOW_X_DATA == 'true' ]] && [[ $b_is_mesa != 'true' ]];then
6646 if [[ $B_SHOW_X_DATA == 'true' && $B_ROOT != 'true' ]];then
6647 if [[ -z $glx_renderer ]];then
6650 if [[ -z $glx_version ]];then
6653 if [[ -z $glx_direct_render ]];then
6654 glx_direct_render='N/A'
6656 if [[ $B_HANDLE_CORRUPT_DATA == 'true' || $B_EXTRA_DATA == 'true' ]];then
6657 direct_render_string=" ${C1}Direct Rendering$SEP3${C2} ${glx_direct_render}${CN}"
6659 gfx_data="${C1}GLX Renderer$SEP3${C2} ${glx_renderer} ${C1}GLX Version$SEP3${C2} ${glx_version}${CN}$direct_render_string"
6660 gfx_data=$( create_print_line " " "$gfx_data" )
6662 print_screen_output "$gfx_data"
6667 print_hard_disk_data()
6670 local hdd_data='' hdd_data_2='' a_hdd_working='' hdd_temp_data='' hdd_string=''
6671 local dev_data='' size_data='' hdd_model='' usb_data='' hdd_name='' divisor=5
6672 local Line_Starter='Drives:' # inherited by print_optical_drives
6676 ## note: if hdd_model is declared prior to use, whatever string you want inserted will
6677 ## be inserted first. In this case, it's desirable to print out (x) before each disk found.
6678 local a_hdd_data_count=$(( ${#A_HDD_DATA[@]} - 1 ))
6680 local a_hdd_basic_working=( ${A_HDD_DATA[$a_hdd_data_count]} )
6682 local hdd_capacity=${a_hdd_basic_working[0]}
6683 local hdd_used=${a_hdd_basic_working[1]}
6685 if [[ $B_SHOW_BASIC_DISK == 'true' || $B_SHOW_DISK == 'true' ]];then
6686 ## note: the output part of this should be in the print hdd data function, not here
6687 get_hard_drive_data_advanced
6688 for (( i=0; i < ${#A_HDD_DATA[@]} - 1; i++ ))
6690 # this adds the (x) numbering in front of each disk found, and creates the full disk string
6692 a_hdd_working=( ${A_HDD_DATA[i]} )
6694 if [[ $B_SHOW_DISK == 'true' ]];then
6695 if [[ -n ${a_hdd_working[3]} ]];then
6696 usb_data="${a_hdd_working[3]} "
6700 dev_data="/dev/${a_hdd_working[0]} "
6701 size_data=" ${a_hdd_working[1]}"
6702 if [[ $B_EXTRA_DATA == 'true' && -n $dev_data ]];then
6703 hdd_temp_data=$( get_hdd_temp_data "$dev_data" )
6704 # error handling is done in get data function
6705 if [[ -n $hdd_temp_data ]];then
6706 hdd_temp_data=" ${hdd_temp_data}C"
6711 divisor=2 # for modulus line print out, either 2 items for full, or default for short
6713 hdd_name="${a_hdd_working[2]}"
6714 hdd_string="$usb_data$dev_data$hdd_name$size_data$hdd_temp_data"
6715 hdd_model="${hdd_model}${C1}$(($i+1)):${C2} $hdd_string "
6716 # printing line one, then new lines according to $divisor setting, and after, if leftovers, print that line.
6719 hdd_data=$( create_print_line "$Line_Starter" "${C1}HDD Total Size:${C2} ${hdd_capacity} (${hdd_used}) ${hdd_model}" )
6720 print_screen_output "$hdd_data"
6725 # using modulus here, if divisible by $divisor, print line, otherwise skip
6726 if [[ $(( $i % $divisor )) -eq 0 ]];then
6727 hdd_data=$( create_print_line "$Line_Starter" "${hdd_model}${CN}" )
6728 print_screen_output "$hdd_data"
6735 # then print any leftover items
6736 if [[ -n $hdd_model ]];then
6737 hdd_data=$( create_print_line "$Line_Starter" "${hdd_model}${CN}" )
6738 print_screen_output "$hdd_data"
6741 hdd_data=$( create_print_line "$Line_Starter" "${C1}HDD Total Size:${C2} ${hdd_capacity} (${hdd_used})${CN}" )
6742 print_screen_output "$hdd_data"
6745 if [[ $B_SHOW_FULL_OPTICAL == 'true' || $B_SHOW_BASIC_OPTICAL == 'true' ]];then
6746 print_optical_drive_data
6756 local info_data='' line_starter='Info:'
6757 local runlvl='' client_data=''
6758 local memory="$( get_memory_data )"
6759 local processes="$(( $( ps aux | wc -l ) - 1 ))"
6760 local up_time="$( get_uptime )"
6761 local script_patch_number=$( get_patch_version_string )
6762 local gcc_string='' gcc_installed='' gcc_others='' closing_data=''
6764 if [[ $B_EXTRA_DATA == 'true' ]];then
6765 get_gcc_system_version
6766 if [[ ${#A_GCC_VERSIONS[@]} -gt 0 ]];then
6767 if [[ -n ${A_GCC_VERSIONS[0]} ]];then
6768 gcc_installed=${A_GCC_VERSIONS[0]}
6772 if [[ $B_EXTRA_EXTRA_DATA == 'true' && -n ${A_GCC_VERSIONS[1]} ]];then
6773 gcc_others=" ${C1}alt$SEP3${C2} $( tr ',' '/' <<< ${A_GCC_VERSIONS[1]} )"
6775 gcc_installed="${C1}Gcc sys$SEP3${C2} $gcc_installed$gcc_others "
6779 # Some code could look superfluous but BitchX doesn't like lines not ending in a newline. F*&k that bitch!
6780 # long_last=$( echo -ne "${C1}Processes$SEP3${C2} ${processes}${CN} | ${C1}Uptime$SEP3${C2} ${up_time}${CN} | ${C1}Memory$SEP3${C2} ${MEM}${CN}" )
6781 info_data="${C1}Processes$SEP3${C2} ${processes} ${C1}Uptime$SEP3${C2} ${up_time} ${C1}Memory$SEP3${C2} ${memory}${CN} "
6783 # this only triggers if no X data is present or if extra data switch is on
6784 if [[ $B_SHOW_X_DATA != 'true' || $B_EXTRA_DATA == 'true' ]];then
6785 runlvl="$( get_runlevel_data )"
6786 if [[ -n $runlvl ]];then
6787 info_data="${info_data}${C1}Runlevel$SEP3${C2} ${runlvl} "
6790 if [[ $SHOW_IRC -gt 0 ]];then
6791 client_data="${C1}Client$SEP3${C2} ${IRC_CLIENT}${IRC_CLIENT_VERSION} "
6793 info_data="${info_data}$gcc_installed"
6794 closing_data="$client_data${C1}$SCRIPT_NAME$SEP3${C2} $SCRIPT_VERSION_NUMBER$script_patch_number${CN}"
6795 if [[ -n $info_data && $( calculate_line_length "$info_data$closing_data" ) -gt $LINE_MAX ]];then
6796 info_data=$( create_print_line "$line_starter" "$info_data" )
6797 print_screen_output "$info_data"
6798 info_data="$closing_data"
6801 info_data="${info_data}$closing_data"
6803 info_data=$( create_print_line "$line_starter" "$info_data" )
6804 if [[ $SCHEME -gt 0 ]];then
6805 info_data="${info_data} ${NORMAL}"
6807 print_screen_output "$info_data"
6811 print_machine_data()
6815 local system_line='' mobo_line='' bios_line='' chassis_line=''
6816 local mobo_vendor='' mobo_model='' mobo_version='' mobo_serial=''
6817 local bios_vendor='' bios_version='' bios_date=''
6818 local system_vendor='' product_name='' product_version='' product_serial='' product_uuid=''
6819 local chassis_vendor='' chassis_type='' chassis_version='' chassis_serial=''
6820 local b_skip_system='false' b_skip_chassis='false'
6821 # set A_MACHINE_DATA
6825 ## keys for machine data are:
6826 # 0-sys_vendor 1-product_name 2-product_version 3-product_serial 4-product_uuid
6827 # 5-board_vendor 6-board_name 7-board_version 8-board_serial
6828 # 9-bios_vendor 10-bios_version 11-bios_date
6830 # 12-chassis_vendor 13-chassis_type 14-chassis_version 15-chassis_serial
6832 if [[ ${#A_MACHINE_DATA[@]} -gt 0 ]];then
6833 # note: in some case a mobo/version will match a product name/version, do not print those
6834 # but for laptops, or even falsely id'ed desktops with batteries, let's print it all if it matches
6835 # there can be false id laptops if battery appears so need to make sure system is filled
6836 if [[ -z ${A_MACHINE_DATA[0]} ]];then
6837 b_skip_system='true'
6839 if [[ $B_PORTABLE != 'true' ]];then
6840 # ibm / ibm can be true; dell / quantum is false, so in other words, only do this
6841 # in case where the vendor is the same and the version is the same and not null,
6842 # otherwise the version information is going to be different in all cases I think
6843 if [[ -n ${A_MACHINE_DATA[0]} && ${A_MACHINE_DATA[0]} == ${A_MACHINE_DATA[5]} ]];then
6844 if [[ -n ${A_MACHINE_DATA[2]} && ${A_MACHINE_DATA[2]} == ${A_MACHINE_DATA[7]} ]] || \
6845 [[ -z ${A_MACHINE_DATA[2]} && ${A_MACHINE_DATA[1]} == ${A_MACHINE_DATA[6]} ]];then
6846 b_skip_system='true'
6851 # no point in showing chassis if system isn't there, it's very unlikely that would be correct
6852 if [[ $B_EXTRA_EXTRA_DATA == 'true' && $b_skip_system != 'true' ]];then
6853 if [[ -n ${A_MACHINE_DATA[7]} && ${A_MACHINE_DATA[14]} == ${A_MACHINE_DATA[7]} ]];then
6854 b_skip_chassis='true'
6856 if [[ -n ${A_MACHINE_DATA[12]} && $b_skip_chassis != 'true' ]];then
6857 # no need to print the vendor string again if it's the same
6858 if [[ ${A_MACHINE_DATA[12]} != ${A_MACHINE_DATA[0]} ]];then
6859 chassis_vendor=" ${A_MACHINE_DATA[12]}"
6861 if [[ -n ${A_MACHINE_DATA[13]} ]];then
6862 chassis_type=" ${C1}type$SEP3${C2} ${A_MACHINE_DATA[13]}"
6864 if [[ -n ${A_MACHINE_DATA[14]} ]];then
6865 chassis_version=" ${C1}version$SEP3${C2} ${A_MACHINE_DATA[14]}"
6867 if [[ -n ${A_MACHINE_DATA[15]} && $B_OUTPUT_FILTER != 'true' ]];then
6868 chassis_serial=" ${C1}serial$SEP3${C2} ${A_MACHINE_DATA[15]}"
6870 if [[ -n "$chassis_vendor$chassis_type$chassis_version$chassis_serial" ]];then
6871 chassis_line="${C1}Chassis$SEP3${C2}$chassis_vendor$chassis_type$chassis_version$chassis_serial"
6875 if [[ -n ${A_MACHINE_DATA[5]} ]];then
6876 mobo_vendor=${A_MACHINE_DATA[5]}
6880 if [[ -n ${A_MACHINE_DATA[6]} ]];then
6881 mobo_model=${A_MACHINE_DATA[6]}
6885 if [[ -n ${A_MACHINE_DATA[7]} ]];then
6886 mobo_version=" ${C1}version$SEP3${C2} ${A_MACHINE_DATA[7]}"
6888 if [[ -n ${A_MACHINE_DATA[8]} && $B_OUTPUT_FILTER != 'true' ]];then
6889 mobo_serial=" ${C1}serial$SEP3${C2} ${A_MACHINE_DATA[8]}"
6891 if [[ -n ${A_MACHINE_DATA[9]} ]];then
6892 bios_vendor=${A_MACHINE_DATA[9]}
6896 if [[ -n ${A_MACHINE_DATA[10]} ]];then
6897 bios_version=${A_MACHINE_DATA[10]}
6901 if [[ -n ${A_MACHINE_DATA[11]} ]];then
6902 bios_date=${A_MACHINE_DATA[11]}
6906 mobo_line="${C1}Mobo$SEP3${C2} $mobo_vendor ${C1}model$SEP3${C2} $mobo_model$mobo_version$mobo_serial"
6907 bios_line="${C1}Bios$SEP3${C2} $bios_vendor ${C1}version$SEP3${C2} $bios_version ${C1}date$SEP3${C2} $bios_date"
6908 if [[ $( calculate_line_length "$mobo_line$bios_line" ) -lt $LINE_MAX ]];then
6909 mobo_line="$mobo_line $bios_line"
6912 if [[ $b_skip_system == 'true' ]];then
6913 system_line=$mobo_line
6916 # this has already been tested for above so we know it's not null
6917 system_vendor=${A_MACHINE_DATA[0]}
6918 if [[ $B_PORTABLE == 'true' ]];then
6919 system_vendor="$system_vendor (portable)"
6921 if [[ -n ${A_MACHINE_DATA[1]} ]];then
6922 product_name=${A_MACHINE_DATA[1]}
6926 if [[ -n ${A_MACHINE_DATA[2]} ]];then
6927 product_version=" ${C1}version$SEP3${C2} ${A_MACHINE_DATA[2]}"
6929 if [[ -n ${A_MACHINE_DATA[3]} && $B_OUTPUT_FILTER != 'true' ]];then
6930 product_serial=" ${C1}serial$SEP3${C2} ${A_MACHINE_DATA[3]} "
6932 system_line="${C1}System$SEP3${C2} $system_vendor ${C1}product$SEP3${C2} $product_name$product_version$product_serial"
6933 if [[ -n $chassis_line && $( calculate_line_length "$system_line$chassis_line" ) -lt $LINE_MAX ]];then
6934 system_line="$system_line $chassis_line"
6940 system_line="${C2}No /sys/class/dmi machine data. Try newer kernel, or install dmidecode.${CN}"
6942 # patch to dump all of above if dmidecode was data source and non root user
6943 if [[ ${A_MACHINE_DATA[0]} == 'dmidecode-non-root-user' || ${A_MACHINE_DATA[0]} == 'dmidecode-no-smbios-dmi-data' ]];then
6944 if [[ ${A_MACHINE_DATA[0]} == 'dmidecode-non-root-user' ]];then
6945 system_line="${C2}No /sys/class/dmi. Using dmidecode: you must be root to run dmidecode.${CN}"
6946 elif [[ ${A_MACHINE_DATA[0]} == 'dmidecode-no-smbios-dmi-data' ]];then
6947 system_line="${C2}No /sys/class/dmi. Using dmidecode: no machine data available.${CN}"
6953 system_line=$( create_print_line "Machine:" "$system_line" )
6954 print_screen_output "$system_line"
6955 if [[ -n $mobo_line ]];then
6956 mobo_line=$( create_print_line " " "$mobo_line" )
6957 print_screen_output "$mobo_line"
6959 if [[ -n $bios_line ]];then
6960 bios_line=$( create_print_line " " "$bios_line" )
6961 print_screen_output "$bios_line"
6963 if [[ -n $chassis_line ]];then
6964 chassis_line=$( create_print_line " " "$chassis_line" )
6965 print_screen_output "$chassis_line"
6971 # args: $1 - module name (could be > 1, so loop it ); $2 - audio (optional)
6972 print_module_version()
6975 local module_versions='' module='' version='' prefix='' modules=$1
6977 # note that sound driver data tends to have upper case, but modules are lower
6978 if [[ $2 == 'audio' ]];then
6979 if [[ -z $( grep -E '^snd' <<< $modules ) ]];then
6980 prefix='snd_' # sound modules start with snd_
6982 modules=$( tr '[A-Z]' '[a-z]' <<< $modules )
6983 modules=$( tr '-' '_' <<< $modules )
6984 # special intel processing, generally no version info though
6985 if [[ $modules == 'hda intel' ]];then
6987 elif [[ $modules == 'intel ich' ]];then
6992 for module in $modules
6994 version=$( get_module_version_number "$prefix$module" )
6995 if [[ -n $version ]];then
6996 module_versions="$module_versions $version"
7000 if [[ -n $module_versions ]];then
7001 echo " ${C1}ver$SEP3${C2}$module_versions"
7006 print_networking_data()
7009 local i='' card_id='' network_data='' a_network_working='' port_data='' driver_data=''
7010 local card_string='' port_plural='' module_version='' pci_bus_id='' bus_usb_text=''
7011 local bus_usb_id='' line_starter='Network:' card_string='' card_data=''
7012 # set A_NETWORK_DATA
7015 # will never be null because null is handled in get_network_data, but in case we change
7016 # that leaving this test in place.
7017 if [[ -n ${A_NETWORK_DATA[@]} ]];then
7018 for (( i=0; i < ${#A_NETWORK_DATA[@]}; i++ ))
7021 a_network_working=( ${A_NETWORK_DATA[i]} )
7034 if [[ ${#A_NETWORK_DATA[@]} -gt 1 ]];then
7035 card_id="-$(( $i + 1 ))"
7037 if [[ -n ${a_network_working[1]} && $B_EXTRA_DATA == 'true' ]];then
7038 module_version=$( print_module_version "${a_network_working[1]}" )
7040 if [[ -n ${a_network_working[1]} ]];then
7041 driver_data="${C1}driver$SEP3${C2} ${a_network_working[1]}$module_version "
7043 if [[ -n ${a_network_working[2]} && $B_EXTRA_DATA == 'true' ]];then
7044 if [[ $( wc -w <<< ${a_network_working[2]} ) -gt 1 ]];then
7047 port_data="${C1}port$port_plural$SEP3${C2} ${a_network_working[2]} "
7049 if [[ -n ${a_network_working[4]} && $B_EXTRA_DATA == 'true' ]];then
7050 if [[ -z $( grep '^usb-' <<< ${a_network_working[4]} ) ]];then
7051 bus_usb_text='bus-ID'
7052 bus_usb_id=${a_network_working[4]}
7054 bus_usb_text='usb-ID'
7055 bus_usb_id=$( cut -d '-' -f '2-4' <<< ${a_network_working[4]} )
7057 pci_bus_id="${C1}$bus_usb_text$SEP3${C2} $bus_usb_id"
7059 card_string="${C1}Card$card_id:${C2} ${a_network_working[0]} "
7060 card_data="$driver_data$port_data$pci_bus_id"
7061 if [[ $( calculate_line_length "$card_string$card_data" ) -gt $LINE_MAX ]];then
7062 network_data=$( create_print_line "$line_starter" "$card_string" )
7065 print_screen_output "$network_data"
7067 network_data=$( create_print_line "$line_starter" "$card_string$card_data" )
7069 print_screen_output "$network_data"
7070 if [[ $B_SHOW_ADVANCED_NETWORK == 'true' ]];then
7071 print_network_advanced_data
7075 if [[ $B_SHOW_IP == 'true' ]];then
7076 print_networking_ip_data
7081 print_network_advanced_data()
7084 local network_data='' if_id='N/A' duplex='N/A' mac_id='N/A' speed='N/A' oper_state='N/A'
7085 local b_is_wifi='false' speed_string='' duplex_string=''
7087 # first check if it's a known wifi id'ed card, if so, no print of duplex/speed
7088 if [[ -n $( grep -Esi '(wireless|wifi|wi-fi|wlan|802\.11|centrino)' <<< ${a_network_working[0]} ) ]];then
7091 if [[ -n ${a_network_working[5]} ]];then
7092 if_id=${a_network_working[5]}
7094 if [[ -n ${a_network_working[6]} ]];then
7095 oper_state=${a_network_working[6]}
7097 # no print out for wifi since it doesn't have duplex/speed data availabe
7098 # note that some cards show 'unknown' for state, so only testing explicitly
7099 # for 'down' string in that to skip showing speed/duplex
7100 if [[ $b_is_wifi != 'true' && $oper_state != 'down' ]];then
7101 if [[ -n ${a_network_working[7]} ]];then
7102 # make sure the value is strictly numeric before appending Mbps
7103 if [[ -n $( grep -E '^[0-9\.,]+$' <<< "${a_network_working[7]}" ) ]];then
7104 speed="${a_network_working[7]} Mbps"
7106 speed=${a_network_working[7]}
7109 speed_string="${C1}speed$SEP3${C2} $speed "
7110 if [[ -n ${a_network_working[8]} ]];then
7111 duplex=${a_network_working[8]}
7113 duplex_string="${C1}duplex$SEP3${C2} $duplex "
7115 if [[ -n ${a_network_working[9]} ]];then
7116 if [[ $B_OUTPUT_FILTER == 'true' ]];then
7117 mac_id=$FILTER_STRING
7119 mac_id=${a_network_working[9]}
7122 network_data="${C1}IF:${C2} $if_id ${C1}state$SEP3${C2} $oper_state $speed_string$duplex_string${C1}mac$SEP3${C2} $mac_id"
7123 network_data=$( create_print_line " " "$network_data" )
7124 print_screen_output "$network_data"
7129 print_networking_ip_data()
7132 local ip=$( get_networking_wan_ip_data )
7133 local wan_ip_data='' a_interfaces_working='' interfaces='' i=''
7134 local if_id='' if_ip='' if_ipv6='' if_ipv6_string='' full_string='' if_string=''
7135 local if_id_string='' if_ip_string=''
7136 local line_max=$(( $LINE_MAX - 50 ))
7138 # set A_INTERFACES_DATA
7139 get_networking_local_ip_data
7140 # first print output for wan ip line. Null is handled in the get function
7141 if [[ -z $ip ]];then
7144 if [[ $B_OUTPUT_FILTER == 'true' ]];then
7148 wan_ip_data="${C1}WAN IP:${C2} $ip "
7149 # then create the list of local interface/ip
7150 i=0 ## loop starts with 1 by auto-increment so it only shows cards > 1
7151 while [[ -n ${A_INTERFACES_DATA[i]} ]]
7154 a_interfaces_working=(${A_INTERFACES_DATA[i]})
7160 if [[ -z $( grep '^Interface' <<< ${a_interfaces_working[0]} ) ]];then
7161 if [[ -n ${a_interfaces_working[1]} ]];then
7162 if [[ $B_OUTPUT_FILTER == 'true' ]];then
7163 if_ip=$FILTER_STRING
7165 if_ip=${a_interfaces_working[1]}
7168 if_ip_string=" ${C1}ip$SEP3${C2} $if_ip"
7169 if [[ $B_EXTRA_DATA == 'true' ]];then
7170 if [[ -n ${a_interfaces_working[3]} ]];then
7171 if [[ $B_OUTPUT_FILTER == 'true' ]];then
7172 if_ipv6=$FILTER_STRING
7174 if_ipv6=${a_interfaces_working[3]}
7177 if_ipv6_string=" ${C1}ip-v6$SEP3${C2} $if_ipv6"
7180 if [[ -n ${a_interfaces_working[0]} ]];then
7181 if_id=${a_interfaces_working[0]}
7183 if_string="$wan_ip_data$if_string${C1}IF:${C2} $if_id$if_ip_string$if_ipv6_string "
7185 if [[ $( calculate_line_length "$if_string" ) -gt $line_max ]];then
7186 full_string=$( create_print_line " " "$if_string" )
7187 print_screen_output "$full_string"
7193 # then print out anything not printed already
7194 if [[ -n $if_string ]];then
7195 full_string=$( create_print_line " " "$if_string" )
7196 print_screen_output "$full_string"
7201 print_optical_drive_data()
7204 local a_drives='' drive_data='' counter=''
7205 local drive_id='' drive_links='' vendor='' speed='' multisession='' mcn='' audio=''
7206 local dvd='' state='' rw_support='' rev='' separator='' drive_string=''
7207 get_optical_drive_data
7208 # 0 - true dev path, ie, sr0, hdc
7209 # 1 - dev links to true path
7210 # 2 - device vendor - for hdx drives, vendor model are one string from proc
7212 # 4 - device rev version
7213 if [[ ${#A_OPTICAL_DRIVE_DATA[@]} -gt 0 ]];then
7214 for (( i=0; i < ${#A_OPTICAL_DRIVE_DATA[@]}; i++ ))
7217 a_drives=(${A_OPTICAL_DRIVE_DATA[i]})
7232 if [[ ${#A_OPTICAL_DRIVE_DATA[@]} -eq 1 && -z ${a_drives[0]} && -z ${a_drives[1]} ]];then
7233 drive_string="No optical drives detected."
7234 B_SHOW_FULL_OPTICAL='false'
7236 if [[ ${#A_OPTICAL_DRIVE_DATA[@]} -gt 1 ]];then
7237 counter="-$(( i + 1 ))"
7239 if [[ -z ${a_drives[0]} ]];then
7242 drive_id="/dev/${a_drives[0]}"
7244 drive_links=$( sed 's/~/,/g' <<< ${a_drives[1]} )
7245 if [[ -z $drive_links ]];then
7248 if [[ -n ${a_drives[2]} ]];then
7249 vendor=${a_drives[2]}
7250 if [[ -n ${a_drives[3]} ]];then
7251 vendor="$vendor ${a_drives[3]}"
7254 if [[ -z $vendor ]];then
7255 if [[ -n ${a_drives[3]} ]];then
7256 vendor=${a_drives[3]}
7261 if [[ $B_EXTRA_DATA == 'true' ]];then
7262 if [[ -n ${a_drives[4]} ]];then
7267 rev=" ${C1}rev$SEP3${C2} $rev"
7269 drive_string="$drive_id ${C1}model$SEP3${C2} $vendor$rev ${C1}dev-links$SEP3${C2} $drive_links"
7271 drive_data="${C1}Optical${counter}:${C2} $drive_string"
7272 drive_data=$( create_print_line "$Line_Starter" "$drive_data" )
7273 print_screen_output "$drive_data"
7276 # 6 - multisession support
7285 if [[ $B_SHOW_FULL_OPTICAL == 'true' ]];then
7286 if [[ -z ${a_drives[5]} ]];then
7289 speed="${a_drives[5]}x"
7291 if [[ -z ${a_drives[8]} ]];then
7293 elif [[ ${a_drives[8]} == 1 ]];then
7298 audio=" ${C1}audio$SEP3${C2} $audio"
7299 if [[ -z ${a_drives[6]} ]];then
7301 elif [[ ${a_drives[6]} == 1 ]];then
7306 multisession=" ${C1}multisession$SEP3${C2} $multisession"
7307 if [[ -z ${a_drives[11]} ]];then
7309 elif [[ ${a_drives[11]} == 1 ]];then
7314 if [[ $B_EXTRA_DATA == 'true' ]];then
7315 if [[ -z ${a_drives[14]} ]];then
7318 state="${a_drives[14]}"
7320 state=" ${C1}state$SEP3${C2} $state"
7322 if [[ -n ${a_drives[9]} && ${a_drives[9]} == 1 ]];then
7326 if [[ -n ${a_drives[10]} && ${a_drives[10]} == 1 ]];then
7327 rw_support="${rw_support}${separator}cd-rw"
7330 if [[ -n ${a_drives[12]} && ${a_drives[12]} == 1 ]];then
7331 rw_support="${rw_support}${separator}dvd-r"
7334 if [[ -n ${a_drives[13]} && ${a_drives[13]} == 1 ]];then
7335 rw_support="${rw_support}${separator}dvd-ram"
7338 if [[ -z $rw_support ]];then
7342 drive_data="${C1}Features: speed$SEP3${C2} $speed$multisession$audio ${C1}dvd$SEP3${C2} $dvd ${C1}rw$SEP3${C2} $rw_support$state"
7343 drive_data=$( create_print_line "$Line_Starter" "$drive_data" )
7344 print_screen_output "$drive_data"
7353 print_partition_data()
7356 local a_partition_working='' partition_used='' partition_data=''
7357 local counter=0 i=0 a_partition_data='' line_starter='' line_max=$(( $LINE_MAX - 35 ))
7358 local partitionIdClean='' part_dev='' full_dev='' part_label='' full_label=''
7359 local part_uuid='' full_uuid='' dev_remote='' full_fs='' line_max_label_uuid=$(( $LINE_MAX - 10 ))
7361 # set A_PARTITION_DATA
7364 for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
7367 a_partition_working=(${A_PARTITION_DATA[i]})
7372 if [[ $B_SHOW_PARTITIONS_FULL == 'true' ]] || [[ ${a_partition_working[4]} == 'main' ]];then
7373 if [[ -n ${a_partition_working[2]} ]];then
7374 partition_used="${C1}used$SEP3${C2} ${a_partition_working[2]} (${a_partition_working[3]}) "
7376 partition_used='' # reset partition used to null
7378 if [[ -n ${a_partition_working[5]} ]];then
7379 full_fs="${a_partition_working[5]}"
7381 full_fs='N/A' # reset partition used to null
7383 full_fs="${C1}fs$SEP3${C2} $full_fs "
7385 if [[ $B_SHOW_LABELS == 'true' || $B_SHOW_UUIDS == 'true' ]];then
7386 if [[ -n ${a_partition_working[6]} ]];then
7387 if [[ -z $( grep -E '(^//|:/)' <<< ${a_partition_working[6]} ) ]];then
7388 part_dev="/dev/${a_partition_working[6]}"
7391 part_dev="${a_partition_working[6]}"
7398 full_dev="${C1}$dev_remote$SEP3${C2} $part_dev "
7399 if [[ $B_SHOW_LABELS == 'true' && $dev_remote != 'remote' ]];then
7400 if [[ -n ${a_partition_working[7]} ]];then
7401 part_label="${a_partition_working[7]}"
7405 full_label="${C1}label$SEP3${C2} $part_label "
7407 if [[ $B_SHOW_UUIDS == 'true' && $dev_remote != 'remote' ]];then
7408 if [[ -n ${a_partition_working[8]} ]];then
7409 part_uuid="${a_partition_working[8]}"
7413 full_uuid="${C1}uuid$SEP3${C2} $part_uuid"
7416 # don't show user names in output
7417 if [[ $B_OUTPUT_FILTER == 'true' ]];then
7418 partitionIdClean=$( sed -r "s|/home/([^/]+)/(.*)|/home/$FILTER_STRING/\2|" <<< ${a_partition_working[0]} )
7420 partitionIdClean=${a_partition_working[0]}
7422 id_size_fs="${C1}ID:${C2} $partitionIdClean ${C1}size$SEP3${C2} ${a_partition_working[1]} $partition_used$full_fs$full_dev"
7423 label_uuid="$full_label$full_uuid"
7424 # label/uuid always print one per line, so only wrap if it's very long
7425 if [[ $B_SHOW_UUIDS == 'true' && $B_SHOW_LABELS == 'true' && $( calculate_line_length "$id_size_fs$label_uuid" ) -gt $line_max_label_uuid ]];then
7426 a_partition_data[$counter]="$id_size_fs"
7428 a_partition_data[$counter]="$label_uuid"
7430 a_partition_data[$counter]="${a_partition_data[$counter]}$id_size_fs$label_uuid"
7432 # because these lines can vary widely, using dynamic length handling here
7433 if [[ $B_SHOW_LABELS == 'true' || $B_SHOW_UUIDS == 'true' ]] || [[ $( calculate_line_length "${a_partition_data[$counter]}" ) -gt $line_max ]];then
7438 # print out all lines, line starter on first line
7439 for (( i=0; i < ${#a_partition_data[@]};i++ ))
7441 if [[ $i -eq 0 ]];then
7442 line_starter='Partition:'
7446 partition_data=$( create_print_line "$line_starter" "${a_partition_data[$i]}" )
7447 print_screen_output "$partition_data"
7457 local b_print_first='true'
7459 if [[ $B_SHOW_PS_CPU_DATA == 'true' ]];then
7461 print_ps_item 'cpu' "$b_print_first"
7462 b_print_first='false'
7464 if [[ $B_SHOW_PS_MEM_DATA == 'true' ]];then
7466 print_ps_item 'mem' "$b_print_first"
7472 # args: $1 - cpu/mem; $2 true/false
7476 local a_ps_data='' ps_data='' line_starter='' line_start_data='' full_line=''
7477 local app_name='' app_pid='' app_cpu='' app_mem='' throttled='' app_daemon=''
7478 local b_print_first=$2 line_counter=0 i=0 count_nu='' extra_data=''
7480 if [[ -n $PS_THROTTLED ]];then
7481 throttled=" ${C1} - throttled from${C2} $PS_THROTTLED"
7485 line_start_data="${C1}CPU - % used - top ${C2} $PS_COUNT ${C1}active$throttled "
7488 line_start_data="${C1}Memory - MB / % used - top ${C2} $PS_COUNT ${C1}active$throttled"
7492 if [[ $b_print_first == 'true' ]];then
7493 line_starter='Processes:'
7498 # appName, appPath, appStarterName, appStarterPath, cpu, mem, pid, vsz, user
7499 ps_data=$( create_print_line "$line_starter" "$line_start_data" )
7500 print_screen_output "$ps_data"
7502 for (( i=0; i < ${#A_PS_DATA[@]}; i++ ))
7505 a_ps_data=(${A_PS_DATA[i]})
7508 # handle the converted app names, with ~..~ means it didn't have a path
7509 if [[ -n $( grep -E '^~.*~$' <<< ${a_ps_data[0]} ) ]];then
7512 app_daemon='command'
7515 app_name=" ${C1}$app_daemon$SEP3${C2} ${a_ps_data[0]}"
7516 if [[ ${a_ps_data[0]} != ${a_ps_data[2]} ]];then
7517 app_name="$app_name ${C1}(started by$SEP3${C2} ${a_ps_data[2]}${C1})${C2}"
7519 app_pid=" ${C1}pid$SEP3${C2} ${a_ps_data[6]}"
7520 # ${C1}user:${C2} ${a_ps_data[8]}
7523 app_cpu=" ${C1}cpu$SEP3${C2} ${a_ps_data[4]}%"
7524 if [[ $B_EXTRA_DATA == 'true' ]];then
7525 extra_data=" ${C1}mem$SEP3${C2} ${a_ps_data[7]}MB (${a_ps_data[5]}%)${C2}"
7529 app_mem=" ${C1}mem$SEP3${C2} ${a_ps_data[7]}MB (${a_ps_data[5]}%)${C2}"
7530 if [[ $B_EXTRA_DATA == 'true' ]];then
7531 extra_data=" ${C1}cpu$SEP3${C2} ${a_ps_data[4]}%"
7535 (( line_counter++ ))
7536 count_nu="${C1}$line_counter:${C2}"
7537 full_line="$count_nu$app_cpu$app_mem$app_name$app_pid$extra_data"
7538 ps_data=$( create_print_line " " "$full_line" )
7539 print_screen_output "$ps_data"
7546 # currently only apt using distros support this feature, but over time we can add others
7550 local repo_count=0 repo_line='' file_name='' file_content='' file_name_holder=''
7551 local repo_full='' b_print_next_line='false'
7555 if [[ -n $REPO_DATA ]];then
7556 # loop through the variable's lines one by one, update counter each iteration
7557 while read repo_line
7560 file_name=$( cut -d ':' -f 1 <<< $repo_line )
7561 file_content=$( cut -d ':' -f 2-6 <<< $repo_line )
7562 # this will dump unwanted white space line starters. Some irc channels
7563 # use bots that show page title for urls, so need to break the url by adding
7565 if [[ $B_RUNNING_IN_SHELL != 'true' ]];then
7566 file_content=$( echo $file_content | sed 's|://|: //|' )
7568 file_content=$( echo $file_content )
7570 # check file name, if different, update the holder for print out
7571 if [[ $file_name != $file_name_holder ]];then
7572 if [[ $REPO_FILE_ID != 'pisi repo' ]];then
7573 repo_full="${C1}Active $REPO_FILE_ID in file:${C2} $file_name"
7575 repo_full="${C1}$REPO_FILE_ID:${C2} $file_name"
7577 file_name_holder=$file_name
7578 b_print_next_line='true'
7580 repo_full=$file_content
7582 # first line print Repos:
7583 if [[ $repo_count -eq 1 ]];then
7584 repo_full=$( create_print_line "Repos:" "$repo_full" )
7586 repo_full=$( create_print_line " " "$repo_full" )
7588 print_screen_output "$repo_full"
7589 # this prints the content of the file as well as the file name
7590 if [[ $b_print_next_line == 'true' ]];then
7591 repo_full=$( create_print_line " " "$file_content" )
7592 print_screen_output "$repo_full"
7593 b_print_next_line='false'
7595 done <<< "$REPO_DATA"
7597 repo_full=$( create_print_line "Repos:" "${C1}Error:${C2} $SCRIPT_NAME does not support this feature for your distro yet." )
7598 print_screen_output "$repo_full"
7603 print_script_version()
7605 local script_patch_number=$( get_patch_version_string )
7606 local script_version="${C1}$SCRIPT_NAME$SEP3${C2} $SCRIPT_VERSION_NUMBER$script_patch_number${CN}"
7607 # great trick from: http://ideatrash.net/2011/01/bash-string-padding-with-sed.html
7608 # left pad: sed -e :a -e 's/^.\{1,80\}$/& /;ta'
7609 # right pad: sed -e :a -e 's/^.\{1,80\}$/ &/;ta'
7610 # center pad: sed -e :a -e 's/^.\{1,80\}$/ & /;ta'
7611 #local line_max=$(( $LINE_MAX - 10 ))
7612 #script_version="$( sed -e :a -e "s/^.\{1,$line_max\}$/ &/;ta" <<< $script_version )" # use to create padding if needed
7613 # script_version=$( create_print_line "Version:" "$script_version" )
7614 print_screen_output "$script_version"
7617 print_sensors_data()
7620 local mobo_temp='' cpu_temp='' psu_temp='' cpu_fan='' mobo_fan='' ps_fan='' sys_fans='' sys_fans2=''
7621 local temp_data='' fan_data='' fan_data2='' b_is_error='false' fan_count=0 gpu_temp=''
7622 local a_sensors_working=''
7623 local Sensors_Data="$( get_sensors_output )"
7627 a_sensors_working=( ${A_SENSORS_DATA[0]} )
7629 # initial error cases, for missing app or unconfigured sensors. Note that array 0
7630 # always has at least 3 items, cpu/mobo/psu temp in it. If it's a single item, then
7631 # it's an error message, not the real data arrays.
7632 if [[ ${#a_sensors_working[@]} -eq 1 ]];then
7633 cpu_temp="${C1}Error:${C2} ${A_SENSORS_DATA[0]}"
7636 for (( i=0; i < ${#A_SENSORS_DATA[@]}; i++ ))
7639 a_sensors_working=( ${A_SENSORS_DATA[i]} )
7642 # first the temp data
7644 if [[ -n ${a_sensors_working[0]} ]];then
7645 cpu_temp=${a_sensors_working[0]}
7649 cpu_temp="${C1}System Temperatures: cpu$SEP3${C2} $cpu_temp "
7651 if [[ -n ${a_sensors_working[1]} ]];then
7652 mobo_temp=${a_sensors_working[1]}
7656 mobo_temp="${C1}mobo$SEP3${C2} $mobo_temp "
7658 if [[ -n ${a_sensors_working[2]} ]];then
7659 psu_temp="${C1}psu$SEP3${C2} ${a_sensors_working[2]} "
7661 gpu_temp=$( get_gpu_temp_data )
7662 # dump the unneeded screen data for single gpu systems
7663 if [[ $( wc -w <<< $gpu_temp ) -eq 1 && $B_EXTRA_DATA != 'true' ]];then
7664 gpu_temp=$( cut -d ':' -f 2 <<< $gpu_temp )
7666 if [[ -n $gpu_temp ]];then
7667 gpu_temp="${C1}gpu$SEP3${C2} ${gpu_temp} "
7670 # then the fan data from main fan array
7672 for (( j=0; j < ${#a_sensors_working[@]}; j++ ))
7676 # we need to make sure it's either cpu fan OR cpu fan and sys fan 1
7677 if [[ -n ${a_sensors_working[0]} ]];then
7678 cpu_fan="${a_sensors_working[0]}"
7679 elif [[ -z ${a_sensors_working[0]} && -n ${a_sensors_working[1]} ]];then
7680 cpu_fan="${a_sensors_working[1]}"
7684 cpu_fan="${C1}Fan Speeds (in rpm): cpu$SEP3${C2} $cpu_fan "
7688 if [[ -n ${a_sensors_working[1]} ]];then
7689 mobo_fan="${C1}mobo$SEP3${C2} ${a_sensors_working[1]} "
7694 if [[ -n ${a_sensors_working[2]} ]];then
7695 ps_fan="${C1}psu$SEP3${C2} ${a_sensors_working[2]} "
7700 if [[ -n ${a_sensors_working[$j]} ]];then
7701 fan_number=$(( $j - 2 )) # sys fans start on array key 5
7702 # wrap after fan 6 total
7703 if [[ $fan_count -lt 7 ]];then
7704 sys_fans="$sys_fans${C1}sys-$fan_number$SEP3${C2} ${a_sensors_working[$j]} "
7706 sys_fans2="$sys_fans2${C1}sys-$fan_number$SEP3${C2} ${a_sensors_working[$j]} "
7715 for (( j=0; j < ${#a_sensors_working[@]}; j++ ))
7719 if [[ -n ${a_sensors_working[$j]} ]];then
7720 fan_number=$(( $j + 1 )) # sys fans start on array key 5
7721 # wrap after fan 6 total
7722 if [[ $fan_count -lt 7 ]];then
7723 sys_fans="$sys_fans${C1}fan-$fan_number$SEP3${C2} ${a_sensors_working[$j]} "
7725 sys_fans2="$sys_fans2${C1}fan-$fan_number$SEP3${C2} ${a_sensors_working[$j]} "
7736 # turning off all output for case where no sensors detected or no sensors output
7737 # unless -s used explicitly. So for -F type output won't show unless valid or -! 1 used
7738 if [[ $b_is_error != 'true' || $B_SHOW_SENSORS == 'true' || $B_TESTING_1 == 'true' ]];then
7739 temp_data="$cpu_temp$mobo_temp$psu_temp$gpu_temp"
7740 temp_data=$( create_print_line "Sensors:" "$temp_data" )
7741 print_screen_output "$temp_data"
7742 # don't print second or subsequent lines if error data
7743 fan_data="$cpu_fan$mobo_fan$ps_fan$sys_fans"
7744 if [[ $b_is_error != 'true' && -n $fan_data ]];then
7745 fan_data=$( create_print_line " " "$fan_data" )
7746 print_screen_output "$fan_data"
7747 # and then second wrapped fan line if needed
7748 if [[ -n $sys_fans2 ]];then
7749 fan_data2=$( create_print_line " " "$sys_fans2" )
7750 print_screen_output "$fan_data2"
7760 local system_data='' bits='' desktop_environment=''
7761 local host_kernel_string='' de_distro_string='' host_string='' desktop_type='Desktop'
7762 local host_name=$HOSTNAME
7763 local current_kernel=$( uname -rm ) # | gawk '{print $1,$3,$(NF-1)}' )
7764 local distro="$( get_distro_data )"
7765 local tty_session=$( basename "$( tty 2>/dev/null )" | sed 's/[^0-9]*//g' )
7767 # I think these will work, maybe, if logged in as root and in X
7768 if [[ $B_RUNNING_IN_X == 'true' ]];then
7769 desktop_environment=$( get_desktop_environment )
7770 if [[ -z $desktop_environment ]];then
7771 desktop_environment='N/A'
7774 if [[ -z $tty_session && $B_CONSOLE_IRC == 'true' ]];then
7775 tty_session=$( get_console_irc_tty )
7777 if [[ -n $tty_session ]];then
7778 tty_session=" $tty_session"
7780 desktop_environment="tty$tty_session"
7781 desktop_type='Console'
7783 de_distro_string="${C1}$desktop_type$SEP3${C2} $desktop_environment ${C1}Distro$SEP3${C2} $distro"
7784 if [[ $B_EXTRA_DATA == 'true' ]];then
7785 gcc_string=$( get_gcc_kernel_version )
7786 if [[ -n $gcc_string ]];then
7787 gcc_string=", ${C1}gcc$SEP3${C2} $gcc_string"
7790 # check for 64 bit first
7791 if [[ -n $( uname -m | grep -o 'x86_64' ) ]];then
7796 bits=" (${bits} bit${gcc_string})"
7797 if [[ $B_SHOW_HOST == 'true' ]];then
7798 if [[ -z $HOSTNAME ]];then
7799 if [[ -n $( type p hostname ) ]];then
7800 host_name=$( hostname )
7802 if [[ -z $host_name ]];then
7806 host_string="${C1}Host$SEP3${C2} $host_name "
7807 system_data=$( create_print_line "System:" "$host_string$host_name ${C1}Kernel$SEP3${C2}" )
7809 host_kernel_string="$host_string${C1}Kernel$SEP3${C2} $current_kernel$bits "
7810 if [[ $( calculate_line_length "$host_kernel_string$de_distro_string" ) -lt $LINE_MAX ]];then
7811 system_data="$host_kernel_string$de_distro_string"
7812 system_data=$( create_print_line "System:" "$system_data" )
7814 system_data=$( create_print_line "System:" "$host_kernel_string" )
7815 print_screen_output "$system_data"
7816 system_data=$( create_print_line " " "$de_distro_string" )
7818 print_screen_output "$system_data"
7822 print_unmounted_partition_data()
7825 local a_unmounted_data='' line_starter='' unmounted_data='' full_fs=''
7826 local full_dev='' full_size='' full_label='' full_uuid='' full_string=''
7828 if [[ -z ${A_PARTITION_DATA} ]];then
7831 get_unmounted_partition_data
7833 if [[ ${#A_UNMOUNTED_PARTITION_DATA[@]} -ge 1 ]];then
7834 for (( i=0; i < ${#A_UNMOUNTED_PARTITION_DATA[@]}; i++ ))
7837 a_unmounted_data=(${A_UNMOUNTED_PARTITION_DATA[i]})
7839 if [[ -z ${a_unmounted_data[0]} ]];then
7842 full_dev="/dev/${a_unmounted_data[0]}"
7844 full_dev="${C1}ID:${C2} $full_dev"
7845 if [[ -z ${a_unmounted_data[1]} ]];then
7848 full_size=${a_unmounted_data[1]}
7850 full_size="${C1}size$SEP3${C2} $full_size"
7851 if [[ -z ${a_unmounted_data[2]} ]];then
7854 full_label=${a_unmounted_data[2]}
7856 full_label="${C1}label$SEP3${C2} $full_label"
7857 if [[ -z ${a_unmounted_data[3]} ]];then
7860 full_uuid=${a_unmounted_data[3]}
7862 full_uuid="${C1}uuid$SEP3${C2} $full_uuid"
7863 if [[ -z ${a_unmounted_data[4]} ]];then
7866 full_fs="${C1}fs$SEP3${C2} ${a_unmounted_data[4]}"
7868 full_string="$full_dev $full_size $full_label $full_uuid $full_fs"
7869 if [[ $i -eq 0 ]];then
7870 line_starter='Unmounted:'
7874 unmounted_data=$( create_print_line "$line_starter" "$full_string" )
7875 print_screen_output "$unmounted_data"
7878 unmounted_data=$( create_print_line "Unmounted:" "No unmounted partitions detected." )
7879 print_screen_output "$unmounted_data"
7885 ########################################################################
7886 #### SCRIPT EXECUTION
7887 ########################################################################
7889 main $@ ## From the End comes the Beginning
7891 ## note: this EOF is needed for smxi handling, this is what triggers the full download ok