ubuntu函数,在获取源代码时有效,但不能与bash命令一起使用

时间:2018-10-06 15:27:11

标签: bash

我正在尝试学习如何在Ubuntu中编写一些基本功能,但我发现其中一些功能可以工作,而有些则不能,我不知道为什么。

具体来说,以下函数addseq2.sh在我获取源代码时将起作用,但是当我尝试使用bash addseq2.sh运行它时将不起作用。当我用$?进行检查时,会得到0: command not found。有谁知道为什么会这样?感谢您的任何建议!

这是addseq2.sh的代码:

#!/usr/bin/env bash
# File: addseq2.sh

function addseq2 {
  local sum=0

  for element in $@
  do
    let sum=sum+$element
  done

  echo $sum
}

感谢大家提供所有有用的建议和帮助!

为了扩展我的原始问题,我已经编写了两个简单的函数。第一个hello.sh如下所示:

#!/usr/bin/env bash
# File: hello.sh

function hello {
  echo "Hello"
}

hello
hello
hello

当我调用此函数时,没有做任何其他事情,我将键入:

$ bash hello.sh

似乎工作正常。在使用$ source hello.sh进行搜索后,我便可以键入hello,它也可以按预期运行。

让我抓狂的是我在这里提到的第一个功能addseq2.sh。如果我尝试重复相同的步骤,请仅使用$ bash addseq2.sh 1 2 3进行调用。我没看到任何结果。按照您对$ echo $?的建议检查后,我可以看到我得到了0并正确执行,但屏幕上没有任何内容。

在使用$ source addseq2.sh进行获取后,只需键入$ addseq2 1 2 3即可调用它,并按预期返回6

我不明白为什么两个函数的行为方式不同。

2 个答案:

答案 0 :(得分:0)

当我检查$时?我得到一个0:找不到命令

这是因为您进行检查的方式,例如: (前导$是显示命令行提示符的约定)

$ $?
-bash: 0: command not found

相反,您可以这样做:

$ echo $?
0

按照惯例0表示成功。在脚本中进行测试的更好方法是:

if addseq.sh
then
    echo 'script worked'
else
    # Redirect error message to stderr
    echo 'script failed' >&2   
fi

现在,即使脚本返回了0,为什么您的脚本仍无法“工作”?您有一个函数,但没有调用它。使用您的代码,我追加了一个呼叫:

#!/usr/bin/env bash
# File: addseq2.sh

function addseq2 {
  local sum=0

  for element in $@
  do
    let sum=sum+$element
  done

  echo $sum
}

addseq2 1 2 3 4          # <<<<<<<

然后我得到了

10

顺便说一句:

let sum=sum+$element

是:

sum=$((sum + element))

答案 1 :(得分:0)

当您执行bash foo.sh时,它会产生一个bash的新实例,然后该实例读取并执行foo.sh中的每个命令。


对于hello.sh,命令为:

function hello {
  echo "Hello"
}

此命令没有可见效果,但是它定义了一个名为hello的函数。

hello
hello
hello

这些命令调用hello函数三次,每次将Hello打印到标准输出。

到达脚本末尾时,bash退出,状态为0。hello函数消失了(它仅在刚刚停止运行的bash进程中定义)。


对于addseq2.sh,命令为:

function addseq2 {
  local sum=0

  for element in $@
  do
    let sum=sum+$element
  done

  echo $sum
}

此命令没有可见效果,但是它定义了一个名为addseq2的函数。

到达脚本末尾时,bash退出,状态为0。addseq2函数消失了(它仅在刚刚停止运行的bash进程中定义)。

这就是bash addseq2.sh不执行任何操作的原因:它只是定义(并且立即忘记了)一个函数而没有调用它。


source命令是不同的。它告诉当前正在运行的外壳程序从文件执行命令,就像在命令行上键入命令一样。这些命令本身仍然像以前一样执行,但是现在这些功能得以保留,因为它们在其中定义的bash进程仍然有效。

如果您想让bash addseq2.sh 1 2 3自动调用addseq2函数并将其传递给命令行参数列表,则必须这样明确地说:Add

addseq2 "$@"

addseq2.sh的结尾。