Colored text printing spaces in shell script

2019-09-10 17:07发布

问题:

I wish to create a shell script to output my current memory usage and CPU usage as bars (for use in a tmux config file)

The expected output will be something like this:

My shell script so far looks like this:

# Determine CPU load
pcpu=$(ps -Ao pcpu | awk '{sum = sum + $1}END{print sum}')

# Determine MEM load
mem=$(ps -Ao rss | awk '{sum = sum + $1}END{print sum}')

# Determine total MEM
tmem=$(cat /proc/info | awk '/MemTotal/ {print $2}')

# Helper function to convert KB to KB/MB/GB/TB
pretty_print() {
  # We start with KB from /proc/meminfo and ps
  [ $1 -lt 16384 ] && echo "${KB} K" && return
  MB=$((($1+512)/1024))
  [ $MB -lt 16384 ] && echo "${KB} M" && return
  GB=$((($MG+512)/1024))
  [ $GB -lt 16384 ] && echo "${KB} G" && return
  TB=$((($GB+512)/1024))
  [ $TB -lt 16384 ] && echo "${KB} T" && return
}

# Helper function to print bars for percentages
print_bars() {
  local GREEN='\033[32m'
  local YELLOW='\033[33m'
  local RED='\033[31m'
  local RESET='\033[0m'
  local current=$(($1*10/$2))
  local bars=0
  while [ $current -gt 0 ]; do
    [ $bars -lt 3 ] && echo $GREEN
    [ $bars -gt 2 ] && echo $YELLOW
    [ $bars -gt 5 ] && echo $RED
    echo '|'
    current=$(($current - 1))
    bars=$((bars + 1))
  done
  echo $RESET
  while [ $bars -lt 10 ]; do
    echo ' '
    bars=$((bars + 1))
  done
}

# Output: CPU $pcpu [|||   ] - MEM $mem / $tmem [|||   ]
echo CPU $pcpu \[$(print_bars $pcpu 100)\] - MEM $(human_print $mem) / $(human_print $tmem) \[$(print_bars $mem $tmem)\]

I'm encountering two separate issues:

  1. All terminating spaces are stripped from the output of print_bars. This is causing it to print things like [| ] or [|||| ] instead of the appropriate [| ] and [|||| ]
  2. The more annoying and the reason for this post: the color codes (\033[Xm) are being printed as spaces in my terminal, putting spaces between the bars like so:

回答1:

You need to put double quotes around the calls to print_bars to prevent word splitting, which removes excess spaces.

echo "CPU $pcpu [$(print_bars $pcpu 100)] - MEM $(human_print $mem) / $(human_print $tmem) [$(print_bars $mem $tmem)]"

The spaces around the color codes are because commands like

echo $GREEN

add a newline after the output, which turns into a space by word splitting. You should use

echo -n $GREEN

or

printf "%s" "$GREEN"


标签: bash shell