#!/bin/bash
########################################################################
#### Script Name: inxi
-#### version: 1.4.8
-#### Date: March 5 2010
+#### version: 1.4.15
+#### Date: September 16 2010
########################################################################
#### SPECIAL THANKS
########################################################################
#### distro for proper package name by doing this: which <application>
#### then find what package owns that application file.
#### DEPENDENCIES
-#### bash >=3.0 (bash); df, readlink, stty, tr, uname, wc (coreutils),
-#### gawk (gawk); grep (grep); hostname (hostname); lspci (pciutils),
+#### bash >=3.0 (bash); df, readlink, stty, tr, uname, wc (coreutils);
+#### gawk (gawk); grep (grep); hostname (hostname); lspci (pciutils);
#### free, ps, uptime (procps);
#### Also the proc filesystem should be present and mounted
####
COLOR_SCHEME_SET=''
# override in user config if desired, seems like less than .3 doesn't work as reliably
CPU_SLEEP='0.3'
+DEV_DISK_LABEL=''
+DEV_DISK_UUID=''
IRC_CLIENT=''
IRC_CLIENT_VERSION=''
PS_COUNT=5
B_CPU_FLAGS_FULL='false'
# test for dbus irc client
B_DBUS_CLIENT='false'
+# kde dcop
+B_DCOP='false'
# Debug flood override: make 'true' to allow long debug output
B_DEBUG_FLOOD='false'
# show extra output data
B_EXTRA_DATA='false'
# override certain errors due to currupted data
B_HANDLE_CORRUPT_DATA='false'
+B_LABEL_SET='false'
B_LOG_COLORS='false'
B_LOG_FULL_DATA='false'
+# kde qdbus
+B_QDBUS='false'
B_ROOT='false'
# Running in a shell? Defaults to false, and is determined later.
B_RUNNING_IN_SHELL='false'
B_TESTING_2='false'
# set to true here for debug logging from script start
B_USE_LOGGING='false'
+B_UUID_SET='false'
# Test for X running
B_X_RUNNING='false'
else
script_debugger "Suggestion: update to Bash v3.1 for optimal inxi output"
fi
+ # now setting qdbus/dcop for first run, some systems can have both by the way
+ if [[ -n $( type -p qdbus ) ]];then
+ B_QDBUS='true'
+ fi
+ if [[ -n $( type -p dcop ) ]];then
+ B_DCOP='true'
+ fi
eval $LOGFE
}
fi
fi
- if [[ $KONVI -eq 1 ]]; then ## dcop Konversation (<= 1.1 (qt3))
+ if [[ $KONVI -eq 1 && $B_DCOP == 'true' ]]; then ## dcop Konversation (<= 1.1 (qt3))
# konvi doesn't seem to like \n characters, it just prints them literally
$print_data="$( tr '\n' ' ' <<< "$print_data" )"
dcop "$DCPORT" "$DCOPOBJ" say "$DCSERVER" "$DCTARGET" "$print_data"
- elif [[ $KONVI -eq 3 ]]; then ## dbus Konversation (> 1.2 (qt4))
+ elif [[ $KONVI -eq 3 && $B_QDBUS == 'true' ]]; then ## dbus Konversation (> 1.2 (qt4))
qdbus org.kde.konversation /irc say "$DCSERVER" "$DCTARGET" "$print_data"
# elif [[ $IRC_CLIENT == 'X-Chat' ]]; then
print_screen_output " shows (for single gpu, nvidia driver) screen number gpu is running on."
print_screen_output " Shows hdd temp with disk data if you have hddtemp installed, if you are root OR if you have"
print_screen_output " added to /etc/sudoers (sudo v. 1.7 or newer): <username> ALL = NOPASSWD: /usr/sbin/hddtemp (sample)"
- print_screen_output " For -t, adds memory use output to cpu (-tx c, and cpu use to memory (-tx m)."
+ print_screen_output " For -t, adds memory use output to cpu (-tx c), and cpu use to memory (-tx m)."
print_screen_output ""
print_screen_output "Additional Options:"
print_screen_output "-h - this help menu."
{
local konvi_qt4_client='' konvi_dbus_exist='' konvi_pid='' konvi_home_dir=''
local konvi='' konvi_qt4_ver='' b_is_qt4=''
-
- konvi_dbus_exist=$( qdbus | grep "org.kde.konversation" )
+
+ # fringe cases can throw error, always if untested app, use 2>/dev/null after testing if present
+ if [[ $B_QDBUS == 'true' ]];then
+ konvi_dbus_exist=$( qdbus 2>/dev/null | grep "org.kde.konversation" )
+ fi
if [[ -n $konvi_dbus_exist && -e /usr/share/kde4/apps/konversation ]]; then
konvi_pid=$( ps -A | grep -i 'konversation' )
{
eval $LOGFS
# in /proc/cpuinfo
- # algorithm
- # if > 1 processor && processor id (physical id) == core id then Hyperthreaded (HT)
- # if > 1 processor && different processor ids then Multiple Processors (SMP)
- # if > 1 processor && processor id != core id then Multi-Core Processors (MCP)
- # if = 1 processor then single core/processor Uni-Processor (UP)
+
if [[ $B_CPUINFO_FILE == 'true' ]]; then
A_CPU_TYPE_PCNT_CCNT=( $(
BEGIN {
FS=": "
IGNORECASE = 1
- core_count = 0
- holder = 0
- i = 0
- index_temp = ""
num_of_cores = 0
- physical_cpu_count = 0
- processor_logical_count = 0
- processors = 1
- type = "UP"
+ num_of_processors = 0
+ num_of_cpus = 0
+ core_id[0]
+ processor_id[0]
+ cpu_id[0]
+ type = "-"
+ iter = 0
}
- # counts logical processors, both HT and physical
+ # array of logical processors, both HT and physical
/^processor/ {
- processor_logical_count = $NF + 1
- }
- # counts physical cores (not used currently)
- /^cpu cores/ {
- num_of_cores = $NF
+ processor_id[iter] = $NF
}
# array of physical cpus ids
/^physical/ {
- a_physical_id[i] = $NF
+ cpu_id[iter] = $NF
}
# array of core ids
/^core id/ {
- a_core_id[i] = $NF
- i++
+ core_id[iter] = $NF
+ iter++
}
END {
- # look for the largest id number, and assign it (dumped this method due intel)
- # note that there are some cases, intel i5 core 2 HT where core_id shows
- # as 0/2, not 0/1. this triggers a 3 core output, erroneously.
- # Sorting the data solves this, since the counter now is mechanical, not
- # trusting the data from the proc/cpuinfo at all re what the core id is
- asort(a_core_id)
- # awk increments j++ counter BEFORE the loop?
- for ( j = 0; j <= processor_logical_count; j++ ) {
- # if ( j in a_core_id && a_core_id[j] > core_count ) {
- if ( j in a_core_id ) {
- #core_count = a_core_id[j]
- if ( a_core_id[j] != holder ){
- core_count++
- holder = a_core_id[j]
- }
- }
+ ## Look thru the array and filter same numbers.
+ ## only unique numbers required
+ ## this is to get an accurate count
+ ## we are only concerned with array length
+
+ i = 0
+ ## count unique processors ##
+ for ( i in processor_id ) {
+ procHolder[processor_id[i]] = 1
+ }
+ for ( i in procHolder ) {
+ num_of_processors++
}
- core_count = core_count + 1
- # trick, set the index equal to value, if the same, it will overwrite
- # this lets us create the actual array of true cpu physical ids
- for ( j in a_physical_id ) {
- index_temp = a_physical_id[j]
- a_cpu_physical_working[index_temp] = a_physical_id[j]
+ i = 0
+ ## count unique physical cpus ##
+ for ( i in cpu_id ) {
+ cpuHolder[cpu_id[i]] = 1
}
- # note that length() is a gawk >= 3.1.5 only method, better to do it manually
- for ( j in a_cpu_physical_working ) {
- ++physical_cpu_count
+ for ( i in cpuHolder ) {
+ num_of_cpus++
}
-
- # looking at logical processor counts over 1, which means either HT, SMP or MCP
- # http://en.wikipedia.org/wiki/Symmetric_multiprocessing
- if ( processor_logical_count > 1 && core_count > 1 ) {
- if ( processor_logical_count > core_count && physical_cpu_count > 1 ) {
- type = "SMP-HT" # could be Xeon/P4 HT dual cpu
+
+ i = 0
+ ## count unique cores ##
+ for ( i in core_id ) {
+ coreHolder[core_id[i]] = 1
+ }
+ for ( i in coreHolder ) {
+ num_of_cores++
+ }
+
+ ####################################################################
+ # algorithm
+ # if > 1 processor && processor id (physical id) == core id then Hyperthreaded (HT)
+ # if > 1 processor && processor id (physical id) != core id then Multi-Core Processors (MCP)
+ # if > 1 processor && processor ids (physical id) > 1 then Multiple Processors (SMP)
+ # if = 1 processor then single core/processor Uni-Processor (UP)
+ if ( num_of_processors > 1 )
+ {
+ # non-multicore HT
+ if ( num_of_processors == (num_of_cores * 2))
+ {
+ type = type "HT-"
}
- else if ( processor_logical_count > core_count ) {
- type = "HT" # this is more than likely a P4 w/HT or an Atom 270
+ # non-HT multi-core or HT multi-core
+ if (( num_of_processors == num_of_cores) ||
+ ( num_of_cpus < num_of_cores))
+ {
+ type = type "MCP-"
}
- else {
- type = "SMP"
+ # >1 cpu sockets active
+ if ( num_of_cpus > 1 )
+ {
+ type = type "SMP-"
}
- }
- # make sure to handle up cpus too
- else {
- core_count = 1
- physical_cpu_count = 1
- }
- print type " " physical_cpu_count " " core_count
+ } else {
+ type = type "UP-"
+ }
+
+ print type " " num_of_cpus " " num_of_cores
}
' $FILE_CPUINFO
) )
/version:/ {
print $NF
}' )
+ # this gives better output than the failure last case, which would only show:
+ # for example: X.org: 1.9 instead of: X.org: 1.9.0
+ if [[ -z $x_version ]];then
+ x_version=$( get_x_version )
+ fi
if [[ -z $x_version ]];then
- x_version=$(xdpyinfo | gawk -F': +' '
+ x_version=$( xdpyinfo | gawk -F': +' '
BEGIN {
IGNORECASE=1
}
print $2
}' )
fi
+
+ # some distros, like fedora, report themselves as the xorg vendor, so quick check
+ # here to make sure the vendor string includes Xorg in string
+ if [[ -z $( grep -E '(X|xorg|x\.org)' <<< $x_vendor ) ]];then
+ x_vendor="$x_vendor X.org"
+ fi
+
A_X_DATA[0]="$x_vendor"
A_X_DATA[1]="$x_version"
-
- #X -version 2>&1 | gawk '/^X Window System Version/ { print $5 }'
- #This method could be used in the future to detect X when X is not running,
- #however currently inxi ignores X checks when X is not found.
+ else
+ x_version=$( get_x_version )
+ if [[ -n $x_version ]];then
+ x_vendor='X.org'
+ A_X_DATA[0]="$x_vendor"
+ A_X_DATA[1]="$x_version"
+ fi
fi
log_function_data "A_X_DATA: ${A_X_DATA[@]}"
eval $LOGFE
}
+# if other tests fail, try this one, this works for root, out of X also
+get_x_version()
+{
+ eval $LOGFS
+ local x_exists=$( type -p X )
+ local x_version=''
+
+ if [[ -n $x_exists ]];then
+ # note: MUST be this syntax: X -version 2>&1
+ # otherwise X -version overrides everything and this comes out null.
+ # two knowns id strings: X.Org X Server 1.7.5 AND Window System Version 1.7.5
+ #X -version 2>&1 | gawk '/^X Window System Version/ { print $5 }'
+ x_version=$( X -version 2>&1 | gawk '
+ BEGIN {
+ IGNORECASE=1
+ }
+ /x.org x server|X Window System Version/ {
+ print $NF
+ }' )
+ fi
+ echo $x_version
+ log_function_data " x_version: $x_version"
+ eval $LOGFE
+}
# this gets just the raw data, total space/percent used and disk/name/per disk capacity
get_hdd_data_basic()
{
eval $LOGFS
local hdd_used=''
- local hdd_data="$( df --exclude-type=aufs --exclude-type=tmpfs --exclude-type=iso9660 )"
+ local hdd_data="$( df --exclude-type=aufs --exclude-type=squashfs --exclude-type=unionfs --exclude-type=devtmpfs --exclude-type=tmpfs --exclude-type=iso9660 )"
log_function_data 'raw' "hdd_data:\n$hdd_data"
hdd_used=$( echo "$hdd_data" | gawk '
get_partition_data()
{
eval $LOGFS
+
+ local a_partition_working='' dev_item=''
#local excluded_file_types='--exclude-type=aufs --exclude-type=tmpfs --exclude-type=iso9660'
# df doesn't seem to work in script with variables like at the command line
- local main_partition_data="$( df -h -T --exclude-type=aufs --exclude-type=tmpfs --exclude-type=iso9660 )"
+ local main_partition_data="$( df -h -T --exclude-type=aufs --exclude-type=squashfs --exclude-type=unionfs --exclude-type=devtmpfs --exclude-type=tmpfs --exclude-type=iso9660 )"
local swap_data="$( swapon -s )"
+ # set dev disk label/uuid data globals
+ get_partition_uuid_label_data 'label'
+ get_partition_uuid_label_data 'uuid'
+
log_function_data 'raw' "main_partition_data:\n$main_partition_data\n\nswap_data:\n$swap_data"
IFS=$'\n'
}
}
' )
+
# now add the swap partition data, don't want to show swap files, just partitions,
# though this can include /dev/ramzswap0. Note: you can also use /proc/swaps for this
# data, it's the same exact output as swapon -s
swapCounter = ++swapCounter
}' ) )
IFS="$ORIGINAL_IFS"
+
+ # now we'll handle some fringe cases where irregular df -hT output shows /dev/disk/.. instead of
+ # /dev/h|sdxy type data for column 1, . A_PARTITION_DATA[6]
+ for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
+ do
+ IFS=","
+ a_partition_working=( ${A_PARTITION_DATA[i]} )
+ IFS="$ORIGINAL_IFS"
+ dev_item='' # reset each loop
+ # note: for swap this will already be set
+ if [[ -n $( grep -E '(by-uuid|by-label)' <<< ${a_partition_working[6]} ) ]];then
+ if [[ -n $DEV_DISK_UUID ]];then
+ dev_item=$( echo "$DEV_DISK_UUID" | gawk '
+ /'$( basename ${a_partition_working[6]} )'/ {
+ item=gensub( /..\/..\/(.+)/, "\\1", 1, $NF )
+ print item
+ }' )
+ fi
+ # if we didn't find anything for uuid try label
+ if [[ -z $dev_item && -n $DEV_DISK_LABEL ]];then
+ dev_item=$( echo "$DEV_DISK_LABEL" | gawk '
+ /'$( basename ${a_partition_working[6]} )'/ {
+ item=gensub( /..\/..\/(.+)/, "\\1", 1, $NF )
+ print item
+ }' )
+ fi
+ if [[ -n $dev_item ]];then
+ # assemble everything we could get for dev/h/dx, label, and uuid
+ IFS=","
+ 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
+ IFS="$ORIGINAL_IFS"
+ fi
+ fi
+ done
if [[ $B_SHOW_LABELS == 'true' || $B_SHOW_UUIDS == 'true' ]];then
get_partition_data_advanced
{
eval $LOGFS
local a_partition_working='' dev_partition_data=''
- local dev_disk_label='' dev_disk_uuid='' dev_item='' dev_label='' dev_uuid=''
+ local dev_item='' dev_label='' dev_uuid=''
local mount_point=''
-
- if [[ -d /dev/disk/by-label ]];then
- dev_disk_label="$( ls -l /dev/disk/by-label )"
- fi
- if [[ -d /dev/disk/by-uuid ]];then
- dev_disk_uuid="$( ls -l /dev/disk/by-uuid )"
- fi
- log_function_data 'raw' "dev_disk_label:\n$dev_disk_label\n\ndev_disk_uuid:\n$dev_disk_uuid"
+ # set dev disk label/uuid data globals
+ get_partition_uuid_label_data 'label'
+ get_partition_uuid_label_data 'uuid'
if [[ $B_MOUNTS_FILE == 'true' ]];then
for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
# it's more likely we'll get a uuid than a label. But this should get the
# dev item set no matter what, so then we can get the rest of any missing data
# first we'll get the dev_item if it's missing
- if [[ -n $dev_disk_uuid ]] && [[ -z $dev_item && -n $dev_uuid ]];then
- dev_item=$( echo "$dev_disk_uuid" | gawk '
+ if [[ -n $DEV_DISK_UUID ]] && [[ -z $dev_item && -n $dev_uuid ]];then
+ dev_item=$( echo "$DEV_DISK_UUID" | gawk '
/'$dev_uuid'/ {
item=gensub( /..\/..\/(.+)/, "\\1", 1, $NF )
print item
}' )
- elif [[ -n $dev_disk_label ]] && [[ -z $dev_item && -n $dev_label ]];then
- dev_item=$( echo "$dev_disk_label" | gawk '
+ elif [[ -n $DEV_DISK_LABEL ]] && [[ -z $dev_item && -n $dev_label ]];then
+ dev_item=$( echo "$DEV_DISK_LABEL" | gawk '
# first we need to change space x20 in by-label back to a real space
#gsub( /x20/, " ", $0 )
# then we can see if the string is there
print item
}' )
fi
- if [[ -n $dev_disk_uuid ]] && [[ -n $dev_item && -z $dev_uuid ]];then
- dev_uuid=$( echo "$dev_disk_uuid" | gawk '
+ if [[ -n $DEV_DISK_UUID ]] && [[ -n $dev_item && -z $dev_uuid ]];then
+ dev_uuid=$( echo "$DEV_DISK_UUID" | gawk '
/'$dev_item'$/ {
print $(NF - 2)
}' )
fi
- if [[ -n $dev_disk_label ]] && [[ -n $dev_item && -z $dev_label ]];then
- dev_label=$( echo "$dev_disk_label" | gawk '
+ if [[ -n $DEV_DISK_LABEL ]] && [[ -n $dev_item && -z $dev_label ]];then
+ dev_label=$( echo "$DEV_DISK_LABEL" | gawk '
/'$dev_item'/ {
print $(NF - 2)
}' )
eval $LOGFE
}
+
+# args: $1 - uuid/label
+get_partition_uuid_label_data()
+{
+ eval $LOGFS
+
+ # only run these tests once per directory to avoid excessive queries to fs
+ case $1 in
+ label)
+ if [[ $B_LABEL_SET != 'true' ]];then
+ if [[ -d /dev/disk/by-label ]];then
+ DEV_DISK_LABEL="$( ls -l /dev/disk/by-label )"
+ fi
+ B_LABEL_SET='true'
+ fi
+ ;;
+ uuid)
+ if [[ $B_UUID_SET != 'true' ]];then
+ if [[ -d /dev/disk/by-uuid ]];then
+ DEV_DISK_UUID="$( ls -l /dev/disk/by-uuid )"
+ fi
+ B_UUID_SET='true'
+ fi
+ ;;
+ esac
+ log_function_data 'raw' "DEV_DISK_LABEL:\n$DEV_DISK_LABEL\n\nDEV_DISK_UUID:\n$DEV_DISK_UUID"
+ # debugging section, uncomment to insert user data
+# DEV_DISK_LABEL='
+#
+# '
+# DEV_DISK_UUID='
+#
+# '
+ eval $LOGFE
+}
+
# args: $1 - type cpu/mem
get_ps_data()
{
{
eval $LOGFS
local a_unmounted_working='' mounted_partitions='' separator='' unmounted_fs=''
- local dev_disk_label='' dev_disk_uuid='' dev_working='' uuid_working='' label_working=''
+ local dev_working='' uuid_working='' label_working=''
if [[ $B_PARTITIONS_FILE == 'true' ]];then
- if [[ -d /dev/disk/by-label ]];then
- dev_disk_label="$( ls -l /dev/disk/by-label )"
- fi
- if [[ -d /dev/disk/by-uuid ]];then
- dev_disk_uuid="$( ls -l /dev/disk/by-uuid )"
- fi
+ # set dev disk label/uuid data globals
+ get_partition_uuid_label_data 'label'
+ get_partition_uuid_label_data 'uuid'
# create list for slicing out the mounted partitions
for (( i=0; i < ${#A_PARTITION_DATA[@]}; i++ ))
}
# note that size 1 means it is a logical extended partition container
# lvm might have dm-1 type syntax
- /[a-z][0-9]+$|dm-[0-9]+$/ && $3 != 1 {
+ # need to exclude loop type file systems, squashfs for example
+ /[a-z][0-9]+$|dm-[0-9]+$/ && $3 != 1 && $NF !~ /loop/ {
size = sprintf( "%.2f", $3*1024/1000**3 )
print $4 "," size "G"
}' ) )
-
+
for (( i=0; i < ${#A_UNMOUNTED_PARTITION_DATA[@]}; i++ ))
do
IFS=","
a_unmounted_working=( ${A_UNMOUNTED_PARTITION_DATA[i]} )
IFS="$ORIGINAL_IFS"
- label_working=$( grep -E "${a_unmounted_working[0]}$" <<< "$dev_disk_label" | gawk '{
+ label_working=$( grep -E "${a_unmounted_working[0]}$" <<< "$DEV_DISK_LABEL" | gawk '{
print $(NF - 2)
}' )
- uuid_working=$( grep -E "${a_unmounted_working[0]}$" <<< "$dev_disk_uuid" | gawk '{
+ uuid_working=$( grep -E "${a_unmounted_working[0]}$" <<< "$DEV_DISK_UUID" | gawk '{
print $(NF - 2)
}' )
unmounted_fs=$( get_unmounted_partition_filesystem "/dev/${a_unmounted_working[0]}" )
IFS="$ORIGINAL_IFS"
done
fi
-
+# echo "${A_PARTITION_DATA[@]}"
# echo "${A_UNMOUNTED_PARTITION_DATA[@]}"
eval $LOGFE
}
print_gfx_data()
{
eval $LOGFS
- local gfx_data='' i='' card_one='Card' root_alert=''
+ local gfx_data='' i='' card_one='Card' root_alert='' root_x_string=''
local screen_resolution="$( get_graphics_res_data )"
local b_is_mesa='false' display_full_string=''
# set A_GFX_CARD_DATA
fi
display_full_string="${C1}$x_vendor${C2} $x_version ${C1}Res:${C2} ${screen_resolution} "
else
- if [[ $B_X_RUNNING == 'true' && $B_ROOT == 'true' ]];then
+ root_x_string=''
+ if [[ $B_ROOT == 'true' ]];then
+ root_x_string='for root '
+ fi
+ if [[ $B_X_RUNNING != 'true' ]];then
+ root_x_string="${root_x_string}out of X"
+ fi
+ if [[ -n $x_vendor && -n $x_version ]];then
+ display_full_string="${C1}$x_vendor${C2} $x_version ${C1}Res:${C2} ${screen_resolution} ${C1}Gfx Data:${C2} N/A $root_x_string"
+ elif [[ $B_X_RUNNING == 'true' && $B_ROOT == 'true' ]];then
root_alert="${C1}Gfx Data:${C2} N/A for root user"
+ display_full_string="${C1}tty res:${C2} ${screen_resolution} $root_alert"
fi
- display_full_string="${C1}tty res:${C2} ${screen_resolution} $root_alert"
fi
if [[ ${#A_GFX_CARD_DATA[@]} -gt 1 ]];then