【问题标题】:returning values in a bash function在 bash 函数中返回值
【发布时间】:2023-03-16 14:55:02
【问题描述】:

我正在使用一个不断增长的 bash 脚本,在这个脚本中我有许多功能。其中一个函数应该返回一个变量值,但我遇到了一些语法问题。下面是代码示例。

ShowTags() {
    local tag=0
    read tag
    echo "$tag"
}

selected_tag=$(ShowTags)
echo "$selected_tag"

从 Linux Journal 文章中提取了这段代码,但问题是它似乎不起作用,或者它可能起作用并且我错过了一些东西。本质上,每当调用该函数时,脚本都会挂起并且不输出任何内容,我需要 CTRL+C 回退到 CLI。

有问题的文章如下。

http://www.linuxjournal.com/content/return-values-bash-functions

所以我的问题是这是返回值的正确方法吗?有没有更好或更可靠的方法来做到这一点?如果有请给我一个例子,这样我就可以在不使用全局变量的情况下解决这个问题。

编辑:

这种行为现在真的让我感动。我正在使用以下脚本。

ShowTags() {  

     echo "hi"
     local tag=0
     read tag
     echo "$tag"
}            

selected_tag=$(ShowTags)
echo "$selected_tag

基本上发生的情况是 bash 会表现得好像读取命令发生在函数顶部的 echo 标记之前。只要我通过一些要阅读的内容,它就会运行顶部回显,并完成脚本的其余部分。我不确定为什么会这样。这正是我的主脚本中发生的事情。

【问题讨论】:

  • 为什么要编辑问题中的代码?现在它和答案中的完全一样,所以答案没有意义。你写问题的时候是不是抄袭错误?
  • 我编辑了代码以反映它在我的脚本中出现的样子。问题不在于语法。当我尝试通过命令替换调用函数时,脚本只是挂断了。
  • read tag 命令正在等待您输入内容。
  • 我试过了,对我来说效果很好。输入selected_tag=$(ShowTags) 后,我输入了一些内容。然后echo "$selected_tag" 显示我输入的内容。
  • 我用我整理的快速脚本更新了我的顶级帖子,并更好地解释了 bash 正在做什么。

标签: linux bash


【解决方案1】:

echo "hi" 更改为echo "hi" >/dev/tty

您没有立即看到它的原因是$(ShowTags) 捕获了该函数的所有标准输出,并将其分配给selected_tag。因此,在您回显该变量之前,您什么都看不到。

通过将提示重定向到/dev/tty,它总是立即显示在终端上,而不是发送到函数的stdout,因此它不会被命令替换捕获。

【讨论】:

  • 谢谢!我很高兴我终于弄清楚了手头的问题。你的救命稻草。
【解决方案2】:

您正在尝试使用Name { ... ] 定义一个函数。你必须使用name() { ... }:

ShowTags() {    # add ()
local tag=0
read tag
echo "$tag"
}               # End with }

selected_tag=$(ShowTags)
echo "$selected_tag"

它现在允许用户输入一个字符串并将其写回:

$ bash myscript 
hello world     # <- my input
hello world     # script's output

您可以添加带有read -p "Enter tag: " tag 的提示,以便在编写输入时更加明显。

【讨论】:

  • 我只是将它放入一个新脚本并运行它,该脚本只是挂断而不要求用户输入。我在函数的开头加入了一个回声,看看它是否通过了,它没有出现,因为它没有被显示。这可能与我的 bash 设置方式有关吗?
  • @barefly 函数回显的任何内容都将放入$selected_tag,您不会在屏幕上看到它。
  • @barefly echo 输出将与其他输出一起被$(ShowTags) 捕获。您可以使用 stderr (echo "starting function" &gt;&amp;2) 绕过这个(这几乎就是 stderr 的用途)。
【解决方案3】:

正如@thatotherguy 所指出的,您的函数声明语法已关闭;但我怀疑这是一个转录错误,就好像脚本中的错误一样,你会遇到不同的问题。我认为发生了什么是函数中的read tag 命令正在尝试从标准输入(默认情况下是终端)中读取一个值,并暂停直到您输入某些内容。我不确定它打算做什么,但正如所写的那样,我希望它会无限期地暂停,直到输入某些内容。

解决方案:要么输入一些内容,要么使用 read 以外的其他内容。您还可以添加提示 (read -p "Enter a tag: " tag) 以更清楚地了解发生了什么。

顺便说一句,我对您链接的linux journal article 有一些反对意见。这些与您的脚本无关,但您应该注意的事项。

首先,function 关键字是一个非标准的 bashism,我建议不要使用它。 myfunc() ... 足以引入函数定义。

其次,更严重的是,文章建议以不安全的方式使用eval。实际上,安全地使用eval 真的很难(参见BashFAQ #48)。您可以通过更改引用来大大改进它,甚至完全不使用eval

eval $__resultvar="'$myresult'"    # BAD, can evaluate parts of $myresult as executable code
eval $__resultvar='"$myresult"'    # better, is only vulnerable to executing $__resultvar
declare $__resultvar="$myresult"   # better still

有关更多选项和讨论,请参阅BashFAQ #6

【讨论】:

    猜你喜欢
    • 2013-06-24
    • 1970-01-01
    • 2011-07-22
    • 1970-01-01
    • 2019-09-13
    • 2023-03-30
    • 1970-01-01
    • 2011-09-08
    • 1970-01-01
    相关资源
    最近更新 更多