This blog post is about a situation where you are capitalising an argument in bash and you get the following error:
bash: ${state^^}: bad substitution
In this example I was capitalising a variable called state to STATE. After some quick googling I found that the reason I am getting this error is not because of my bad coding – but because I might not be using a version of bash greater than 4.
When I checked the version I am using on my mac it was:
$ bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin20)
Copyright (C) 2007 Free Software Foundation, Inc.
and running the same command in Visual Studio showed the same – that I was running 3.2.57 (??!!??)
Which seemed quite old – that copyright of 2007 gives it away. I am running Big Sur – version 11.1 of macOS and from some more googling it appears there is some history around Apple and Bash and GPL licenses and <yawn>…… here are some links http://meta.ath0.com/2012/02/05/apples-great-gpl-purge/ and
And I realised that many macOS users probably don’t know is that they are using an outdated version of Bash shell.
How to upgrade Bash on macOS.
For macOS you should use homebrew to install things:
$ brew install bash
To verify the installation, you can check that you now have two versions of Bash on your system:
$ which -a bash
/usr/local/bin/bash
/bin/bash
The first one is the new version, and the second one is the old version:
$ /usr/local/bin/bash --version
GNU bash, version 5.1.4(1)-release (x86_64-apple-darwin20.2.0)
Copyright (C) 2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ /bin/bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin20.2.0)
Copyright (C) 2007 Free Software Foundation, Inc.
Since the directory of the new version (/usr/local/bin) comes by default before the directory of the old version (/bin) in the PATH variable, the version used when you just type bash is the new one:
$ bash –version
GNU bash, version 5.1.4(1)-release (x86_64-apple-darwin20.2.0)
Copyright (C) 2020 Free Software Foundation, Inc.
We now need to whitelist our shell as Unix systems restrict this, so to use the newly installed Bash shell as the default shell, it must be able to act as a login shell. So we will add it to the /etc/shells
file. We will edit this file as the root user:
$ sudo vim /etc/shells
and enter in your admin password.
You will now be in vim editor:
Use the i key to go into INSERT mode, paste in /usr/local/bin/bash down the bottom then hit th ESC key and type
:wq!
Which will write and save our changes.
Set Default Shell
Because /bin/bash
is still set as the default shell – you will still be using version 3.2.57. To change this to the new shell, execute the following command:
$ chsh -s /usr/local/bin/bash
The default shell for your user is now set to the new version of Bash. If you close and reopen the terminal window, you should now be using the new version already:
$ echo "$BASH_VERSION"
5.1.4(1)-release
The chsh
command changes the default shell only for the user who executes the command. If you want to change the default shell for other users too, so run the following (which will ask for your admin password):
$ sudo chsh -s /usr/local/bin/bash
All done – right?
So I went back into Visual Code and ran the original script – but still had the issue!!
Updating Visual Code to use the new Bash version
I found you need to go to Preferences and change Settings:
In the search field type in bash
click on “Edit in settings.json” for Osx and enter in “/usr/local/bin/bash” as shown below
Exit the Terminal and a new bash session will have
echo "$BASH_VERSION"
5.1.4(1)-release
I ran my script and it worked.
Yip.