Operating System - HP-UX
1820071 Members
2425 Online
109608 Solutions
New Discussion юеВ

I want to know Size calculation using bash script

 
Sendykimber
Occasional Visitor

I want to know Size calculation using bash script

I am trying to display size in human-readable form on HP-UX. We have a few legacy systems which we use for sftp transfers. These servers are connected T1 leased line and transfers are very slow. I have to occasionally check the size to verify if the transfer is done or not. As HP-UX cant display the size in kb or GB, we have to manually divide the output to verify. I am just trying to build a small script to display the size in GB. 

5 REPLIES 5
Steven Schweda
Honored Contributor

Re: I want to know Size calculation using bash script

> I am trying to display size in human-readable form on HP-UX. [...]

   "size" of _what_?  A file?  Define "human-readable form".  What is
the non-"human-readable form" you see now?

> [...] We have a few legacy systems [...]

   "legacy" means "HP-UX", or what?

> [...] HP-UX cant display the size in kb or GB, [...]

   HP-UX is not the problem.  The "ls" program supplied with your
(unspecified) version of HP-UX might be problem.  Of course, I don't
know what you're doing.  How would you solve this problem on a non-HP-UX
(non-"legacy"?) system?

      uname -a

   If a better "ls" program would help, then you should be able to
install GNU coreutils on your (unspecified) HP-UX system.  See, for
example:

      http://hpux.connect.org.uk/hppd/hpux/Gnu/coreutils-9.1/

> [...] using bash script

   I doubt that the shell matters much, either.

Bill Hassell
Honored Contributor

Re: I want to know Size calculation using bash script

Assuming you want to display output from the ls -l (or ll) command, here is a script called lls which shows the file (or files) size with suffixes for K M G T. If you specify a list of files, the list is sorted largest size first.

 

#!/usr/bin/sh
# POSIX-sh and ksh compatible

###################################
#
#     #       #        #####
#     #       #       #     #
#     #       #       #
#     #       #        #####
#     #       #             #
#     #       #       #     #
#     ####### #######  #####
#
###################################
#

# Script to list largest files first with Kb Mb Gb Tb adjustments
# Output matches field widths for ll but one additional
#    field is added for units of measure (b Kb Mb Gb)
#   -k = use 1000 rather than 1024 for kilo

# CUSTOMIZATION:
#
# Set PAGER={favorite pager cmd such as more or less, etc}
#

USAGETXT="
  Usage: $MYNAME [-kq] [-l <len>] [ optional path(s) ]
    where -k = use 1000 instead of 1024 for kilo
          -l <len> = shows <len> lines (no PAGER)
          -q = quiet (no note at the end)
