bash:换人错误


148
#!/bin/bash

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

这个bash脚本给我在Ubuntu上的错误替换错误。任何帮助将不胜感激。


对我来说很好。你想达到什么目的?
fedorqui'SO停止伤害

我正在尝试将作业名称分为两个:job_201312161447和0003。仅当我尝试在ubuntu上运行它时,才会给出此错误。
阿林丹·乔杜里

嗯,奇怪。如果使用该cut怎么办?cut -d_ -f1,2 <<< "$jobname"cut -d_ -f3 <<< "$jobname"使其
fedorqui“所以停止损害”

谢谢。但是为什么jobname_pre = $ {jobname:0:16}给出了错误
Arindam Choudhury

1
@bludger,您是对的,我看到,如果执行sh script.sh此操作,则会出现“错误替换”错误。
fedorqui'SO stop harm'13

Answers:


200

/bin/shUbuntu下的默认shell()指向dash,而不是bash

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

因此,如果您使用来chmod +x your_script_file.sh运行它./your_script_file.sh,或者您使用来运行它bash your_script_file.sh,它应该可以正常工作。

使用它运行sh your_script_file.sh将不起作用,因为hashbang行将被忽略,脚本将由解释dash,该脚本不支持该字符串替换语法。


2
他正在使用,/bin/bash所以您的答案不合适吗?您在哪里看到他在使用/bin/shsh script.sh
Daniel W.

4
@DanFromGermany,因为这是导致该错误的唯一原因,即他以不考虑hashbang的方式运行脚本,并且其他某些shell不支持bash语法(可能是破折号)。问题并不总是包含所有需要的细节,我们必须紧密联系……无论如何都可以低估我的答案。
万尼Totaro

2
我不需要投票。我有相同的错误消息bad substitution,我只是想收集信息,但是这个问题没有帮助,因为它的信息太少了。
Daniel W.

2
@DanFromGermany您可以尝试发布您自己的问题,也许不是完全相同的问题。
Vanni Totaro

69

我有同样的问题。确保您的脚本没有

#!/bin/sh 

在脚本的顶部。相反,您应该添加

#!/bin/bash

5
我使用#!bin/bashsh script.sh,它仍然给我错误消息。然后./script.sh工作。
whyisyoung 2015年

如果您的文件缺少顶部的shebang,则添加#!/bin/bash也将修复Bad替换
杰米

1
@whyisyoung您的变量名称中可能带有点(。)。它提供了不好的替代品。错误。
user13107'9

4
@whyisyoung #!仅在直接执行脚本时使用该行。如果使用sh script.sh该行将被完全忽略。
bfontaine


21

您的脚本语法是有效的bash并且很好。

失败的可能原因:

  1. bash不是真正的bash,而是ksh其他不了解bash参数替换的shell。因为您的脚本看起来不错,并且可以与bash一起使用。这样做ls -l /bin/bash,并检查它是真正的bash,而不是符号链接到一些其他的壳。

  2. 如果您的系统上确实有bash,则您可能会以错误的方式执行脚本,例如:ksh script.shsh script.sh(并且您的默认shell不是bash)。既然你有适当的射手,如果你有打击./script.shbash ./script.sh应该没事。


7
如果/bin/bash(not /bin/sh)曾经链接到另一个shell,我会感到惊讶。
chepner

实际上,bash的大多数语法扩展都来自ksh;当然,它具有特定的参数扩展语法。我不会倾向于建议将其称为不可能的外壳。
查尔斯·达菲

7

尝试使用bash命令显式运行脚本,而不是仅将其作为可执行文件执行。


3
好一个 这将有助于增加一些样本输出来使它看起来更清晰,使用sh scriptbash script...我的建议:)
fedorqui“所以停止损害”

4

另外,请确保脚本的第一行没有空字符串。

即确保#!/bin/bash是脚本的第一行。


3

与您的示例无关,但是Bad substitution对于Bash无法识别的任何替换语法,您也可以在Bash中得到错误。可能是:

  • 流浪空格。例如bash -c '${x }'
  • 错字了。例如bash -c '${x;-}'
  • 在更高的Bash版本中添加的功能。例如bash -c '${x@Q}'在Bash 4.4之前。

如果您在同一个表达式中有多个替换项,则Bash可能对查明有问题的表达式不是很有帮助。例如:

$ bash -c '"${x } multiline string
$y"'
bash: line 1: ${x } multiline string
$y: bad substitution

2
这是第一击,Bad substitution因此我认为我应该包括我们遇到的情况。(它@Q在Bash 4.3中隐藏在长的多行表达式中。)
Daniel Darabos

2
这是我在Mac上运行Bash 3.x时的问题
coloradocolby

2
关于@Q在中添加的Prooflinkbash-4.4
x-yuri

2

bash或破折号都可以使用,但是语法必须为:

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

1
这是完全不同的操作。另外,由于OP遵循使用小写变量名的良好做法(请参阅pubs.opengroup.org/onlinepubs/9699919799/basedefs/…)-大写名称用于对OS或shell有意义的变量;小写名称是保留供应用程序使用),它也应该这样做。
Charles Duffy

0

看起来像“ + x”会引起问题:

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

0

我在bash中带有花括号的表达式中两次添加了美元符号:

cp -r $PROJECT_NAME ${$PROJECT_NAME}2

代替

cp -r $PROJECT_NAME ${PROJECT_NAME}2

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.