richbai90
richbai90

Reputation: 5204

How to reset tput text decoration and color

I have a bash script and I want to be able to highlight critical errors when they occur. To that end I wrote the simple function below

error() {
# set the text decoration
tput -S <<END
bold
setaf 1
END
# echo the error to stderr
echo "$1" 1>&2
exit 1
}

The problem with this code is that the terminal keeps the tput settings after the script exits. I have tried rectifying this in two ways.

  1. Add a tput reset command before exiting
  2. Execute the commands in a subshell

Option 1 doesn't work because it clears the terminal completely, even with the -x option.

Option 2 doesn't seem to have any effect, the terminal remains changed even after returning to the main shell. My option 2 code looks like this

error() {
    bash -C <<EOF
tput -S <<END
bold
setaf 1
END
echo "$1" 1>&2
EOF
    exit 1
}

Upvotes: 0

Views: 2464

Answers (2)

Vab
Vab

Reputation: 442

A simpler alternative for having colored text output without additional packages.

Copy and paste the following lines to your shell and call the corresponding function passing it desired message, you will see how cool is the output, quick and simple )

:<<'ANSIcolorCodes'
Black        0;30     Dark Gray     1;30
Red          0;31     Light Red     1;31
Green        0;32     Light Green   1;32
Brown/Orange 0;33     Yellow        1;33
Blue         0;34     Light Blue    1;34
Purple       0;35     Light Purple  1;35
Cyan         0;36     Light Cyan    1;36
Light Gray   0;37     White         1;37
ANSIcolorCodes

# # # Just to have unify messages # # #
type echo_blue  echo_green  echo_red  echo_red_s &> /dev/null || {
  echo_blue(){
   echo -en "\033[0;34m$*" ;echo -e "\033[0;0m"
  }
  echo_green(){
   echo -en "\033[0;32m$*" ;echo -e "\033[0;0m"
  }
  echo_red(){
   echo -en "\033[0;31m$*" ;echo -e "\033[0;0m"
  }
  echo_red_s(){
   echo -en "\033[9;31m$*" ;echo -e "\033[0;0m"
  }
  ### Due to Update #1
  # Define Bold
  echo_bold(){ 
   echo -en "\033[1m$*" ;echo -e "\033[0m"; 
  }
  # Define Blue-Bold, and so on for any other color if needed.
  echo_blue_bold(){ echo_blue `echo_bold "$*"`; }
}

Reference link:

Update #1 (01 Sep 2022)

This is the BOLD syntax of echo command with ANSI.

  • echo -e '\033[1mYOUR_STRING\033[0m'

Please review and test the provided functions including the updated code part at the end.

Upvotes: 0

KamilCuk
KamilCuk

Reputation: 140960

You output tput sgr0. I would do:

error() {
   tput bold setaf 1 >&2
   echo "ERROR: $*" >&2
   tput sgr0 >&2
}

Or "more advanced":

error() {
   tput bold setaf 1
   echo "ERROR: $*"
   tput sgr0
} >&2

It is odd that you are using bash -C, -C sets C flag in $-, which disallows overwriting an existing file with the >, >&, and <> redirection operators, see Bash manual about set builtin command. Just bash, without -C, or bash -s <arg> <arg2>.

Upvotes: 2

Related Questions