一个函数定义为:
do_something () {
do it
}
Run Code Online (Sandbox Code Playgroud)
我可以理解它的名称“do_something”和大括号来封装操作代码,但我无法理解()这里的目的是什么,因为 Bash 脚本中没有命名参数。将其定义为可能更好更直接
do_something {
do it
}
Run Code Online (Sandbox Code Playgroud)
这与它当前的语法没有冲突,甚至更多地声明没有命名参数。什么是的用法()吗?
Eli*_*gan 47
(),语法真的会很模糊。定义一个函数必须有一些明确的语法,并且在不实质性改变其他shell 语法的情况下,它不可能是这样的:
do_something {
# one or more commands go here
}
Run Code Online (Sandbox Code Playgroud)
您说这“与其当前的语法不冲突”,但确实如此!请注意,当您尝试运行该文件的第一行时,不会出现任何类型的语法错误。你得到一个错误,但这不是关于语法的错误。带有 的第二行}是语法错误,但第一行不是。相反,do_something {尝试运行一个名为的命令do_something并将其{作为参数传递给该命令:
$ do_something {
do_something: command not found
Run Code Online (Sandbox Code Playgroud)
如果已经有一个名为 的命令do_something,则您正在运行它。如果已经有一个被调用的函数do_something,你就是在调用它。一般来说,语法明确很重要,但特别重要的是可以重新定义函数而不会意外调用它。定义一个函数和调用它不应该看起来一样。
{和(.正如type {你会告诉你的,{是一个shell关键字。这使它像[[. 如果在它本来是命令的情况下使用,则{带有特殊语义。具体来说,它执行命令分组。然而,在其他情况下,它可能被用于未转义的字面{字符。这包括将其作为命令的第二个或后续单词传递的情况。
当然,Bash本来可以被设计成{与目前不同的处理方式。然而,它的语法将不再与 POSIX shell 兼容,并且 Bash 不会真正成为 Bourne 风格的 shell,并且不能运行许多 shell 脚本。
相反,(是一个shell元字符。如果它出现在命令中并且没有被引用(用、 或)' ',它总是被特殊对待。因此,语法中没有歧义:" "\
do_something() {
# one or more commands go here
}
Run Code Online (Sandbox Code Playgroud)
那不可能是别的意思。如果 Bash 没有函数,那么它将是一个语法错误,因为同样的原因echo foo(bar)是一个语法错误。
如果你真的不喜欢这个()符号,那么你可以使用关键字function并省略它,正如sudodus 提到的那样。请注意,这不是在大多数其他 Bourne 风格的 shell 中定义函数的语法的一部分——在某些情况下,它受到支持,但以这种方式定义的函数具有不同的语义——因此使用它的脚本将不可移植。(这种语法能够明确的原因是它function本身是 Bash 中的一个关键字,表示它后面的任何内容都是函数定义的开始。)
最后,请注意,虽然大多数函数定义{在实践中使用,但允许使用任何复合命令。如果你有一个函数,你希望它的主体总是在子 shell 中运行,你可以使用( )而不是{ }.
sud*_*dus 15
该()令牌是告诉shell解释你是声明功能。
$ do_something () { echo 'do it'; } ; do_something
do it
Run Code Online (Sandbox Code Playgroud)
一个替代方案bash是function
function do_something {
echo 'do it'
}
Run Code Online (Sandbox Code Playgroud)
或者作为单线你可以测试
$ bash -c "function do_something { echo 'do it'; } ; do_something"
do it
Run Code Online (Sandbox Code Playgroud)
你真是一个真正的大括号风格的人!
考虑其他完美的大括号样式:
foo
{
...
}
foo
{
...
}
foo
while ...; do ...; done # Look, ma! No braces!
foo
( ... ) # Look, ma! No braces and a subshell to boot!
Run Code Online (Sandbox Code Playgroud)
shell 如何判断这些是函数定义而不是简单的命令foo后跟命令列表?在所有这些情况下,都需要一个额外的消歧因素,例如 like()或function关键字。
| 归档时间: |
|
| 查看次数: |
8412 次 |
| 最近记录: |