Technology Tales

Adventures in consumer and enterprise technology

TOPIC: INFINITE LOOP

Adding visual appeal to bash command line scripts with colour variables on Linux

23rd November 2025

While I was updating some scripts to improve their functionality, I made some unexpected discoveries. One involved adding some colour to the output, and a second will come up later. The colours can be defined as values of variables, as you can see below:

# Colours
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # no colour

In all cases, \033 is the shell escape sequence while [ is the control sequence initiator and m closes the sequence for colour definitions like we have here. A numeric value of 0 resets things to the default, which is how it is used in the no colour (NC) case that we have above to ensure that the colouration does not overflow beyond the intended text. Otherwise, 31 specifies red, 32 specifies green and 33 specifies yellow, giving options to use later on in the code. All of this is in line with the ANSI standard.

This is how these colour variables get used:

echo -e "\n${YELLOW}$(printf '*' {1..40}) All done $(printf '*' {1..40})${NC}\n"

The above is for an example with yellow text produced using ${YELLOW} segment after the newline sequence (\n)  that is activated b y the -e switch passed to the echo command. This is turned off by the ${NC} portion at the end of the text, again before a terminating newline sequence. One extra addition here is the part that outputs forty asterisks: $(printf '*' {1..40}). You could have $(printf '*%.0s' {1..40}) instead, which is clearer to some because of the null output character sequence %.0s. In the earlier example, I opted for the simpler option.

AND & OR, a cautionary tale

27th March 2009

The inspiration for this post is a situation where having the string "OR" or "AND" as an input to a piece of SAS Macro code, breaking a program that I had written. Here is a simplified example of what I was doing:

%macro test;
    %let doms=GE GT NE LT LE AND OR;
    %let lv_count=1;
    %do %while (%scan(&doms,&lv_count,' ') ne );
        %put &lv_count;
        %let lv_count=%eval(&lv_count+1);
    %end;
%mend test;

%test;

The loop proceeds well until the string "AND" is met and "OR" has the same effect. The result is the following message appears in the log:

ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: %scan(&doms,&lv_count,' ') ne
ERROR: The condition in the %DO %WHILE loop, , yielded an invalid or missing value, . The macro will stop executing.
ERROR: The macro TEST will stop executing.

Both AND & OR (case doesn't matter, but I am sticking with upper case for sake of clarity) seem to be reserved words in a macro DO WHILE loop, while equality mnemonics like GE cause no problem. Perhaps, the fact that and equality operator is already in the expression helps. Regardless, the fix is simple:

%macro test;
    %let doms=GE GT NE LT LE AND OR;
    %let lv_count=1;
    %do %while ("%scan(&doms,&lv_count,' ')" ne "");
        %put &lv_count;
        %let lv_count=%eval(&lv_count+1);
    %end;
%mend test;

%test;

Now none of the strings extracted from the macro variable &DOMS will appear as bare words and confuse the SAS Macro processor, but you do have to make sure that you are testing for the null string ("" or '') or you'll send your program into an infinite loop, always a potential problem with DO WHILE loops so they need to be used with care. All in all, an odd-looking message gets an easy solution without recourse to macro quoting functions like %NRSTR or %SUPERQ.

  • The content, images, and materials on this website are protected by copyright law and may not be reproduced, distributed, transmitted, displayed, or published in any form without the prior written permission of the copyright holder. All trademarks, logos, and brand names mentioned on this website are the property of their respective owners. Unauthorised use or duplication of these materials may violate copyright, trademark and other applicable laws, and could result in criminal or civil penalties.

  • All comments on this website are moderated and should contribute meaningfully to the discussion. We welcome diverse viewpoints expressed respectfully, but reserve the right to remove any comments containing hate speech, profanity, personal attacks, spam, promotional content or other inappropriate material without notice. Please note that comment moderation may take up to 24 hours, and that repeatedly violating these guidelines may result in being banned from future participation.

  • By submitting a comment, you grant us the right to publish and edit it as needed, whilst retaining your ownership of the content. Your email address will never be published or shared, though it is required for moderation purposes.