0

I have 2 scripts. script.conf

#!/bin/bash
set -o errexit
set -o nounset
set -o pipefail
# set -o xtrace

[ -f $HOME/Templates/bash_colors.sh ] && source $HOME/Templates/bash_colors.sh

INFO=${INFO:-"1"}
DEBUG=${DEBUG:-"0"}
ERROR=${ERROR:-"1"}

Red=${Red:-}
Yellow=${Yellow:-}
Cyan=${Cyan:-}
Color_Off=${Color_Off:-}
__msg_error() {
    [[ "${ERROR}" == "1" ]] && echo -e "${Red}[ERROR]: $*${Color_Off}";
}

__msg_debug() {
    [[ "${DEBUG}" == "1" ]] && echo -e "${Yellow}[DEBUG]: $*${Color_Off}";
}

__msg_info() {
    [[ "${INFO}" == "1" ]] && echo -e "${Cyan}[INFO]: $*${Color_Off}";
}

and testConf.sh

#!/bin/bash

# INFO="0"

scriptDir="${BASH_SOURCE%/*}"
[ -f ${scriptDir}/script.conf ] && source ${scriptDir}/script.conf

INFO="0"


__msg_error "Test error1"

__msg_info "Test Info"

__msg_error "Test error2"

__msg_debug "Test debug"

The strange thing is if set INFO to 0 I would expect that both error messages would be echoed which is not the case. Just the first will printed. I don't understand why. Maybe you have an idea?

It seem like the script is stopped when INFO is 0.

See the trace:

++ INFO=1
++ DEBUG=0
++ ERROR=1
++ Red='\033[0;31m'
++ Yellow='\033[0;33m'
++ Cyan='\033[0;36m'
++ Color_Off='\033[0m'
+ INFO=0
+ __msg_error 'Test error1'
+ [[ 1 == \1 ]]
+ echo -e '\033[0;31m[ERROR]: Test error1\033[0m'
[ERROR]: Test error1
+ __msg_info 'Test Info'
+ [[ 0 == \1 ]]

But why?

bash_colors.sh

#!/bin/bash


# src: https://stackoverflow.com/a/28938235/1959528
# Reset
Color_Off='\033[0m'       # Text Reset

# Regular Colors
Black='\033[0;30m'        # Black
Red='\033[0;31m'          # Red
Green='\033[0;32m'        # Green
Yellow='\033[0;33m'       # Yellow
Blue='\033[0;34m'         # Blue
Purple='\033[0;35m'       # Purple
Cyan='\033[0;36m'         # Cyan
White='\033[0;37m'        # White

# Bold
BBlack='\033[1;30m'       # Black
BRed='\033[1;31m'         # Red
BGreen='\033[1;32m'       # Green
BYellow='\033[1;33m'      # Yellow
BBlue='\033[1;34m'        # Blue
BPurple='\033[1;35m'      # Purple
BCyan='\033[1;36m'        # Cyan
BWhite='\033[1;37m'       # White

# Underline
UBlack='\033[4;30m'       # Black
URed='\033[4;31m'         # Red
UGreen='\033[4;32m'       # Green
UYellow='\033[4;33m'      # Yellow
UBlue='\033[4;34m'        # Blue
UPurple='\033[4;35m'      # Purple
UCyan='\033[4;36m'        # Cyan
UWhite='\033[4;37m'       # White

# Background
On_Black='\033[40m'       # Black
On_Red='\033[41m'         # Red
On_Green='\033[42m'       # Green
On_Yellow='\033[43m'      # Yellow
On_Blue='\033[44m'        # Blue
On_Purple='\033[45m'      # Purple
On_Cyan='\033[46m'        # Cyan
On_White='\033[47m'       # White

# High Intensity
IBlack='\033[0;90m'       # Black
IRed='\033[0;91m'         # Red
IGreen='\033[0;92m'       # Green
IYellow='\033[0;93m'      # Yellow
IBlue='\033[0;94m'        # Blue
IPurple='\033[0;95m'      # Purple
ICyan='\033[0;96m'        # Cyan
IWhite='\033[0;97m'       # White

# Bold High Intensity
BIBlack='\033[1;90m'      # Black
BIRed='\033[1;91m'        # Red
BIGreen='\033[1;92m'      # Green
BIYellow='\033[1;93m'     # Yellow
BIBlue='\033[1;94m'       # Blue
BIPurple='\033[1;95m'     # Purple
BICyan='\033[1;96m'       # Cyan
BIWhite='\033[1;97m'      # White

# High Intensity backgrounds
On_IBlack='\033[0;100m'   # Black
On_IRed='\033[0;101m'     # Red
On_IGreen='\033[0;102m'   # Green
On_IYellow='\033[0;103m'  # Yellow
On_IBlue='\033[0;104m'    # Blue
On_IPurple='\033[0;105m'  # Purple
On_ICyan='\033[0;106m'    # Cyan
On_IWhite='\033[0;107m'   # White
antibus
  • 983
  • 1
  • 11
  • 16
  • 1
    Guess - you are running the script in the $PWD with `bash scriptname`, so `scriptDir="${BASH_SOURCE%/*}"` results in the script name (there is no path info to trim from the right) so `[ -f ${scriptDir}/script.conf ]` fails -- explaining your `It seem like the script is stopped when INFO is 0.` This is not a guess - ANSI colors are nice -- but are generally more trouble than they are worth if you need any type of portability. (not t mention their impact on script readability if used heavily -- even with nice names for the escape sequences) – David C. Rankin Sep 14 '20 at 07:18
  • @DavidC.Rankin I tried without colors and it still didn't work. Also `script.conf` is correctly sourced. Otherwise even the first error message would not have been printed right? – antibus Sep 14 '20 at 07:37
  • If you look at your output `++ Color_Off='\033[0m'` is from sourcing `source $HOME/Templates/bash_colors.sh` in `script.conf`. Your next output is `+ INFO=0` meaning sourcing `${scriptDir}/script.conf` in `testConf.sh` failed. – David C. Rankin Sep 14 '20 at 07:47
  • Mh... I am not sure I understood this correctly. I execute `testConf.sh`. If the sourcing of `script.conf` would fail I wouldn't do anything related to colors. It would just set `INFO` to 0 and would try calling all the `__msg_*` which would fail. Even tracing wouldn't work as `set -o xtrace` is set in `script.conf`. – antibus Sep 14 '20 at 08:01
  • Okay, I agree with what you are saying there. Go ahead a post your `bash_colors.sh` so I can pull them all down and see what it going on. – David C. Rankin Sep 14 '20 at 08:29
  • Thx... I added the `bash_colors.sh` – antibus Sep 14 '20 at 08:50

2 Answers2

1

Your code is doing what you have told it do. In scipt.conf you set a number of flags, particularly the errexit flag and initialize your error, debug and info flags:

INFO=${INFO:-"1"}
DEBUG=${DEBUG:-"0"}
ERROR=${ERROR:-"1"}

And you create your functions that make use of the flags:

__msg_error() {
    [[ "${ERROR}" == "1" ]] && echo -e "${Red}[ERROR]: $*${Color_Off}";
}

__msg_debug() {
    [[ "${DEBUG}" == "1" ]] && echo -e "${Yellow}[DEBUG]: $*${Color_Off}";
}

__msg_info() {
    [[ "${INFO}" == "1" ]] && echo -e "${Cyan}[INFO]: $*${Color_Off}";
}

(note: your ERRORand INFO flags are set to 1)

Then in testConf.sh you set INFO to zero so the only messages that will be output is with ERROR=1

INFO="0"


__msg_error "Test error1"

__msg_info "Test Info"

__msg_error "Test error2"

__msg_debug "Test debug"

Running the scripts give the expected output, "Test error1" and "Test error2" are displayed fine and quite red, e.g.

$ bash ./testConf.sh
[ERROR]: Test error1
[ERROR]: Test error2

Note: however it is mandatory you provide "./" before the filename, otherwise the condition I discuss in the first comment will occur, (you concatenate two filenames since there would be no path information when run from $PWD without the "./" causing the test and source to fail.

When you complained only one output was shown, the set -o errexit causes the entire script to exit on the first error. If you want to follow what is done, just add set -x as the fist line under #!/bin/bash in your script. You will find the exit was triggered due to the comparison for 'Test Info' failing [[ 0 == \1 ]] and it would be normal behavior to then exit skipping the Test error2 output.

In conf.script, I would suggest a validating both the existence and non-empty nature of the file to be sourced before attempting the source, and also check that the source completed without error, e.g.

colorfile="$HOME/tmpd/bash_colors.sh"

if [ ! -s "$colorfile" ]; then
    printf "error: file not found or empty '%s'\n" "$colorfile" >&2
else
    . "$colorfile" || {
        printf "error: failed to source '%s'\n" "$colorfile" >&2
    }
fi

(note: you can use '.' to source the file into the current. '.' was the orgiinal source operator, but sometime later the alias for source was added as well.

Let me know if you are having problems elsewhere. It may be a stray character like a carriage-return stuck in your file that is not copied when I copy the snippets down.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • Removing `set -o errexit` actually solves the issue. Now I see both error messages. Thx. However I wasn't aware that `[[ "${INFO}" == "1" ]]` is considered an error an bash exit. – antibus Sep 14 '20 at 09:52
  • Glad you got it sorted out. Generally, unless you have read `man bash` with a fine-toothed-comb before setting all of the options, it is best to stick with `set -x` for initial debugging. Good luck with your scripting! – David C. Rankin Sep 14 '20 at 09:54
-1

If you set INFO to 0, you have the following assignments to the variables which are relevant to __msg_error

INFO : 0

DEBUG : 0

ERROR : 1

Hence, only ERROR is printed.

user1934428
  • 19,864
  • 7
  • 42
  • 87