"
set -u
export PATH=/usr/bin
MYNAME=${0##*/}

TRACEME=${TRACEME:-false}               # TRACEME non-null = trace on
[ $TRACEME != false ]  && set -x && PS4='[$LINENO]: '

typeset -L10 PERM
typeset -R3  LINKS
typeset -L10 UID UIDBLANK
typeset -L8  GID
typeset -R6  VARSIZE
UIDBLANK=" "

# F U N C T I O N S
###################

###########
#  Usage  #
###########

function Usage
{
 # Minimum Usage function
 # Requires $USAGETXT to be assigned externally.
 #   Typically, this is done at the start of a script
 #   to act as both documentation and a Usage message

  TRACEME=${TRACEME:-false}      # TRACEME non-null = trace on
  [ $TRACEME != false ]  && set -x && PS4='[$LINENO]: '
  MYNAME=${MYNAME:-${0##*/}}

# If supplied, show an error message
  if [ $# -gt 0 ]
  then
     ERRMSG="$*"
     echo "\n$ERRMSG"
     WIDTH=${#ERRMSG}
     eval typeset -Z$WIDTH BAR=0
     echo "$BAR" | tr "0" "="
  fi

# Show the usage message - handle missing USAGETXT

  USAGETXT=${USAGETXT:-NotSet}
  [[ "$USAGETXT" = "NotSet" || "$USAGETXT" = "" ]] &&
     echo "\n$MYNAME: USAGETXT is null or not assigned" ||
     echo "$USAGETXT"
  exit 1
}


##################
#  Main Program  #
##################

KB=1024
QUIET=false
FIXEDLEN=0

while getopts ":qkl:" OPTCHAR
do
   case $OPTCHAR in
        k) KB=1000
           ;;
        l) FIXEDLEN="$OPTARG"
           ;;
        q) QUIET=true
           ;;
        *) eval "ERROPT=\$$(($OPTIND-1))"
           Usage "Invalid option(s): $ERROPT"
           ;;
   esac
done
shift $(($OPTIND -1))

## Setup the display method
## If -l is used, PAGER=head
## If $PAGER is set, use that
## Otherwise, use more

PAGER=${PAGER:-undef}
if [[ $FIXEDLEN -ne 0 ]]
then
   PAGER="head -$FIXEDLEN"
elif [[ "$PAGER" = undef ]]
then
   PAGER="more -e"
fi

# Setup test and divisor values

let KB1=$KB-1
let MB=$KB*$KB
let MB1=$KB*$KB-1
let GB=$KB*$KB*$KB
let GB1=$KB*$KB*$KB-1

# The incantation ${@+"$@"} ensures that all possible command line
# parameters will be represented including null and space/tab strings.
# This makes the script work exactly like ll except for the units of
# measure.

ls -la ${@+"$@"} \
   | sort -rnk5 \
   | while read PERM LINKS UID GID SIZE REST
     do
       [ "$UID" = "$UIDBLANK" ] && continue     # break out - ll returned subdirs
# find overall magnitude
       if [ "$PERM" != "total     " ]
       then
         SIZEDIGITS=${#SIZE}
         if [ $SIZEDIGITS -ge 13 ]                      # terabytes
         then
           UNITS="Tb"
           RSIZE=$(echo "scale=1 \n $SIZE/$GB/$KB" | bc)
         elif [ $SIZEDIGITS -ge 10 ]                    # gigabytes
         then
           UNITS="Gb"
           RSIZE=$(echo "scale=1 \n $SIZE/$GB" | bc)
         elif [ $SIZEDIGITS -ge 7 ]                     # megabytes
         then
           UNITS="Mb"
           RSIZE=$(echo "scale=1 \n $SIZE/$MB" | bc)
         elif [ $SIZEDIGITS -ge 4 ]                     # kilobytes
         then
           UNITS="Kb"
           RSIZE=$(echo "scale=1 \n $SIZE/$KB" | bc)
         fi
         if [ $SIZEDIGITS -le 3 ]                       # bytes
         then
           UNITS="b "
           RSIZE=$SIZE
           VARSIZE=$(printf "%6i" $SIZE)
         else
           VARSIZE=$(printf "%4.1f" $RSIZE)
         fi
         echo "$PERM $LINKS $UID $GID $VARSIZE $UNITS $REST"
       fi
     done | $PAGER
[[ "$QUIET" = false ]] && echo "Note: K = $KB bytes, M=K*K G=M*M"

 

 

Examples:

 

# lls /stand/vmunix
-rwxr-xr-x   4 root       sys       140.7 Mb May 29  2018 /stand/vmunix
Note: K = 1024 bytes, M=K*K G=M*M

# lls /stand
-rwxr-xr-x   4 root       sys       140.7 Mb May 29  2018 vmunix
-rw-r--r--   1 root       sys        19.4 Kb Jul 26 08:39 ext_ioconfig.lkg
-rw-r--r--   1 root       sys        19.4 Kb Jul 26 08:39 ext_ioconfig
drwxr-xr-x  62 root       root        8.0 Kb Sep 15 09:22 ..
drwxr-xr-x   5 root       sys         8.0 Kb Nov 21  2018 backup
drwxr-xr-x   5 root       sys         8.0 Kb Jul 23  2010 last_install
drwxr-xr-x   5 root       sys         8.0 Kb Feb  8  2019 current
drwxr-xr-x   5 root       root        8.0 Kb Oct 19  2021 crashconfig
dr-xr-xr-x   9 bin        bin         8.0 Kb Sep 15 09:22 .
-rw-r--r--   1 root       sys         7.2 Kb Jul 26 08:39 ioconfig.lkg
-rw-r--r--   1 root       sys         7.2 Kb Jul 26 08:39 ioconfig
-rw-r--r--   1 root       sys         6.2 Kb Apr 20  2018 system.prev
drwxr-xr-x   2 root       sys          96 b  Jul 26 08:41 krs
drwxr-xr-x   2 root       root         96 b  Jul 23  2010 lost+found
dr-xr-xr-x   3 bin        bin          96 b  Jul 23  2010 boot.sys
-rw-r--r--   1 root       sys          44 b  Feb 23  2021 bootconf
-rw-------   1 root       root         40 b  Jul 26 08:39 rootconf
lrwxr-xr-x   1 root       root         15 b  Jul 26 08:39 system -> nextboot/system
lrwxr-xr-x   1 root       root         14 b  Jul 26 08:39 bootfs -> current/bootfs
lrwxr-xr-x   1 root       root          7 b  Jul 26 08:39 nextboot -> current
-rw-r--r--   1 root       sys           0 b  Sep 15 09:22 IGNITE:2022-09-15
-rw-r--r--   1 root       sys           0 b  Jul 23  2010 .kc.lock
Note: K = 1024 bytes, M=K*K G=M*M


To show just the 10 largest files and drop the tag line at the bottom:

# lls -l 10 -q /stand
-rwxr-xr-x   4 root       sys       140.7 Mb May 29  2018 vmunix
-rw-r--r--   1 root       sys        19.4 Kb Jul 26 08:39 ext_ioconfig.lkg
-rw-r--r--   1 root       sys        19.4 Kb Jul 26 08:39 ext_ioconfig
drwxr-xr-x  62 root       root        8.0 Kb Sep 15 09:22 ..
drwxr-xr-x   5 root       sys         8.0 Kb Nov 21  2018 backup
drwxr-xr-x   5 root       sys         8.0 Kb Jul 23  2010 last_install
drwxr-xr-x   5 root       sys         8.0 Kb Feb  8  2019 current
drwxr-xr-x   5 root       root        8.0 Kb Oct 19  2021 crashconfig
dr-xr-xr-x   9 bin        bin         8.0 Kb Sep 15 09:22 .
-rw-r--r--   1 root       sys         7.2 Kb Jul 26 08:39 ioconfig.lkg

 

 

Examples:

 

# lls /stand/vmunix
-rwxr-xr-x   4 root       sys       140.7 Mb May 29  2018 /stand/vmunix
Note: K = 1024 bytes, M=K*K G=M*M

# lls /stand
-rwxr-xr-x   4 root       sys       140.7 Mb May 29  2018 vmunix
-rw-r--r--   1 root       sys        19.4 Kb Jul 26 08:39 ext_ioconfig.lkg
-rw-r--r--   1 root       sys        19.4 Kb Jul 26 08:39 ext_ioconfig
drwxr-xr-x  62 root       root        8.0 Kb Sep 15 09:22 ..
drwxr-xr-x   5 root       sys         8.0 Kb Nov 21  2018 backup
drwxr-xr-x   5 root       sys         8.0 Kb Jul 23  2010 last_install
drwxr-xr-x   5 root       sys         8.0 Kb Feb  8  2019 current
drwxr-xr-x   5 root       root        8.0 Kb Oct 19  2021 crashconfig
dr-xr-xr-x   9 bin        bin         8.0 Kb Sep 15 09:22 .
-rw-r--r--   1 root       sys         7.2 Kb Jul 26 08:39 ioconfig.lkg
-rw-r--r--   1 root       sys         7.2 Kb Jul 26 08:39 ioconfig
-rw-r--r--   1 root       sys         6.2 Kb Apr 20  2018 system.prev
drwxr-xr-x   2 root       sys          96 b  Jul 26 08:41 krs
drwxr-xr-x   2 root       root         96 b  Jul 23  2010 lost+found
dr-xr-xr-x   3 bin        bin          96 b  Jul 23  2010 boot.sys
-rw-r--r--   1 root       sys          44 b  Feb 23  2021 bootconf
-rw-------   1 root       root         40 b  Jul 26 08:39 rootconf
lrwxr-xr-x   1 root       root         15 b  Jul 26 08:39 system -> nextboot/system
lrwxr-xr-x   1 root       root         14 b  Jul 26 08:39 bootfs -> current/bootfs
lrwxr-xr-x   1 root       root          7 b  Jul 26 08:39 nextboot -> current
-rw-r--r--   1 root       sys           0 b  Sep 15 09:22 IGNITE:2022-09-15
-rw-r--r--   1 root       sys           0 b  Jul 23  2010 .kc.lock
Note: K = 1024 bytes, M=K*K G=M*M


To show just the 10 largest files and drop the tag line at the bottom:

# lls -l 10 -q /stand
-rwxr-xr-x   4 root       sys       140.7 Mb May 29  2018 vmunix
-rw-r--r--   1 root       sys        19.4 Kb Jul 26 08:39 ext_ioconfig.lkg
-rw-r--r--   1 root       sys        19.4 Kb Jul 26 08:39 ext_ioconfig
drwxr-xr-x  62 root       root        8.0 Kb Sep 15 09:22 ..
drwxr-xr-x   5 root       sys         8.0 Kb Nov 21  2018 backup
drwxr-xr-x   5 root       sys         8.0 Kb Jul 23  2010 last_install
drwxr-xr-x   5 root       sys         8.0 Kb Feb  8  2019 current
drwxr-xr-x   5 root       root        8.0 Kb Oct 19  2021 crashconfig
dr-xr-xr-x   9 bin        bin         8.0 Kb Sep 15 09:22 .
-rw-r--r--   1 root       sys         7.2 Kb Jul 26 08:39 ioconfig.lkg

 

 



Bill Hassell, sysadmin

Re: I want to know Size calculation using bash script

Great script Bill! If I was going to suggest some changes and enhancements (and I do!), I would say:

  1. You should really be using KB, MB, GB, TB etc. rather than Kb, Mb, Gb, Tb - by my understanding b = bit and B = byte. So network links are usually measured in bits (per second) e.g. a 100Mb link, but data storage sizes are usually measured in bytes e.g. 100MB file.
  2. If we're going to be really pedantic, then actually KB, MB, GB, TB - kilobyte, megabyte, gigabyte, terabyte etc are actually now used for decimal values (1000) and if we are using binary values the we should use KiB, MiB, GiB, TiB - kibibyte, mebibyte, gibibyte, tebibyte.

All summarised nicely in wikipedia: https://en.wikipedia.org/wiki/Byte#Multiple-byte_units

I'm sure you know all this, but would be nice to see the enhancement in the script ;op

 


I am an HPE Employee
Accept or Kudo
Bill Hassell
Honored Contributor

Re: I want to know Size calculation using bash script

Thanks for the reminder Duncan.

Here is the script with MB and MiB when using the -k option:

#!/usr/bin/sh
# POSIX-sh and ksh compatible

###################################
#
#     #       #        #####
#     #       #       #     #
#     #       #       #
#     #       #        #####
#     #       #             #
#     #       #       #     #
#     ####### #######  #####
#
###################################

# Revision history
# Oct  3 2022 blh Changed suffix from lower b to B for bytes
# May 14 2014 blh Added -r and -l options
# Dec 11 2013 blh Added -q option
#                 Drop -F option for a clean filename
# Jun 07 2013 blh Fixup to handle ll for multiple directories
# Jun 07 2013 blh Major rewrite to handle Gb and Tb without overflow
# Apr 07 2013 blh Added -t and PAGER choice
#                 Added tag line for magnitude
# Nov 03 2012 blh Original version
#

# Script to list largest files first with KB MB GB adjustments
# Output matches field widths for ll but one additional
#    field is added for units of measure (B KB MB GB)
#   -k = use 1000 rather than 1024 for kilo

# CUSTOMIZATION:
#
# Set PAGER=<favorite pager such as more or less, etc>
#

USAGETXT="
  Usage: $MYNAME [-kq] [-l <len>] [ optional path(s) ]
    where -k = use 1000 instead of 1024 for kilo
          -l <len> = shows <len> lines (no PAGER)
          -q = quiet (no note at the end)
"

set -u
export PATH=/usr/bin
MYNAME=${0##*/}

TRACEME=${TRACEME:-false}               # TRACEME non-null = trace on
[ $TRACEME != false ]  && set -x && PS4='[$LINENO]: '

typeset -L10 PERM
typeset -R3  LINKS
typeset -L10 UID UIDBLANK
typeset -L8  GID
typeset -R6  VARSIZE
UIDBLANK=" "



# F U N C T I O N S
###################

###########
#  Usage  #
###########

function Usage
{
 # Minimum Usage function
 # Requires $USAGETXT to be assigned externally.
 #   Typically, this is done at the start of a script
 #   to act as both documentation and a Usage message

  TRACEME=${TRACEME:-false}      # TRACEME non-null = trace on
  [ $TRACEME != false ]  && set -x && PS4='[$LINENO]: '
  MYNAME=${MYNAME:-${0##*/}}

# If supplied, show an error message
  if [ $# -gt 0 ]
  then
     ERRMSG="$*"
     echo "\n$ERRMSG"
     WIDTH=${#ERRMSG}
     eval typeset -Z$WIDTH BAR=0
     echo "$BAR" | tr "0" "="
  fi

# Show the usage message - handle missing USAGETXT

  USAGETXT=${USAGETXT:-NotSet}
  [[ "$USAGETXT" = "NotSet" || "$USAGETXT" = "" ]] &&
     echo "\n$MYNAME: USAGETXT is null or not assigned" ||
     echo "$USAGETXT"
  exit 1
}


##################
#  Main Program  #
##################

KB=1024
QUIET=false
FIXEDLEN=0

while getopts ":qkl:" OPTCHAR
do
   case $OPTCHAR in
        k) KB=1000
           ;;
        l) FIXEDLEN="$OPTARG"
           ;;
        q) QUIET=true
           ;;
        *) eval "ERROPT=\$$(($OPTIND-1))"
           Usage "Invalid option(s): $ERROPT"
           ;;
   esac
done
shift $(($OPTIND -1))

## Setup the display method
## If -l is used, PAGER=head
## If $PAGER is set, use that
## Otherwise, use more

PAGER=${PAGER:-undef}
if [[ $FIXEDLEN -ne 0 ]]
then
   PAGER="head -$FIXEDLEN"
elif [[ "$PAGER" = undef ]]
then
   PAGER="more -e"
fi

# Setup test and divisor values

let KB1=$KB-1
let MB=$KB*$KB
let MB1=$KB*$KB-1
let GB=$KB*$KB*$KB
let GB1=$KB*$KB*$KB-1

# The incantation ${@+"$@"} ensures that all possible command line
# parameters will be represented including null and space/tab strings.
# This makes the script work exactly like ll except for the units of
# measure.

ls -la ${@+"$@"} \
   | sort -rnk5 \
   | while read PERM LINKS UID GID SIZE REST
     do
       [ "$UID" = "$UIDBLANK" ] && continue     # break out - ll returned subdirs
# find overall magnitude
       if [ "$PERM" != "total     " ]
       then
         SIZEDIGITS=${#SIZE}
         if [ $SIZEDIGITS -ge 13 ]                      # terabytes
         then
           [ $KB -eq 1000 ] && UNITS=Tib || UNITS="TB"
           RSIZE=$(echo "scale=1 \n $SIZE/$GB/$KB" | bc)
         elif [ $SIZEDIGITS -ge 10 ]                    # gigabytes
         then
           [ $KB -eq 1000 ] && UNITS="GiB" || UNITS="GB"
           RSIZE=$(echo "scale=1 \n $SIZE/$GB" | bc)
         elif [ $SIZEDIGITS -ge 7 ]                     # megabytes
         then
           [ $KB -eq 1000 ] && UNITS="MiB" || UNITS="MB"
           RSIZE=$(echo "scale=1 \n $SIZE/$MB" | bc)
         elif [ $SIZEDIGITS -ge 4 ]                     # kilobytes
         then
           [ $KB -eq 1000 ] && UNITS="KiB" || UNITS="KB"
           RSIZE=$(echo "scale=1 \n $SIZE/$KB" | bc)
         fi
         if [ $SIZEDIGITS -le 3 ]                       # bytes
         then
           [ $KB -eq 1000 ] && UNITS="B  " || UNITS="B "
           RSIZE=$SIZE
           VARSIZE=$(printf "%6i" $SIZE)
         else
           VARSIZE=$(printf "%4.1f" $RSIZE)
         fi
         echo "$PERM $LINKS $UID $GID $VARSIZE $UNITS $REST"
       fi
     done | $PAGER
[[ "$QUIET" = false ]] &&
   [[ KB -eq 1000 ]] &&
      echo "Note: KiB = 1024 bytes, M=K*K G=M*M" ||
      echo "Note: KB = 1000 bytes, M=K*K G=M*M"

And some examples:

 # lls -l 10 /stand
-rwxr-xr-x   4 root       sys       140.7 MB May 29  2018 vmunix
-rw-r--r--   1 root       sys        19.4 KB Jul 26 08:39 ext_ioconfig.lkg
-rw-r--r--   1 root       sys        19.4 KB Jul 26 08:39 ext_ioconfig
drwxr-xr-x  62 root       root        8.0 KB Oct  2 01:11 ..
drwxr-xr-x   5 root       sys         8.0 KB Nov 21  2018 backup
drwxr-xr-x   5 root       sys         8.0 KB Jul 23  2010 last_install
drwxr-xr-x   5 root       sys         8.0 KB Feb  8  2019 current
drwxr-xr-x   5 root       root        8.0 KB Oct 19  2021 crashconfig
dr-xr-xr-x   9 bin        bin         8.0 KB Oct  1 09:22 .
-rw-r--r--   1 root       sys         7.2 KB Jul 26 08:39 ioconfig.lkg
Note: KB = 1000 bytes, M=K*K G=M*M

and

 # lls -l 10 -k /stand
-rwxr-xr-x   4 root       sys       147.6 MiB May 29  2018 vmunix
-rw-r--r--   1 root       sys        19.8 KiB Jul 26 08:39 ext_ioconfig.lkg
-rw-r--r--   1 root       sys        19.8 KiB Jul 26 08:39 ext_ioconfig
drwxr-xr-x  62 root       root        8.1 KiB Oct  2 01:11 ..
drwxr-xr-x   5 root       sys         8.1 KiB Nov 21  2018 backup
drwxr-xr-x   5 root       sys         8.1 KiB Jul 23  2010 last_install
drwxr-xr-x   5 root       sys         8.1 KiB Feb  8  2019 current
drwxr-xr-x   5 root       root        8.1 KiB Oct 19  2021 crashconfig
dr-xr-xr-x   9 bin        bin         8.1 KiB Oct  1 09:22 .
-rw-r--r--   1 root       sys         7.4 KiB Jul 26 08:39 ioconfig.lkg
Note: KiB = 1024 bytes, M=K*K G=M*M

I toyed with the idea to add peta exa and zeta....
but I haven't seen any files that large in HP-UX yet.



Bill Hassell, sysadmin
Steven Schweda
Honored Contributor

Re: I want to know Size calculation using bash script

> Here is the script with MB and MiB when using the -k option:
> [...]

   If you're using 1024 instead of 1000, is SIZEDIGITS what you care
about?

   Rounding (instead of truncating) might be nice, too.  For example,
511 is closer to 512 than you'd make it look:

$ echo "scale=1 ; 512/ 1024" | bc
.5
$ echo "scale=1 ; 511/ 1024" | bc
.4

   Everything's complicated.