ChatGPT解决这个技术问题 Extra ChatGPT

bash : 错误替换

#!/bin/bash

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

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

它对我来说很好。你想达到什么目的?
我试图将作业名分为两部分:job_201312161447 和 0003。仅当我尝试在 ubuntu 上运行它时才会出现此错误。
嗯很奇怪。如果使用 cut 会怎样? cut -d_ -f1,2 <<< "$jobname"cut -d_ -f3 <<< "$jobname" 成功了
谢谢。但为什么 jobname_pre=${jobname:0:16} 给出错误
@bludger 你是对的,我看到如果你这样做 sh script.sh 它会得到一个“错误替换”错误。

V
Vanni Totaro

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


他正在使用/bin/bash,所以你的答案不适合?!你在哪里读到他在使用 /bin/shsh script.sh
@DanFromGermany,因为这是该错误的唯一原因,即他以不考虑 hashbang 的方式运行脚本,并且其他一些 shell(可能是破折号)不支持 bash 语法。问题并不总是包含所有需要的细节,我们必须加入这些点......无论如何,请随时对我的答案投反对票。
我不需要投票。我有同样的错误消息 bad substitution,我只是想收集信息,但这个问题没有帮助,因为它的信息太少。
@DanFromGermany您可以尝试发布自己的问题,也许这不是完全相同的问题。
我正在使用 zsh :facepalm:
Z
ZeMoon

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

#!/bin/sh 

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

#!/bin/bash

我使用了 #!bin/bashsh script.sh,它仍然给了我错误信息。然后 ./script.sh 起作用。
如果您的文件在顶部缺少 shebang,则添加 #!/bin/bash 也将修复 错误替换
@whyisyoung 您的变量名称中可能有一个点 (.)。它给出了不好的替代品。错误。
@whyisyoung #! 行仅在您直接执行脚本时使用。如果您使用 sh script.sh,则该行将被完全忽略。
是的,在 Ubuntu 上遇到了同样的问题,因为它默认使用破折号来运行脚本。
N
Nacho Coloma

对于到达此处的其他人,在使用 env 变量语法的命令时也会出现此确切消息,例如 ${which sh} 而不是正确的 $(which sh)


区别在于花括号 { 与普通括号 ( (花了我一点时间来弄清楚你展示的是什么)
P
P.P

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

失败的可能原因:

您的 bash 并不是真正的 bash,而是 ksh 或其他不了解 bash 参数替换的 shell。因为您的脚本看起来不错并且可以与 bash 一起使用。执行 ls -l /bin/bash 并检查它是否真的是 bash 而不是符号链接到其他 shell。如果您的系统上确实有 bash,那么您可能以错误的方式执行脚本,例如:ksh script.sh 或 sh script.sh(并且您的默认 shell 不是 bash)。既然你有适当的 shebang,如果你有 bash ./script.sh 或 bash ./script.sh 应该没问题。


如果 /bin/bash(不是 /bin/sh)曾经链接到不同的 shell,我会感到惊讶。
ksh 实际上是大多数 bash 语法扩展的起源;它当然有特定的参数扩展语法。我不会倾向于建议将其称为不太可能有能力的外壳。
R
Ravindra S

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


好一个。通过使用 sh scriptbash script 添加一些示例输出以使其更清晰会很有帮助...我的建议 :)
R
RavinderSingh13

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

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


D
Daniel Darabos

与您的示例无关,但对于 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

这是 Bad substitution 的第一次点击,所以我想我会包括我们遇到的案例。 (它是 Bash 4.3 中的 @Q 隐藏在一个长的多行表达式中。)
这是我在 mac 上运行 Bash 3.x 时遇到的问题
Prooflink 关于在 bash-4.4 中添加的 @Q
H
Hagen

两者 - bash 或破折号 - 工作,但语法需要:

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

那是完全不同的操作。此外,由于 OP 通过使用小写变量名称来遵循良好做法(请参阅 pubs.opengroup.org/onlinepubs/9699919799/basedefs/…——大写名称用于对 OS 或 shell 有意义的变量;小写名称保留给应用程序使用),因此应该这样做同样地。
s
sashoalm

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

cp -r $PROJECT_NAME ${$PROJECT_NAME}2

代替

cp -r $PROJECT_NAME ${PROJECT_NAME}2

A
Ahmed Oladele

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


A
Andrew Knutsen

看起来像“+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

N
Neuron

就我而言(在 ubuntu 18.04 下),我混合了 $( ${} ),效果很好:

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

完整示例 here


p
prashant thakre

我使用 #!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 #