Created
April 13, 2020 02:25
-
-
Save Zobber/479250e3f14430e96c814dd3e5c4d4e3 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# | |
# showmydisks - report partitions, types, filesystems, and disk space usage | |
# | |
PRGVERSION="v0.12 * 2015-09-12 (c) Andreas Schamanek" | |
# Copyright 2004-2015: Andreas Schamanek <[email protected]> | |
# Homepage: http://wox.at/as/_/showmydisks | |
# License + History: see end of file | |
# Usage : showmydisks [--debug] [-L] [-u] ["dev1 ... devN"] | |
# Example: showmydisks "hda sda" | |
# Example: showmydisks -u # show also unallocated sectors | |
# Note : Use this script carefully. It's been hacked quick and dirty | |
# by a bad programmer. It's been tested only on a few Debian systems. | |
# It currently depends on the existence of at least: | |
# bash, df, sed, awk, file, /etc/fstab, /sys/block, /proc | |
# ''lsblk'' from the util-linux collection is a great alternative providing | |
# more details and a beautiful output with several options to configure it. | |
# lsblk(8) should be available on all major Linux distributions by default. | |
# me (name of this script without path) | |
ME=$(basename $0) | |
PRGVERSION="$ME $PRGVERSION" | |
# some standard variables | |
TRUE=0 ; FALSE=1 | |
# debug? | |
DEBUG=$FALSE | |
[[ $1 == --debug ]] && DEBUG=$TRUE && shift | |
# some useful functions | |
function debugmsg { test $DEBUG = $TRUE && echo -ne "$1" >&2 ; } | |
function warning { echo -e "\n$ME: warning: $1\n" >&2 ; } | |
function die { echo -e "\n$ME: error: $2. aborting.\n" >&2 ; exit $1 ; } | |
# if $1 is --help show usage and example | |
[[ $1 == --help ]] \ | |
&& echo "Usage: $ME [--debug] [-L] [-u] [\"dev1 ... devN\"] | |
Example: $ME \"hda sda\" | |
(Note: Order of command line arguments must not be mixed up.) | |
" >&2 && exit 0 | |
# if $1 is -L only list devices of hard drives/block devices w/o RAIDs | |
LISTONLY=$FALSE | |
[[ $1 == -L ]] && LISTONLY=$TRUE && shift | |
# if $1 is -u show also unallocated sectors | |
SHOWUNALLOCATED=$FALSE | |
[[ $1 == -u ]] && SHOWUNALLOCATED=$TRUE && shift | |
debugmsg "$PRGVERSION\n" | |
# warn if script not run as root and expand PATH (mostly for fdisk) | |
test $UID -ne 0 -a $LISTONLY = $FALSE \ | |
&& { warning "you probably want to be root" ; PATH="/sbin:$PATH" ; } | |
# list of disks to investigate, provided by $1 or /sys/block/{h,s}d? | |
DISKS=${1:-`cd /sys/block && "ls" -d hd? sd? 2>/dev/null`} | |
debugmsg "[disks to consider: $(echo $DISKS)]\n" | |
# Skip CD-Rom drives and disks with no size, and construct $DISKS | |
for MYDEV in $DISKS ; do | |
test -r /sys/block/$MYDEV/device/media \ | |
&& if [ "/$(</sys/block/$MYDEV/device/media)" = "/cdrom" ] ; then | |
debugmsg "[$MYDEV is type cd-rom]\n" | |
# remove CD-Rom from $DISKS | |
DISKS=${DISKS/$MYDEV/} | |
fi | |
if [ -s /sys/block/$MYDEV/size ] ; then | |
MYDEVSIZE=$(</sys/block/$MYDEV/size) | |
if (( MYDEVSIZE < 99 )) ; then | |
debugmsg "[$MYDEV's size is reported as $MYDEVSIZE; skipping it]\n" | |
DISKS=${DISKS/$MYDEV/} | |
else | |
debugmsg "[$MYDEV's size = $MYDEVSIZE]\n" | |
fi | |
else | |
debugmsg "[$MYDEV has no valid /sys/block/$MYDEV/size; skipping it]\n" | |
DISKS=${DISKS/$MYDEV/} | |
fi | |
done | |
DISKS=$(echo $DISKS) # just to remove newlines and extra spaces | |
# bail out if $DISKS is empty | |
[[ $DISKS ]] || die 2 "list of disks to investigate is empty" | |
# add Software RAID to DISKS unless user requested a specific list | |
if [ "/$1/" = '//' -a -r /proc/mdstat ] ; then | |
# testing for /proc/mdstat is not sufficient; maybe test -s is? | |
MDDEVS=$(cd /sys/block && "ls" -d md[0-9] md[0-9][0-9] 2>/dev/null ) | |
MDDEVS=$(echo $MDDEVS) # remove newlines (just for the debugmsg) | |
debugmsg "[MDDEVS=$MDDEVS]\n" | |
test "/$MDDEVS/" != '//' && DISKS="$DISKS md" | |
fi | |
# Eventually we have compiled $DISKS | |
debugmsg "[DISKS=$DISKS]\n" | |
# list of valid disks and partitions (e.g. as detected by kernel) | |
# VALIDDISKS=$(</proc/partitions) # kernel 2.4.x, has no cdrom, etc. | |
VALIDDISKS=$(</proc/diskstats) # kernel 2.6.x | |
# VALIDDISKS=" hda hda1 hda2 hde hde5" # your custom list, mind the 1st space | |
# symbols for output | |
SYMDISK="> " # symbol for disks | |
SYMPART="|-- " # symbol for partitions | |
# SYMSEP="-----------\n" # separator between disks (include \n, ...) | |
# make sure we got what we need | |
[ ! -r /proc/partitions ] && { die 1 "/proc/partitions not readable" ; } | |
[ ! -r /proc/mounts ] && { die 1 "/proc/mounts not readable" ; } | |
# collect system data for later use | |
DF=$(df -klT) | |
[ -r /proc/mdstat ] && MDSTAT=$(</proc/mdstat) || MDSTAT= | |
# find rootfs device | |
ROOTFS=$(awk '$2=="/"&&$1!="rootfs"{print $1}' /proc/mounts) | |
if [[ $ROOTFS ]] ; then | |
mapfile -t rootfsarray <<<"$ROOTFS"; rootfscount=${#rootfsarray[@]}; | |
if (( rootfscount > 1 )) ; then | |
warning "Found $rootfscount rootfs devices mounted on /" | |
debugmsg "[ROOTFS($rootfscount)=$ROOTFS]\n" | |
debugmsg "[reducing ROOTFS to last entry]\n" | |
ROOTFS=${#rootfsarray[-1]} | |
fi | |
else | |
warning "Could not find a device for rootfs (= mount on /)". | |
fi | |
debugmsg "[ROOTFS=$ROOTFS]\n" | |
ROOTFSDEV=$(readlink -e $ROOTFS) | |
[[ $ROOTFSDEV ]] || die 3 "readlink -e failed for $ROOTFS" | |
debugmsg "[ROOTFSDEV=$ROOTFSDEV]\n" | |
ROOTFSTYPE=$(awk "\$1==\"$ROOTFS\"{print \$3}" /proc/mounts) | |
# some more useful functions | |
function getparm { MYPOS=$1 ; shift ; echo ${@:$MYPOS:1} ; } | |
function prettyprintsize { | |
MYVAL="$1" | |
for UNIT in KB MB GB TB ; do | |
MYRES="$MYVAL $UNIT" | |
NEW=$((MYVAL / 1024)) | |
test $NEW -lt 2 && break | |
MYVAL=$NEW | |
done | |
echo -n $MYRES | |
} | |
function getcapacity { | |
MYCAPAC=$(awk -v partition=$1 '$4 == partition {print $3}' </proc/partitions) | |
debugmsg "[MYCAPAC=$MYCAPAC] " | |
[ $MYCAPAC ] && prettyprintsize $MYCAPAC | |
} | |
function isrootfs { | |
# check if $1 is the rootfs | |
[[ /dev/$1 == $ROOTFSDEV ]] || return $FALSE | |
MYDF=$(echo "$DF" | awk '/\/$/{df=$5}END{print df}') | |
CAPFREE=$(prettyprintsize $MYDF) | |
echo -n "on / as $ROOTFSTYPE ($CAPFREE free)" | |
} | |
function mountedas { | |
# note: mountedas returns $FALSE if $1 _is_ mounted, $TRUE if _not_ | |
awk "/^\/dev\/$1 /"'{ printf "on %s as %s", $2, $3 }' < /proc/mounts | |
# if mounted get free capacity | |
MYDF=`echo "$DF" | grep "^/dev/$1 "` | |
if [ -n "$MYDF" ] ; then | |
CAPFREE=$(prettyprintsize $(getparm 5 $MYDF)) | |
echo -n " ($CAPFREE free)" | |
return $FALSE | |
fi | |
} | |
function gettype { | |
# get type of filesystem if partition $1 is not mounted by use of _file -s_ | |
# idea from _scanpartitions_ of KNOPPIX 3.7 (c) Klaus Knopper Nov 2002 | |
FILE=$(LC_ALL=C file -Ls "/dev/$1") | |
[ "$?" = "0" ] || return 2 | |
case "$FILE" in | |
*[Ee][Xx][Tt]2*) echo -n "ext2"; return 0;; | |
*[Ee][Xx][Tt]3*) echo -n "ext3"; return 0;; | |
*[Ee][Xx][Tt]4*) echo -n "ext4"; return 0;; | |
*[Rr][Ee][Ii][Ss][Ee][Rr]*) echo -n "reiserfs"; return 0;; | |
*[Ff][Aa][Tt]*|*[Xx]86*) echo -n "vfat|msdos"; return 0;; | |
*[Xx][Ff][Ss]*) echo -n "xfs"; return 0;; | |
*[Nn][Tt][Ff][Ss]*) echo -n "ntfs"; return 0;; | |
*[Ss][Ww][Aa][Pp]*) echo -n "swap"; return 0;; | |
*LUKS\ encrypted*) echo -n "LUKS encrypted"; return 0;; | |
*\ data*) echo -n "garbage?"; return 0;; | |
*) echo -n "fs unknown"; return 0;; | |
esac | |
} | |
function isinraid { | |
# check if $1 is part of a Software RAID set (checking $MDSTAT) | |
RAID=$(awk -F: "/ $1\[/ { print \$1 }" <<< "$MDSTAT") | |
[ $RAID ] && echo -n ", used in" $RAID | |
} | |
# start of actions ------------------------------------------------------ | |
# print name of system | |
# echo "# $(uname -n) (kernel $(uname -r), disks as of $(date +%Y-%m-%d))" | |
for MYDEV in $DISKS ; do | |
# cleanup + check MYDEV is a block device (unless it is md) | |
MYDEV=$(basename -- "$MYDEV") | |
if [ $MYDEV != 'md' -a ! -b /dev/"$MYDEV" ] ; then | |
warning "$MYDEV is not a block special device" | |
fi | |
# start output (unless $LISTONLY) | |
[ $LISTONLY = $FALSE ] && echo -en "${SYMDISK}$MYDEV:" | |
# check if it's there | |
if ! echo "$VALIDDISKS" | grep -sq " $MYDEV" ; then | |
die 1 "$MYDEV seems to be no valid disk or partition" | |
fi | |
# LISTONLY: Only list devices of block devices (quick and dirty) | |
if [ $LISTONLY = $TRUE ] ; then | |
[ "/$MYDEV/" != '/md/' ] && echo "$MYDEV" | |
continue | |
fi | |
# we have to distinguish normal block devs and Software RAID | |
case /$MYDEV/ in | |
/md/ ) # Software RAID | |
MYMODEL="Software RAID" | |
echo -n \ ${MYMODEL} | |
# total capacity; we sum up all md "partitions" | |
echo -n " (" | |
prettyprintsize $(awk '$4 ~ /^md[0-9]/ { sum+=$3 } | |
END { print sum }' </proc/partitions) | |
echo ")" | |
MYFDISK="" | |
;; | |
* ) # block devices (no Software RAID) | |
# print brand/model | |
MYMODEL="unknown brand" | |
test -f /sys/block/$MYDEV/device/vendor && | |
MYMODEL=$(</sys/block/$MYDEV/device/vendor) | |
test -f /sys/block/$MYDEV/device/model && | |
MYMODEL="$MYMODEL $(</sys/block/$MYDEV/device/model)" | |
test -f /proc/ide/$MYDEV/model && | |
MYMODEL=$(head -1 /proc/ide/$MYDEV/model) | |
echo -n \ ${MYMODEL} | |
# print total capacity | |
echo -n " "; echo "($(getcapacity $MYDEV))" | |
# save _fdisk -l_ for later use | |
if [ $UID -ne 0 ] ; then | |
MYFDISK=`fdisk -l /dev/$MYDEV 2>/dev/null \ | |
| sed -ne "/^\/dev\/$MYDEV/{s/\*/ /;p}"` | |
else | |
# if script is run as root do not suppress error messages | |
MYFDISK=`fdisk -l /dev/$MYDEV \ | |
| sed -ne "/^\/dev\/$MYDEV/{s/\*/ /;p}"` | |
fi | |
;; | |
esac # /$MYDEV/ | |
# get list of partitions | |
PARTITIONS="$(echo `awk -v pat=$MYDEV[0-9]+ '$4 ~ pat {print $4}' < /proc/partitions`)" | |
for PARTITION in $PARTITIONS ; do | |
echo -n "${SYMPART}${PARTITION/$MYDEV}:" | |
# get type ID of partition | |
PARTTYPE=`echo "$MYFDISK" \ | |
| awk "/^\/dev\/$PARTITION /"'{ print $5}'` | |
debugmsg " [PARTTYPE=$PARTTYPE]" | |
case /$PARTTYPE/ in | |
// ) if [ $MYDEV = 'md' ] ; then | |
echo -n " $(</sys/block/$PARTITION/md/level) " | |
else | |
echo -n " type unknown `getcapacity $PARTITION` " | |
fi | |
isrootfs $PARTITION \ | |
|| { mountedas $PARTITION && gettype $PARTITION ; } | |
;; | |
/5/ ) echo -n " extended partition" ;; | |
/82/ ) echo -n " Linux swap partition" | |
echo -n ", " ; getcapacity $PARTITION ;; | |
/83/ ) echo -n " " ; getcapacity $PARTITION ; echo -n " " | |
isrootfs $PARTITION \ | |
|| { mountedas $PARTITION && gettype $PARTITION ; } | |
;; | |
/7/ ) echo -n " type 7 (NTFS?) " | |
getcapacity $PARTITION ; echo -n " " | |
mountedas $PARTITION && gettype $PARTITION | |
;; | |
/fd/ ) echo -n " " ; getcapacity $PARTITION | |
echo -n ", partition type fd" | |
[ "$MDSTAT" ] && isinraid $PARTITION | |
;; | |
* ) echo -n " partition type $PARTTYPE" ;; | |
esac | |
echo | |
done # all partitions | |
# print number of unallocated sectors (if requested) | |
if [ $SHOWUNALLOCATED = $TRUE -a $MYDEV != 'md' ] ; then | |
UNALLOCATED="" | |
UNALLOCATED=$(\ | |
(echo -e "v\nq" | fdisk /dev/$MYDEV) 2>/dev/null \ | |
| sed -ne '/unallocated sectors/s/^.* \([0-9]\+\) unallo.*$/\1/p' ) | |
test "/$UNALLOCATED/" = '//' || echo "($UNALLOCATED unallocated sectors)" | |
fi | |
# print separator line/symbol between disk | |
echo -en "$SYMSEP" | |
done # all disks | |
exit 0 | |
# License | |
# | |
# This script is free software; you can redistribute it and/or modify it | |
# under the terms of the GNU General Public License as published by | |
# the Free Software Foundation; either version 2 of the License, or | |
# (at your option) any later version. | |
# | |
# This script is distributed in the hope that it will be useful, | |
# but WITHOUT ANY WARRANTY; without even the implied warranty of | |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
# GNU General Public License for more details. | |
# | |
# You should have received a copy of the GNU General Public License | |
# along with this script; if not, write to the | |
# Free Software Foundation, Inc., 59 Temple Place, Suite 330, | |
# Boston, MA 02111-1307 USA | |
# History | |
# | |
# 0.02 * 2004-12-23 first buggy "punish me" alpha release | |
# 0.03 * 2005-01-19 added code to read /sys/block/sd?/device/... | |
# 0.04 * 2009-09-13 cosmetic changes and testing if it still works | |
# 0.05 * 2009-09-14 print warning if not /root but go on; added --help; | |
# 0.05 * 2009-09-14 removed sfdisk requirement; some cosmetics | |
# 0.06 * 2009-09-15 added -u (unallocated sectors); removed bc requirement | |
# 0.07 * 2009-09-15 added support for /dev/md (Software RAID) | |
# 0.08 * 2010-03-07 added support for -L (only list devices) | |
# 0.09 * 2011-02-20 added ext4 + LUKS, more info about fd partitions (mdstat) | |
# 0.10 * 2012-08-25 skipping disks with no /sys/block/$MYDEV/size, + cosmetics | |
# 0.11 * 2015-03-27 added note about lsblk from util-linux | |
# 0.12 * 2015-09-12 fixed detection of rootfs device |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment