bash: Bad Substitution
Asked Answered
P

14

250
#!/bin/bash

jobname="job_201312161447_0003"
jobname_pre=${jobname:0:16}
jobname_post=${jobname:17}

This bash script gives me Bad substitution error on Ubuntu. Any help will be highly appreciated.

Pisciculture answered 16/12, 2013 at 16:1 Comment(7)
It is working fine to me. What are you trying to accomplish?Meristic
I am trying to divide the jobname into two: job_201312161447 and 0003. Its giving this error only when I am trying to run this on ubuntu.Pisciculture
Mmmm strange. What if you use cut? cut -d_ -f1,2 <<< "$jobname" and cut -d_ -f3 <<< "$jobname" make itMeristic
thanks. but why jobname_pre=${jobname:0:16} gave errorPisciculture
@bludger you are right, I see that if you do sh script.sh it gets a "Bad substitution" error.Meristic
@Meristic cool. Added it as an answer.Retrace
Lots of alternative solutions: http://askubuntu.com/questions/571852/alternatives-for-variable-string-substitution-in-bashLactate
Q
308

The default shell (/bin/sh) under Ubuntu points to dash, not bash.

me@pc:~$ readlink -f $(which sh)
/bin/dash

So if you chmod +x your_script_file.sh and then run it with ./your_script_file.sh, or if you run it with bash your_script_file.sh, it should work fine.

Running it with sh your_script_file.sh will not work because the hashbang line will be ignored and the script will be interpreted by dash, which does not support that string substitution syntax.

Quijano answered 16/12, 2013 at 16:44 Comment(5)
@DanFromGermany because that's the only reason for that error, i.e. he's running the script in a way that doesn't consider the hashbang, and that bash syntax is not supported by some other shell (probably dash). Questions don't always contain all the needed details, and we must join the dots... anyway feel free to downvote my answer.Quijano
I dont need to downvote. I have the same error message bad substitution and I'm just trying to gather information but this question doesn't help because it has too few information.Sunset
@DanFromGermany you could try posting your own question, maybe it's not exactly the same problem.Quijano
and I was using zsh :facepalm:Tubercular
Thanks for this! I just got bit by this too. Just what we needed: another shell program with subtle quirks that make it fit on a 5.25 inch disk.Danikadanila
B
122

I had the same problem. Make sure your script didnt have

#!/bin/sh 

at the top of your script. Instead, you should add

#!/bin/bash
Bigoted answered 24/4, 2014 at 19:2 Comment(6)
I used #!bin/bash and sh script.sh, it still gave me the error message. Then ./script.sh works.Revivalism
If your file is missing a shebang at the top adding #!/bin/bash will also fix the Bad substitution.Chiu
@Revivalism your variable could be having a dot (.) in its name. It gives bad subst. error.Apropos
@Revivalism the #! line is used only when you execute your script directly. If you use sh script.sh the line is completely ignored.Meetly
yes, got same issue on Ubuntu because it default using dash to run script.Grubbs
This is the correct answer for me, I had a #!/bin/sh at the top of my script (erroneously), under centos doing ./myscript.sh it ignored the shebang, ran it under bash, and it worked. In Ubuntu it ran it (correctly) in /bin/sh and failed.Lastex
C
106

For others that arrive here, this exact message will also appear when using the env variable syntax for commands, for example ${which sh} instead of the correct $(which sh)

