当Bash运行你的脚本时,它是将它解析为代码,还是将其解析为命令? Bash是否实际编译,并像Python一样运行你的脚本,或者Bash是否通过其命令解析器运行它?
答案 0 :(得分:10)
Bash是一个单行解释器,这意味着它一次读取一个命令,然后解释并运行它。其他类型的shell也是如此 - sh,ksh,zsh,csh等。
这是一个例子。我有一个名为test.sh
的3行脚本,如下所示:
echo one
echo two
'
以bash test.sh
运行时,它会提供此输出:
one
two
test.sh: line 3: unexpected EOF while looking for matching `''
test.sh: line 4: syntax error: unexpected end of file
它成功运行第一个和第二个命令,然后遇到悬空单引号并抛出错误。
我们假设我们在Perl中编写相同的代码,test.pl
:
print "one\n"
print "two\n"
'
并使用perl test.pl
运行它。我们得到:
syntax error at test.pl line 2, near "print"
Can't find string terminator "'" anywhere before EOF at test.pl line 3.
所以,它并没有运行前两行 ,尽管它们在语法上是正确的。那是因为Perl两次传球。在第一遍中,它执行语法检查并将脚本转换为内部形式。在第二遍中,它运行它。
shell的单次执行的简单性也是它的最大限制。容忍语法错误,甚至根本不运行,使得使用shell语言构建大而强大的代码变得很困难。但是,shell脚本是快速丢弃代码的理想选择,尤其是利用命令行实用程序的代码。
答案 1 :(得分:5)
现在的bash
shell(版本4.4)以纯文本方式运行脚本。它不会将文件预编译为某种形式的字节码。
根据源代码,shell本身只使用reader_loop()
来处理输入。这会在循环内调用read_command()
后跟execute_command()
。
由于read_command()
还包含对调用YACC解析器函数parse_command()
的{{1}}的调用,这意味着解析发生在逐行 >基础,而不是在一些大型编译阶段预先。
答案 2 :(得分:2)
另一种看待$group
一次处理其输入行的方法是在有效bash
语句之后创建一个语法错误的脚本,然后运行剧本。 echo
会在产生语法错误之前产生一些输出:
bash
产生
echo output
()