14
read -p "Enter yes/no   " SOMEVAR

SOMEVAR=`"echo ${SOMEVAR,,}"`

The code above gives me a ${SOMEVAR,,}: bad substitution error.

1 Answers1

21

The parameter expansion ${variable,,} would expand to the value of $variable with all character in lower case in the bash shell. Given that you get a "bad substitution" error when this code runs suggests that you are in fact either

  • not using that shell but possibly /bin/sh (which is not always bash). But not getting an error for read -p suggests that it's more likely that you are
  • using an older release of bash which does not support this expansion (introduced in release 4 of bash).

The generic form of the expansion is ${variable,,pattern} in which all characters in $variable that matches pattern would be converted to lower case (use ^^ to convert to upper case):

$ str="HELLO"
$ printf '%s\n' "${str,,[HEO]}"
heLLo

See also the bash manual on your system.


For older releases of bash, you could instead do the following to lowercase the value of a variable:

variable=$( tr 'A-Z' 'a-z' <<<"$variable" )

This passes the value of the variable through tr using a "here-string". The tr utility transliterates all characters in the A to Z ASCII range (assuming the C/POSIX locale) to the corresponding character in the a to z range.


Note also that

SOMEVAR=`"echo ${SOMEVAR,,}"`

is better written as

SOMEVAR=${SOMEVAR,,}

In fact, what you wrote would give you a "command not found" error in bash release 4+, unless you have a command called echo string, including the space (where string was what the user inputted). This is due to the command substitution trying to execute the double quoted string.

Kusalananda
  • 320,670
  • 36
  • 633
  • 936
  • 5
    or they have a pre-4.0 Bash (like the 3.2 on Macs) – ilkkachu Feb 12 '19 at 20:54
  • @ilkkachu Well spotted! – Kusalananda Feb 12 '19 at 20:54
  • @Kusalananda thank you for the explanation and the HELLO example. Though this is part of an installation script which has #!/bin/bash at the start. – Hitanshu Sachania Feb 12 '19 at 21:04
  • @HitanshuSachania The script _assumes_ that you have a more recent `bash` installed in `/bin/bash`. To fix that, try installing a newer `bash` using Homebrew (if you're on macOS) and then run the script with that `bash` as `/usr/local/bin/bash installscript` (or whatever the script is called), or change the `#!`-line to point to the newer `bash`. – Kusalananda Feb 12 '19 at 21:07
  • 1
    @HitanshuSachania If it's macOS, then I would _not_ recommend replacing the `/bin/bash` binary with a newer version. – Kusalananda Feb 13 '19 at 08:54
  • @Kusalananda it's Ubuntu on my university's cluster. The BASH version is 3.2.51. I've asked them to update it which might take a while, but are you certain updating BASH might resolve this error? – Hitanshu Sachania Feb 13 '19 at 17:33
  • @HitanshuSachania If `bash` is updated past release 4 (the latest is release 5.0), it is guaranteed to work. Well, the `${variable,,}` thing will work anyway. Also note that an Ubuntu installation running a `bash` that is _that_ old is uncommon (it must be older than Ubuntu 14, which has reached its end of life now), and I would seriously question the sysadmin's dedication to keeping the system up to date and secure. – Kusalananda Feb 13 '19 at 17:38
  • 2
    @HitanshuSachania if they really have a bash version 3.2, then they're probably using Ubuntu 8.04 since [that was the last one](http://old-releases.ubuntu.com/releases/hardy/ubuntu-8.04-dvd-amd64.list) to ship with a 3.2 bash. That's almost 11 years old! Using software that old is an enormous security risk. In fact, there is [a whopping huge bug](https://unix.stackexchange.com/q/157381/22222) in bash itself. That should be a good way of convincing them to upgrade although any sysadmin who has allowed this to happen is a bigger security risk than the bugs themselves. – terdon Feb 13 '19 at 17:49
  • @Kusalananda sorry, that was an error from my side. The system has SUSE Linux (Release: 11). – Hitanshu Sachania Feb 13 '19 at 18:00
  • @terdon the system actually has SUSE Linux (Release: 11). Don't know how I believed it had Ubuntu. – Hitanshu Sachania Feb 13 '19 at 18:02
  • 1
    @HitanshuSachania Still, that's from 2009 (end of support in 2010) and the `bash` installed on it would likely be a security risk in itself. – Kusalananda Feb 13 '19 at 18:03
  • 1
    @Kusalananda I shall take this point to them. Thank you for all your help. – Hitanshu Sachania Feb 13 '19 at 18:07
  • 1
    @Kusalananda I have BASH 5 in the system now but the error persists. `while [[ $SOMEVAR = "" ]] ; do read -n 3 -p "Do you agree with license terms and conditions? (y/n) " SOMEVAR SOMEVAR=`echo "${SOMEVAR,,}"` done if [[ "$SOMEVAR" == "y" || "$SOMEVAR" == "yes" ]] ; then` This is how the erroneous part of the script is. – Hitanshu Sachania Feb 20 '19 at 19:09
  • 1
    @HitanshuSachania The `echo` should not be there. See the second part of my answer. Do you still get a "bad substitution" error? – Kusalananda Feb 20 '19 at 19:18
  • 1
    @Kusalananda Sorry for the late reply. Changing the script according to the 2nd part of your answer worked. Thank you. Though I still don't understand why did the original script not work for me but worked for others. – Hitanshu Sachania Feb 25 '19 at 07:56