Bash脚本错误:“功能:未找到”。为什么会出现?


73

我正在尝试bash script在我的Ubuntu计算机上运行,这给了我一个错误:

找不到功能

为了进行测试,我创建了以下脚本,该脚本可以在笔记本电脑上正常运行,但不能在台式机上正常运行。有什么想法吗?如果相关的话,我的笔记本电脑是Mac。

#!/bin/bash

function sayIt {   
   echo "hello world"
}

sayIt

这将在我的笔记本电脑上返回“ hello world”,但在我的台式机上将返回:

run.sh:3:找不到函数hello world run.sh:5:语法错误:“}”意外


知道您如何调用脚本会很有趣。
Timo

Answers:


136

可能是在桌面上您实际上不是在下面运行,bash而是在dash其他不能识别该function关键字的POSIX兼容外壳下运行。该function关键字是bashism,一个bash扩展。POSIX语法不使用function并且强制使用括号。

$ more a.sh
#!/bin/sh

function sayIt {   
   echo "hello world"
}

sayIt
$ bash a.sh
hello world
$ dash a.sh
a.sh: 3: function: not found
hello world
a.sh: 5: Syntax error: "}" unexpected

POSIX语法在以下两种情况下均可使用:

$ more b.sh
#!/bin/sh

sayIt () {   
   echo "hello world"
}

sayIt
$ bash b.sh
hello world
$ dash b.sh
hello world

2
function来自korn外壳,它早于bash。
cdarke 2012年

1
+1遇到了这个确切的问题,但是bash仍会按预期执行。至少有了您的解释,我知道原因方式!:)
Zuul 2013年

那么,如何在bash而不是破折号或POSIX兼容的shell下运行脚本?
Alessandro C,

可能的原因是该脚本没有为正在执行的用户设置执行位,这意味着该脚本被作为纯shell脚本读取。确保这是正确的,并且shebang路径实际上会调用Bash。
Toby Speight

对我来说,我正在运行一个sh脚本(例如sh train.sh -d),但是它给了我错误。这个答案帮助我意识到了这个问题(我不得不写/ bin / bash train.sh -d
Octav

19

我遇到了同样的问题,然后我修改了语法并为我工作。尝试删除关键字功能添加在函数名称后方括号()

#!/bin/bash

sayIt()
{   
   echo "hello world"
}

sayIt


-5

在函数名称之后或调用时是否不需要()?

function sayIt() { ...
}

sayIt()

?:)

嗯,实际上,在我的Mac上,它的作用与您粘贴时一样。

dtpwmbp:~ pwadas$ cat aa.sh 
#!/bin/bash

function sayIt() {   
   echo "hello world"
}

sayIt

dtpwmbp:~ pwadas$ ./aa.sh 
hello world
dtpwmbp:~ pwadas$ 

比较bash版本,AFAIR需要一些较旧的版本“()”。

dtpwmbp:~ pwadas$ bash --version
GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin12)
Copyright (C) 2007 Free Software Foundation, Inc.
dtpwmbp:~ pwadas$ 

还比较两个shell上的shopt选项(man bash)的状态,也许其中一个具有打开或关闭一些compat语法的功能?不带参数的“ shopt”命令将列出支持的选项状态。

在某些bash脚本中使用的“功能”关键字是什么?


可悲的是,我真的不知道为什么我对这个问题的回答被
否决了

您应该()在函数定义中包含,但在调用函数时则不应该包含。
Jacob

@PiotrWadas,我没有投票给你,但实际上更多的是问题,而不是答案。
格琳·杰克曼(Glenn Jackman)2013年

是的,您的答案确实是关于上述答案的问题。因此它应该是对该答案的评论,而不是答案本身
johnnyB 2014年

function foo() {实际上无效function foo {function foo {语法在旧版本的ksh和试图保持与它们的兼容性的现代外壳程序上受支持,但与1992 POSIX sh标准兼容的外壳程序要求支持该语法。相反,foo() {在所有符合POSIX的外壳上均有效。function foo() {是这两种格式的混合形式,其支持程度不及任何一种。参见wiki.bash-hackers.org/scripting/obsolete
Charles Duffy
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.