将 subshel​​l 传递给 bash 函数

Passing subshell to bash function

我有一组 bash 日志函数,使我能够轻松地将所有输出重定向到日志文件并在发生某些事情时退出:

#! /usr/bin/env bash

# This script is meant to be sourced

export SCRIPT=[=11=]
if [ -z "${LOG_FILE}" ]; then
    export LOG_FILE="./log.txt"
fi

# 
# If the message is piped receives info, if the message is a parameter
# receives info, message
log() {
    local TYPE
    local IN
    local PREFIX
    local LINE

    TYPE=""
    if [ -n "" ]; then
        IN=""
    else
        if read -r LINE; then
          IN="${LINE}"
        fi

        while read -r LINE; do
          IN="${IN}\n${LINE}"
        done

        IN=$(echo -e "${IN}")
    fi

    if [ -n "${IN}" ]; then
        PREFIX=$(date +"[%X %d-%m-%y - $(basename "${SCRIPT}")] ${TYPE}: ")
        IN="$(echo "${IN}" | awk -v PREFIX="${PREFIX}" '{printf PREFIX}[=11=]')"
        touch "${LOG_FILE}"
        echo "${IN}" >> "${LOG_FILE}"
    fi
}

# receives message as parameter or piped, logs as info
info() {
    log "( INFO )" "$@" 
}

# receives message as parameter or piped, logs as an error
error() {
    log "(ERROR )" "$@"
}

# logs error and exits
fail() {
    error ""
    exit 1
}

# Reroutes stdout to info and sterr to error
log_wrap()
{
    "$@" > >(info) 2> >(error)
    return $?
}

然后我使用函数如下:

LOG_FILE="logging.log"
source "log_functions.sh"

info "Program started"
log_wrap some_command arg0 arg1 --kwarg=value || fail "Program failed"

哪个有效。由于 log_wrap 重定向 stdout 和 sterr 我不希望它干扰使用管道或重定向组成的命令。如:

log_wrap echo "File content" > ~/user_file || fail "user_file could not be created."
log_wrap echo "File content" | sudo tee ~/root_file > /dev/null || fail "root_file could not be created."

所以我想要一种方法来对这些命令进行分组,以便解决它们的重定向问题,然后将其传递给 log_wrap。我知道两种分组方式:

概括地说,我的问题是:有没有办法将命令组合(在我的例子中由 redirection/piping 组合)传递给 bash 函数?

按照它的设置方式,您只能传递 Posix 所谓的简单命令——命令名称和参数。子 shell 或大括号组等复合命令将不起作用。

但是,您可以在一个简单的命令中使用函数 运行 任意代码:

foo() { { echo "File content" > ~/user_file; } || fail "user_file could not be created."; }
log_wrap foo

您还可以考虑使用 exec:

将包装器自动应用于脚本其余部分中的所有命令
exec > >(info) 2> >(error)
{ echo "File content" > ~/user_file; } || fail "user_file could not be created.";