为啥变量赋值中的空格会在 Bash 中出错? [复制]
Posted
技术标签:
【中文标题】为啥变量赋值中的空格会在 Bash 中出错? [复制]【英文标题】:Why does a space in a variable assignment give an error in Bash? [duplicate]为什么变量赋值中的空格会在 Bash 中出错? [复制] 【发布时间】:2017-06-04 13:06:24 【问题描述】:#!/bin/bash
declare -r NUM1=5
NUM2 =4 # Line 4
num3=$((NUM1 + NUM2))
num4=$((NUM1 - NUM2))
num5=$((NUM1 * NUM2))
num6=$((NUM1 / NUM2)) # Line 9
echo "$num3"
echo $((5**2))
echo $((5%4))
我正在使用这个 bash 脚本,当我运行该脚本时,我得到了错误
./bash_help
./bash_help: line 4: NUM2: command not found
./bash_help: line 9: NUM1 / NUM2: division by 0 (error token is "NUM2")
5
25
1
所以我把代码改成了这个,错误就消失了。
#!/bin/bash
declare -r NUM1=5
NUM2=4
num3=$((NUM1 + NUM2))
num4=$((NUM1 - NUM2))
num5=$((NUM1 * NUM2))
num6=$((NUM1 / NUM2))
echo "$num3"
echo $((5**2))
echo $((5%4))
为什么在给变量赋值时不能使用空格?使用空格来提高代码的可读性是惯例。谁能解释一下?
【问题讨论】:
这只是bash
中的范式之一,你不能质疑它
在 shell 中,空格是重要的分隔符。在大多数情况下,您不能添加或删除它们以使事情看起来更好,因为它们会改变命令行的含义。
谢谢,虽然这是一个小问题。清晰可以减少错误。
清晰性和向后兼容性很少同时存在。 POSIX sh 于 1991 年首次发布,其根源可以追溯到 1970 年代。正如 Common LISP 是由历史 LISP 拼凑而成的丑陋且非常有用的庞然大物,Scheme 又小又漂亮,而且完全缺乏实用的库生态系统,bash 处于这种鸿沟的前者(旧的、丑陋的和有用的)方面。
顺便说一句,shellcheck.net 会自动为您捕获此类错误;非常值得使用(就此而言,可以在本地安装它,并让您的编辑器在您工作时自动运行它)。
【参考方案1】:
这不是 bash(或更一般地说,POSIX 系列 shell)中的约定。
至于“为什么”,那是因为各种做错的方式都具有作为命令的有效含义。如果您将NUM2 = 4
赋值为赋值,那么您不能在不引用它的情况下将=
作为文字参数传递。 因此,任何此类更改都将是向后不兼容的,而不是放置在未定义的空间中(POSIX sh 标准的扩展需要存在以避免违反该标准)。
NUM2= 4 # runs "4" as a command, with the environment variable NUM2 set to an empty string
NUM2 =4 # runs "NUM2" as a command, with "=4" as its argument
NUM2 = 4 # runs "NUM2" as a command, with "=" as its first argument, and "4" as another
【讨论】:
【参考方案2】:在 Bash 中,函数以空格分隔的单词的形式传递参数。
来自文档
“每个运算符和操作数必须是单独的参数。”
变量赋值不同,使用这种语法name=[value]
您不能在等号周围放置不带引号的空格的原因是 bash 会将其解释为命令。
【讨论】:
【参考方案3】:原因很简单,shell 就是这样设计的。对于具有其他编程语言经验的人来说,这可能没有意义(如果您将 shell 语法称为“语言”,在某种意义上它确实如此)。
Shell 脚本在许多情况下可以简单地不引用字符串(只要作为单个字符串的字符序列不包含任何空格或特殊字符)。多亏了这一点,你可以写:
my_command -n -X arg1 arg2
而不是(在某种虚构的伪代码中)
"my_command" "-n" "-X" "arg1" "arg2"
在大多数语言中,情况正好相反:引用文字字符串,从而释放“语法空间”以使用不带任何特殊字符的变量(如 shell 脚本中的 $
)。
Shell 语法在常见情况下提供了便利,但代价是在做一些其他事情时不太方便(和可读性)。这既是诅咒,也是祝福。好消息是如果你有一个交互式 shell,你可以 100% 确定你有一个解释器来处理某种(可能是不优雅的)程序。由于其普遍可用性(尽管存在各种不同的风格),shell 是一种非常有用的平台,值得学习。
【讨论】:
以上是关于为啥变量赋值中的空格会在 Bash 中出错? [复制]的主要内容,如果未能解决你的问题,请参考以下文章