Coulter answered 17/8, 2016 at 9:33 Comment(2)
The difference is curly brace { vs normal bracket ( (took me a little time to figure out what you were showing)Dichloride
This was my issue with a similar problem. Was reviewing different bash script examples from StackExchange and copy/paste resulted in this disconnect. Curly braces needed to be substituted and it all worked!Bushed
M
26

Your script syntax is valid bash and good.

Possible causes for the failure:

  1. Your bash is not really bash but ksh or some other shell which doesn't understand bash's parameter substitution. Because your script looks fine and works with bash. Do ls -l /bin/bash and check it's really bash and not sym-linked to some other shell.

  2. If you do have bash on your system, then you may be executing your script the wrong way like: ksh script.sh or sh script.sh (and your default shell is not bash). Since you have proper shebang, if you have bash ./script.sh or bash ./script.sh should be fine.

Maund answered 16/12, 2013 at 16:35 Comment(2)
I'd be surprised if /bin/bash (not /bin/sh) were ever linked to a different shell.Bodleian
ksh is actually where most of bash's syntax extensions originated from; it certainly has the specific parameter expansion syntax in question. I wouldn't tend to suggest calling it out as a shell unlikely to be capable.Endosmosis
R
11

Try running the script explicitly using bash command rather than just executing it as executable.

Retrace answered 16/12, 2013 at 16:18 Comment(1)
Good one. It would be helpful to add some sample output to make it more clear, by using sh script and bash script... my suggestion :)Meristic
J
8

Also, make sure you don't have an empty string for the first line of your script.

i.e. make sure #!/bin/bash is the very first line of your script.

Joshuajoshuah answered 5/4, 2016 at 18:23 Comment(0)
F
7

Not relevant to your example, but you can also get the Bad substitution error in Bash for any substitution syntax that Bash does not recognize. This could be:

  • Stray whitespace. E.g. bash -c '${x }'
  • A typo. E.g. bash -c '${x;-}'
  • A feature that was added in a later Bash version. E.g. bash -c '${x@Q}' before Bash 4.4.

If you have multiple substitutions in the same expression, Bash may not be very helpful in pinpointing the problematic expression. E.g.:

$ bash -c '"${x } multiline string
$y"'
bash: line 1: ${x } multiline string
$y: bad substitution
Fruition answered 6/4, 2020 at 15:47 Comment(3)
This is the first hit for Bad substitution so I thought I'd include the case that we ran into. (It was @Q in Bash 4.3 hiding in a long multi-line expression.)Fruition
This was my issue when running Bash 3.x on macOrdure
Prooflink regarding @Q being added in bash-4.4.Bedim
B
3

I was adding a dollar sign twice in an expression with curly braces in bash:

cp -r $PROJECT_NAME ${$PROJECT_NAME}2

instead of

cp -r $PROJECT_NAME ${PROJECT_NAME}2
Bugs answered 11/5, 2020 at 12:26 Comment(0)
H
2

Both - bash or dash - work, but the syntax needs to be:

FILENAME=/my/complex/path/name.ext
NEWNAME=${FILENAME%ext}new
Hamil answered 10/3, 2016 at 10:3 Comment(1)
That's a completely different operation. Also, since the OP was following good practices by using lower-case variable names (see pubs.opengroup.org/onlinepubs/9699919799/basedefs/… -- uppercase names are used for variables with meaning to the OS or shell; lowercase names are reserved for application use), it behooves to do likewise.Endosmosis
C
0

I have found that this issue is either caused by the marked answer or you have a line or space before the bash declaration

Chantilly answered 28/2, 2020 at 14:30 Comment(0)
L
0

Looks like "+x" causes problems:

root@raspi1:~# cat > /tmp/btest
#!/bin/bash

jobname="job_201312161447_0003"
jobname_pre=${jobname:0:16}
jobname_post=${jobname:17}
root@raspi1:~# chmod +x /tmp/btest
root@raspi1:~# /tmp/btest
root@raspi1:~# sh -x /tmp/btest
+ jobname=job_201312161447_0003
/tmp/btest: 4: /tmp/btest: Bad substitution
Lengthen answered 10/3, 2020 at 2:40 Comment(0)
S
0

in my case (under ubuntu 18.04), I have mixed $( ${} ) that works fine:

BACKUPED_NB=$(ls ${HOST_BACKUP_DIR}*${CONTAINER_NAME}.backup.sql.gz | wc --lines)

full example here.

Swami answered 24/11, 2020 at 17:37 Comment(0)
R
0

I used #!bin/bash as well tried all approaches like no line before or after #!bin/bash.
Then also tried using +x but still didn't work. Finally i tried running the script ./script.sh it worked fine.

#!/bin/bash
jobname="job_201312161447_0003"
jobname_post=${jobname:17}

root@ip-10-2-250-36:/home/bitnami/python-module/workflow_scripts# sh jaru.sh
jaru.sh: 3: jaru.sh: Bad substitution

root@ip-10-2-250-36:/home/bitnami/python-module/workflow_scripts# ./jaru.sh
root@ip-10-2-250-36:/home/bitnami/python-module/workflow_scripts#

Rikki answered 26/2, 2022 at 4:19 Comment(0)
H
0

In my case I eventually found I had a missing } for one of the environmental variables. ${model.a should have been ${model}.a

The takeaway is that it may be a typo.

I am editing in vi on SCO 5.0.5 so please don't bash me for missing a syntax error.

Horatio answered 17/5, 2023 at 15:57 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.