ChatGPT解决这个技术问题 Extra ChatGPT

bash : Bad Substitution

#!/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.

It is working fine to me. What are you trying to accomplish?
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.
Mmmm strange. What if you use cut? cut -d_ -f1,2 <<< "$jobname" and cut -d_ -f3 <<< "$jobname" make it
thanks. but why jobname_pre=${jobname:0:16} gave error
@bludger you are right, I see that if you do sh script.sh it gets a "Bad substitution" error.

V
Vanni Totaro

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.


He is using /bin/bash so your answer does not fit?! Where do you read he's using /bin/sh or sh script.sh ?
@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.
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.
@DanFromGermany you could try posting your own question, maybe it's not exactly the same problem.
and I was using zsh :facepalm:
Z
ZeMoon

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

I used #!bin/bash and sh script.sh, it still gave me the error message. Then ./script.sh works.
If your file is missing a shebang at the top adding #!/bin/bash will also fix the Bad substitution.
@whyisyoung your variable could be having a dot (.) in its name. It gives bad subst. error.
@whyisyoung the #! line is used only when you execute your script directly. If you use sh script.sh the line is completely ignored.
yes, got same issue on Ubuntu because it default using dash to run script.
N
Nacho Coloma

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)


The difference is curly brace { vs normal bracket ( (took me a little time to figure out what you were showing)
P
P.P

Your script syntax is valid bash and good.

Possible causes for the failure:

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. 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.


I'd be surprised if /bin/bash (not /bin/sh) were ever linked to a different shell.
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.
R
Ravindra S

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


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 :)
R
RavinderSingh13

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.


D
Daniel Darabos

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

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.)
This was my issue when running Bash 3.x on mac
Prooflink regarding @Q being added in bash-4.4.
H
Hagen

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

FILENAME=/my/complex/path/name.ext
NEWNAME=${FILENAME%ext}new

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.
s
sashoalm

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

A
Ahmed Oladele

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


A
Andrew Knutsen

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

N
Neuron

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.


p
prashant thakre

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#