TOPIC: C STANDARD LIBRARY
Adding visual appeal to bash command line scripts with colour variables on Linux
23rd November 2025While 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.
Catching keyboard interruptions in a Python script for a more orderly exit
17th April 2024A while back, I was using a Python script to watch a folder and process photos in there, whenever a new one was added. Eventually, I ended up with a few of these because I was unable to work out a way to get multiple folders watched in the same script.
In each of them, though, I needed a tidy way to exit a running script in place of the stream of consciousness that often emerges when you do such things to it. Because I knew what was happening anyway, I needed a script to terminate quietly and set to uncover a way to achieve this.
What came up was something like the code that you see below. While I naturally did some customisations, I kept the essential construct to capture keyboard interruption shortcuts, like the use of CTRL + C in a Linux command line interface.
if __name__ == '__main__':
try:
main()
except KeyboardInterrupt:
print('Interrupted')
try:
sys.exit(130)
except SystemExit:
os._exit(130)
What is happening above is that the interruption operation is captured in a nested TRY/EXCEPT block. The outer block catches the interruption, while the inner one runs through different ways of performing the script termination. For the first termination function call, you need to call the SYS package and the second needs the OS one, so you need to declare these at the start of your script.
Of the two, SYS.EXIT is preferable because it invokes clean-up activities while OS._EXIT does not, which might explain the "_" prefix in the second of these. In fact, calling SYS.EXIT is not that different to issuing RAISE SYSTEMEXIT instead because that lies underneath it. Here OS._EXIT is the fallback for when SYS.EXIT fails, and it is not all that desirable given the abrupt action that it invokes.
The exit code of 130 is fed to both, since that is what is issued when you terminate a running instance of an application on Linux anyway. Using 0 could negate any means of picking up what has happened if you have downstream processing. In my use case, everything was standalone, so that did not matter so much.