【问题标题】:Shell scripting return values not correct, why?Shell 脚本返回值不正确,为什么?
【发布时间】:2013-02-12 16:29:36
【问题描述】:

在我编写的用于测试函数如何返回值的 shell 脚本中,我遇到了一个奇怪的意外行为。下面的代码假定当输入函数 fnttmpfile 时,第一个 echo 语句将打印到控制台,然后第二个 echo 语句实际上将字符串返回给调用 main。好吧,这就是我的假设,但我错了!

#!/bin/sh

fntmpfile() {
TMPFILE=/tmp/$1.$$
echo "This is my temp file dude!"
echo "$TMPFILE"
}

mainname=main
retval=$(fntmpfile "$mainname")
echo "main retval=$retval"

实际发生的情况正好相反。第一个回显到调用函数,第二个回显到 STDOUT。为什么会这样,有没有更好的方法....

main retval=这是我的临时文件,伙计! /tmp/main.19121

这个测试的全部原因是因为我正在编写一个 shell 脚本来做一些数据库备份,并决定使用小函数来做特定的事情,你知道让它干净而不是意大利面条代码。我使用的功能之一是:

log_to_console() {
    # arg1 = calling function name
    # arg2 = message to log
    printf "$1 - $2\n"
}

整个问题在于返回字符串值的函数正在获取 log_to_console 输出,而不是取决于事物的顺序。我想这是我不知道的关于 shell 脚本的那些问题之一。

【问题讨论】:

标签: bash shell scripting


【解决方案1】:

不,发生的事情是您正在运行您的函数,它会向标准输出输出两行:

This is my temp file dude!
/tmp/main.4059

当你运行它$() 时,bash 会截取输出并将其存储在值中。存储在变量中的字符串包含第一个换行符(最后一个被删除)。所以真正在你的“retval”变量中的是以下 C 风格的字符串:

"This is my temp file dude!\n/tmp/main.4059"

这并不是真正返回一个字符串(不能在 shell 脚本中这样做),它只是捕获函数返回的任何输出。这就是为什么它不起作用。如果您想登录到控制台,请正常调用您的函数。

【讨论】:

  • 将日志输出发送到 stderr(即echo "Created temp file: $TMPFILE" >&2)也可能是合适的——$() 仅捕获标准输出。