为什么 bash 会给出“错误替换”错误?

问题描述 投票:0回答:14
#!/bin/bash

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

这个 bash 脚本给了我一个

bad substitution
错误。

string bash substitution
14个回答
307
投票

Ubuntu 下的默认 shell (

/bin/sh
) 指向
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
解释,它不支持该字符串替换语法。


121
投票

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

#!/bin/sh 

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

#!/bin/bash

104
投票

对于到达此处的其他人,在使用命令的 env 变量语法时也会出现此确切消息,例如

${which sh}
而不是正确的
$(which sh)


26
投票

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

可能失败的原因:

  1. 您的

    bash
    并不是真正的 bash,而是
    ksh
    或其他不理解 bash 参数替换的 shell。因为您的脚本看起来不错并且可以与 bash 一起使用。 执行
    ls -l /bin/bash
    并检查它确实是 bash 并且没有符号链接到其他 shell。

  2. 如果您的系统上确实有 bash,那么您可能会以错误的方式执行脚本,例如:

    ksh script.sh
    sh script.sh
    (并且您的默认 shell 不是 bash)。既然你有合适的 shebang,如果你有 bash
    ./script.sh
    bash ./script.sh
    应该没问题。


11
投票

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


8
投票

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

即确保

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


7
投票

与您的示例无关,但对于 Bash 无法识别的任何替换语法,您也可能会在 Bash 中收到

Bad substitution
错误。这可能是:

  • 杂散空白。例如。
    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

3
投票

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

cp -r $PROJECT_NAME ${$PROJECT_NAME}2

而不是

cp -r $PROJECT_NAME ${PROJECT_NAME}2

2
投票

两者 - bash 或 dash - 都可以,但语法必须是:

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

0
投票

我发现这个问题要么是由标记的答案引起的,要么是你在 bash 声明之前有一行或空格


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
投票

就我而言(在ubuntu 18.04下),我混合了

$( ${} )
,效果很好:

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

完整示例此处


0
投票

我使用了

#!bin/bash
也尝试了所有方法,例如前后没有线条
#!bin/bash.

然后也尝试使用+x但仍然不起作用。 最后我尝试运行脚本
./script.sh
它工作得很好。

#!/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:错误替换

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#


0
投票

就我而言,我最终发现其中一个环境变量缺少 } 。

${model.a
应该是
${model}.a

要点是这可能是一个错字。

我正在 SCO 5.0.5 上的 vi 中编辑,所以请不要因为缺少语法错误而批评我。

© www.soinside.com 2019 - 2024. All rights reserved.