我正在尝试为AWS编写一个自动化流程,该流程需要在bash脚本中进行一些JSON处理和其他操作。我关注了一些bash脚本博客,发现了这一点:
<a class="nav-link text-white" [routerLink]='["/another/link/to/component"]' routerLinkActive="aLink">Component 2</a
,带有以下注释:
等号(=)的两边都没有空格。我们 还可以从变量名称的开头删除$符号,当 设置
这很丑陋,很难读取,并且与其他脚本语言相比也很困难,在编写bash脚本时,用户很容易通过在两者之间留有空格来犯错。我认为每个人都喜欢编写干净且可读的代码,这种限制肯定不利于代码的可读性。
你能解释为什么吗?带有示例的解释受到高度赞赏。
答案 0 :(得分:4)
这是因为否则语法将不明确。考虑以下命令行:
cat = foo
是对变量cat
的赋值,还是使用参数“ =”和“ foo”运行命令cat
?请注意,“ =”和“ foo”都是完全合法的文件名,因此可以在cat
上运行。 Shell语法通过命令解释来解决此问题,因此要避免这种解释,您需要省略空格。 cat =foo
有同样的问题。
另一方面,请考虑:
var= cat
命令cat
是否将变量var
设置为空字符串(即var='' cat
的简写)或对外壳变量var
的赋值运行?同样,shell语法有利于命令解释,因此您需要避免添加空格的诱惑。
shell语法中有很多地方,空格是重要的分隔符。另一个常见的问题是在测试中,如果您在以下位置遗漏了任何:
if [ "$foo" = "$bar" ]
...这将导致不同的含义,这可能会导致错误或只是默默地做错了事。
我要说的是shell语法不允许您随意添加或删除空格以提高可读性。甚至不要尝试,您只会破坏事情。
答案 1 :(得分:4)
您需要了解的是Shell语言和语法很旧。真的很老带有变量的UNIX shell的第一个版本是Bourne shell,它是在1977年设计和实现的。那时,很少有先例。 (AFAIK,只是Thompson shell,根据手册的内容,该词不支持变量。)
1970年代设计决策的基本原理...在时间的迷雾中迷失了。由Steve Bourne及其同事在Bell Labs的v6 UNIX上做出设计决定。他们可能不知道40多年后他们的决定仍然有用。
与使用C语言编写程序的替代方法相比,Bourne shell被设计为通用且易于使用。从这些方面来说,这是一次了不起的成功。
但是,任何一种成功的语言都有被广泛采用的“问题”。这就使解决可能出现的任何问题(实际问题或感知问题)变得更加困难。任何更改语言的建议都必须与该更改对语言的现有用户/使用的影响进行权衡。您不想破坏现有程序或脚本。
不管是否在外壳变量分配中允许在=
周围加空格,更改此设置都会破坏数百万个外壳脚本。只是不会发生。
当然,Linux(及其之前的UNIX)允许您设计和实现自己的shell。从理论上讲,您可以替换默认外壳。这只是很多工作。
没有什么可以阻止您使用其他脚本语言(例如Python,Ruby,Perl等)编写脚本或设计和实现自己的脚本语言。
总结:
我们不能肯定地知道 为什么他们使用这种语法为变量赋值来设计shell,但是无论如何这都是没有意义的。
参考:
答案 2 :(得分:3)
在许多情况下,它可以防止歧义。否则,如果您有一条语句foo = bar
,则可能意味着将foo
和=
作为参数运行bar
程序,或设置foo
变量到bar
。当您不需要空格时,现在您就可以将模糊性限制在程序名称包含等号的情况下,这基本上是闻所未闻的。
答案 3 :(得分:1)
我同意@StephenC,以下是有关消息来源的更多信息:
1975年的Unix v6没有环境,只有一个exec
syscall接受了一个程序和一串参数数组。由汤普森(Thompson)编写的系统sh
不支持only single digit numbered arguments之类的变量,$1
(也许$12
至今被解释为${1}2
的原因)>
自1979年以来,Unix v7受到硬件进步的鼓舞,在exec
调用中增加了许多功能,包括a second string array。 man
page这样描述,直到今天仍然如此:
当进程开始时,exec(2)使称为
environment
的字符串数组可用。按照惯例,这些字符串的格式为name=value
现在由伯恩(Bourne)编写的系统sh
与v6 shell十分相似,但是现在允许您在命令前面以相同格式指定这些环境字符串(因为您将使用哪种其他格式?)。简单化的解析器实质上是将单词分隔成空格,如果包含=
并且所有前面的字符都是字母数字,则flagged a word as destined for a variable会被分隔。
由于Unix v7的不可思议的普及性,fork和clones复制了很多东西,包括这种行为,而这就是我们今天仍然看到的。