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
  • 333,661
  • 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 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 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