ChatGPT解决这个技术问题 Extra ChatGPT

在 Bash 变量赋值中找不到命令错误

我有这个名为 test.sh 的脚本:

#!/bin/bash
STR = "Hello World"
echo $STR

当我运行 sh test.sh 我得到这个:

test.sh: line 2: STR: command not found

我究竟做错了什么?我在网上查看了非常基本的/初学者 bash 脚本教程,这就是他们所说的声明变量的方式......所以我不确定我做错了什么。

我在 Ubuntu Server 9.10 上。是的,bash 位于 /bin/bash

我很高兴你确实提出了这个问题,你不是那里唯一的 bash 菜鸟!
谢谢你问这个问题。这不是一个尴尬的问题。我在办公室工作到深夜,我周围没有 Bash 专家来回答这个问题。
这些天(差不多七年后!)有一个名为 shellcheck 的 FOSS linter/analyzer 将自动检测这个和其他常见的语法问题。它可以在线使用或离线安装并集成到您的编辑器中。
我建议您使用:#!/usr/bin/env bash 而不是直接放入 #!/bin/bash,除非您绝对确定您的 bash/bin 中,因为这个答案:stackoverflow.com/a/21613044/3589567

W
William Pursell

= 符号周围不能有空格。

当你写:

STR = "foo"

bash 尝试使用 2 个参数(字符串 =foo)运行名为 STR 的命令

当你写:

STR =foo

bash 尝试使用 1 个参数(字符串 =foo)运行名为 STR 的命令

当你写:

STR= foo

bash 尝试在其环境中将 STR 设置为空字符串来运行命令 foo

我不确定这是否有助于澄清或仅仅是混淆,但请注意:

第一个命令完全等同于:STR "=""foo",第二个等同于 STR"=foo",最后一个等同于 STR="" foo。

sh language spec, section 2.9.1 的相关部分指出:

“简单命令”是一系列可选的变量分配和重定向,以任何顺序,可选地后跟单词和重定向,由控制运算符终止。

在这种情况下,word 是 bash 将要运行的命令。任何包含 = 的字符串(在字符串开头以外的任何位置)不是重定向并且其中 = 之前的字符串部分是有效的变量名是变量赋值,而任何字符串那不是重定向或变量赋值是命令。在 STR = "foo" 中,STR 不是变量赋值。


如果您有一个名称包含“-”的变量,则会发生相同的错误。在这种情况下,解决方案是删除“-”
chomp@ 在 pubs.opengroup.org/onlinepubs/9699919799 的第 2.10.10 节的规则 7b 中“如果 '=' 之前的所有字符构成一个有效名称(请参阅 XBD 名称),则应返回令牌 ASSIGNMENT_WORD。”在 pubs.opengroup.org/onlinepubs/9699919799 的第 3.231 节的链接之后,我们发现“在 shell 命令语言中,一个仅由可移植字符集中的下划线、数字和字母组成的单词。名称的第一个字符不是数字。”。因此单词 FOO-BAR=qux 不是变量赋值,因为 FOO-BAR 不是有效名称。
我提供赏金来奖励对初学者始终常见的问题的清晰解释(好吧,并且在我想链接它时能够更快地找到它:D)。感谢您让事情变得如此简单!
@fedorqui 谢谢!我并不完全相信这是一个明确的解释,我经常想知道它是否可以变得更简单。
@Timo $st=$i 不是变量赋值。它扩展为一个字符串,并且该字符串作为命令执行。您似乎正在尝试执行 eval $st=$i。不要那样做。
J
Joey

删除 = 符号周围的空格:

#!/bin/bash 
STR="Hello World" 
echo $STR 

不过,这很有趣,因为 set foo = bar 在 Windows 批处理文件中也是一个常见错误——批处理语言因此而受到嘲笑;-)
谢谢@乔伊。我一直在编写一个 shell 脚本,我在“=”之后用空格初始化变量。你拯救了我的一天
为什么 bash 不接受左侧字段中的数字?像 3="Hello World",它抱怨找不到命令
B
Benjamin W.

在交互模式下,一切看起来都很好:

$ str="Hello World"
$ echo $str
Hello World

显然(!)正如 Johannes 所说,= 周围没有空格。如果 = 周围有任何空格,则在交互模式下它会给出错误

找不到命令“str”


但请注意 OP 说的是 STR = "Hello World",因此此答案不适用于此处。
@Arkapravo 交互模式是什么意思,是否与$标记有关
@KasunSiyambalapitiya 所说的“交互模式”是指在实际终端中输入这些命令,而不是在脚本中。
D
Derek Haber

我知道这已经得到了一个非常高质量的答案。但是,简而言之,你不能有空格。

#!/bin/bash
STR = "Hello World"
echo $STR

由于等号周围有空格,因此无法正常工作。如果你要跑...

#!/bin/bash
STR="Hello World"
echo $STR

它会工作


K
Knowledge Cube

当您定义任何变量时,您不必添加任何额外的空格。

例如

name = "Stack Overflow"  
// it is not valid, you will get an error saying- "Command not found"

所以删除空格:

name="Stack Overflow" 

它会正常工作。