You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash中关闭stdout后,函数如何返回值?

关闭stdout后如何让Bash函数正常返回值?

背景

为了避免脚本被CRON调用时写入/var/log/cron.log,我在多个Bash脚本开头加入了以下代码:

# Not an interactive use.
if [[ ! -t 0 && ! -t 1 ]]; then
    #echo "The script is not called interactively.  Close stdout and stderr."
    # Close standard output file descriptor
    exec 1<&-
    # Close standard error file descriptor
    exec 2<&-
fi

但这段代码存在副作用:脚本内函数通过echo返回的值无法被$(...)调用行读取。比如下面的示例脚本,运行后不会输出Test is true:

#! /bin/bash

# Not an interactive use.
if [[ ! -t 0 && ! -t 1 ]]; then
    #echo "The script is not called interactively.  Close stdout and stderr."
    # Close standard output file descriptor
    exec 1<&-
    # Close standard error file descriptor
    exec 2<&-
fi

function myTest() {
    echo true
}

if [[ $(myTest) == true ]]; then
    echo Test is true;
fi

我找到一种用全局变量的临时解决方法,但不够优雅:

declare gResult;

function myTest() {
    gResult=true;
}

myTest
if [[ "$gResult" == true ]]; then
    echo Test is true;
fi

可行解决方案

1. 重定向到/dev/null而非关闭文件描述符

核心问题是exec 1<&-直接关闭了stdout文件描述符,导致$(...)无法捕获子shell的输出。只需将关闭操作改为重定向到/dev/null,既能避免输出写入cron日志,又能保留stdout的存在性,让函数的echo输出可以被正常捕获:

# 非交互式调用处理
if [[ ! -t 0 && ! -t 1 ]]; then
    # 将stdout和stderr重定向到/dev/null,而非关闭
    exec 1>/dev/null
    exec 2>/dev/null
fi

修改后,原示例脚本中$(myTest)能正常拿到true,执行echo Test is true,但该输出会被导向/dev/null,不会出现在/var/log/cron.log中,完全满足需求。

2. 利用函数的退出状态返回简单值

如果函数只需返回布尔状态或小整数结果,直接使用Bash函数的退出状态(return语句)即可,完全不需要依赖stdout:

function myTest() {
    # 返回0表示成功/true,非0表示失败/false
    return 0
}

# 直接通过函数的退出状态判断
if myTest; then
    echo Test is true;
fi

这种方式完全避开了stdout的问题,代码更简洁,适合状态类返回场景。

3. 备份文件描述符(适合必须关闭stdout的场景)

如果业务场景要求必须关闭stdout,可以先将stdout备份到一个备用文件描述符,让函数输出到这个备份描述符,捕获时从该描述符读取:

# 非交互式调用处理
if [[ ! -t 0 && ! -t 1 ]]; then
    # 备份stdout到文件描述符3,再关闭原stdout和stderr
    exec 3>&1
    exec 1<&-
    exec 2<&-
fi

function myTest() {
    # 输出到备份的文件描述符3
    echo true >&3
}

# 从文件描述符3捕获函数输出
if [[ $(myTest 2>&1) == true ]]; then
    # 若需输出内容,同样指向备份的描述符
    echo Test is true >&3
fi

内容的提问来源于stack exchange,提问作者ballatom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 22:32:52