1

I'm trying to create a shell script that sets up my Ubuntu server for a Laravel app. The user is asked to confirm before proceeding with the following code taken from here:

How do I prompt a user for confirmation in bash script?

#!/bin/sh
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' 

echo "\n ${GREEN}Enter the folder name for the Laravel application: ${NC}"
read APP_NAME


read -r -p "Are you sure? [y/N] " response
response=${response,,}    # tolower
if [[ $response =~ ^(yes|y)$ ]]
then
    echo "Installing dependencies..."
else
    exit
fi

I'm getting this error:

Bad substitution 

on the line

response=${response,,}    # tolower
Community
  • 1
  • 1
zeros-and-ones
  • 4,227
  • 6
  • 35
  • 54
  • How are you running your script? Your code is fine. What OS (you say Linux, but is this under some windoze interpreter?) Tested on `GNU bash, version 4.3.42(1)-release ` – David C. Rankin Jul 07 '16 at 05:15
  • I am running the script by calling ./script-name after i chmod u+x, running on Ubuntu 16.04 GNU bash, version 4.3.42(1)-release (x86_64-pc-linux-gnu) – zeros-and-ones Jul 07 '16 at 05:17
  • I would check to make sure you do not have `carriage returns` or some other stray *Unicode* character embedded in your script. The actual script is OK. Confirm with `hexdump -C yourscriptname`. Also, in you actual script, you are including `#!/bin/bash` at the top, right? (I don't know what Ubuntu uses for the default shell) – David C. Rankin Jul 07 '16 at 05:18
  • checking now good call thanks. – zeros-and-ones Jul 07 '16 at 05:19
  • Are you sure? [y/N] Y ./test.sh: 2: ./test.sh: Bad substitution – zeros-and-ones Jul 07 '16 at 05:27
  • I added to my comment above, make sure you have `#!/bin/bash` at the top of Ubuntu may be attempting to run it with dash (that has no *parameter expansion* to lower case -- which would trigger the *Bad Substitution*. Or call the script with `bash test.sh` – David C. Rankin Jul 07 '16 at 05:29
  • That fixed it for the test.sh script that i was using to isolate just the confirm statement. The original had #!/bin/sh in stead of bash – zeros-and-ones Jul 07 '16 at 05:31
  • Ha! Happens -- good luck with your scripting. – David C. Rankin Jul 07 '16 at 05:33
  • By changing it to #!/bin/bash from #!/bin/sh the confirm now is working but I lost my colors. – zeros-and-ones Jul 07 '16 at 05:34
  • Are you using `ANSI` escapes or `tput`? Both will work fine under bash, but you will have to tell it what colors to use. I'm sure there is an option somewhere that causes bash to reset the terminal when a script is invoked. (no clue what off the top of my head). There are many examples of color use with bash on SO. `tput` is favored, but `ANSI` works fine too via `printf` or `echo -e`. – David C. Rankin Jul 07 '16 at 05:37
  • I guess I am using ANSI, thank you. Adding -e flag to my echo statements cleaned that up. – zeros-and-ones Jul 07 '16 at 05:40
  • Alright adding -e and changing sh to bash were the two solutions I needed. Thank you so much. If you want to add "make sure you have #!/bin/bash" as an answer I'll mark it as correct. – zeros-and-ones Jul 07 '16 at 05:45

2 Answers2

0

This is a case modification substitution. Here is the description (from the Bash manual on shell parameter expansion):

${parameter^pattern}
${parameter^^pattern}
${parameter,pattern}
${parameter,,pattern}

This expansion modifies the case of alphabetic characters in parameter. The pattern is expanded to produce a pattern just as in filename expansion. Each character in the expanded value of parameter is tested against pattern, and, if it matches the pattern, its case is converted. The pattern should not attempt to match more than one character. The ‘^’ operator converts lowercase letters matching pattern to uppercase; the ‘,’ operator converts matching uppercase letters to lowercase. The ‘^^’ and ‘,,’ expansions convert each matched character in the expanded value; the ‘^’ and ‘,’ expansions match and convert only the first character in the expanded value. If pattern is omitted, it is treated like a ‘?’, which matches every character. If parameter is ‘@’ or ‘*’, the case modification operation is applied to each positional parameter in turn, and the expansion is the resultant list. If parameter is an array variable subscripted with ‘@’ or ‘*’, the case modification operation is applied to each member of the array in turn, and the expansion is the resultant list.

This works on bash >= 4.0.

Alternatively, you can use

response=$(echo "$response" | tr '[:upper:]' '[:lower:]')
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Diego Torres Milano
  • 65,697
  • 9
  • 111
  • 134
0

Thanks to David C. Rankins help in the comments section this issue was resolved by changing:

#!/bin/sh

to

#!/bin/bash

and changing

echo "string data"

to

echo -e "string data"
zeros-and-ones
  • 4,227
  • 6
  • 35
  • 54