代码之家  ›  专栏  ›  技术社区  ›  Jordan Mackie

当函数包含其他echo时,从bash函数(<4.3)返回字符串的最安全方法

  •  2
  • Jordan Mackie  · 技术社区  · 7 年前

    我想在函数中打印一些日志样式的消息,但也需要在函数末尾返回一个字符串值。

    我遇到过命名空间,但不幸的是,我没有使用BASH的最新版本。

    例如:

    doThing() {
       echo "stuff"
       echo "things"
       echo "usefulstring"
    }
    
    result=$( doThing )
    
    [[ $result = "usefulstring" ]] && echo "Worked" || echo "Failed. :("
    

    我宁愿避开全局,从我读到的,我应该避免EVAL。 那么还有其他的选择吗?

    另外-我想看到stdout上的日志回声,但不是返回值。可以在函数中使用重定向来实现这一点吗?

    3 回复  |  直到 7 年前
        1
  •  1
  •   Inian    7 年前

    假设您可以使用最少的磁盘I/O,那么您可以打开一个文件描述符来写入文件,然后在函数完成后对其进行解析。

    在本例中,fd 3 为我们的目标服务

    doThing() {
       echo "stuff"
       echo "things"
    
       exec 3<> /tmp/foo
       echo "usefulstring" >&3
       exec 3>&-
    }
    

    现在使用 read 对于单个变量或 mapfile 如果要向数组传递多个单词。这样,即使字符串值之间包含空格,变量也会保存这些值。

    doThing
    read -r str < /tmp/foo
    

    结果将在 str 你可以在条件句中引用它。如果你的文件系统 /tmp /var 很忙,你可以用 mktemp 在本地目录上创建用于fd的文件。

    这也满足了您最后的要求-我想在stdout上看到日志回声,但不想看到返回值。

        2
  •  2
  •   cdarke    7 年前

    可以使用数组并获取最后一个元素:

    doThing() {
       echo "stuff"
       echo "things"
       echo "usefulstring"
    }
    
    # This creates an array
    result=($( doThing ))
    echo ${result[@]}    # Just for debugging
    
    # This get the index of the last element
    end=$(( ${#result[*]} - 1 ))
    result=${result[$end]}
    
    echo $result    # Just for debugging
    
    [[ $result = "usefulstring" ]] && echo "Worked" || echo "Failed. :("
    

    给予:

    stuff things usefulstring
    usefulstring
    Worked
    
        3
  •  1
  •   Gordon Davisson    7 年前

    一般来说,从一个程序(或shell函数)输出的与主输出数据不同的日志类型输出应该被发送到标准错误,而不是标准输出,这是这样的:

    doThing() {
       echo "stuff" >&2    # Logging output goes to stderr
       echo "things"  >&2
       echo "usefulstring"
    }
    

    …然后 result=$( doThing ) 将“stuff”和“things”打印到stderr,并设置 result 到“usefulstring”。如果希望日志输出最终变为脚本的标准输出,可以将其重新定向,如下所示:

    result=$( doThing ) 2>&1
    
    推荐文章