【问题标题】:output of shell script to console and file将 shell 脚本输出到控制台和文件
【发布时间】:2017-04-19 17:29:33
【问题描述】:

我在 Linux 中有如下的 shell 脚本

#!/bin/bash
LOG_LOCATION=/home/$USER/logs
exec > >(tee /home/$USER/logs/"$1") 2>&1

[ $# -ne 1 ] && { echo "Usage : $0 table ";exit 1; }

table=$1

TIMESTAMP=`date "+%Y-%m-%d"`
touch /home/$USER/logs/${TIMESTAMP}.success_log
touch /home/$USER/logs/${TIMESTAMP}.fail_log
success_logs=/home/$USER/logs/${TIMESTAMP}.success_log
failed_logs=/home/$USER/logs/${TIMESTAMP}.fail_log

#Function to get the status of the job creation
function log_status
{
       status=$1
       message=$2
       if [ "$status" -ne 0 ]; then
                echo "`date +\"%Y-%m-%d %H:%M:%S\"` [ERROR] $message [Status] $status : failed" | tee -a "${failed_logs}"
                #echo "Please find the attached log file for more details"
                exit 1
                else
                    echo "`date +\"%Y-%m-%d %H:%M:%S\"` [INFO] $message [Status] $status : success" | tee -a "${success_logs}"
                fi
}


`hive -e "create table testing.${table} as select * from fishing.${table}"`

cp /home/$USER/logs/"$1" /home/$USER/debug/"$1" 

g_STATUS=$?
log_status $g_STATUS "Hive create ${table}"

echo "***********************************************************************************************************************************************************************"

如果我的 shell 脚本中有这个

exec 2>&1 | tee /home/logging/"$1"

然后我只在控制台而不是重定向文件上获取日志。

如果我的脚本中有这个

exec> /home/logging/"$1" 2>&1

然后我在重定向文件上有日志,但在控制台上没有。

如何在控制台和重定向文件上同时记录日志

【问题讨论】:

  • 你想做什么?运行 1 美元?
  • 尝试在exec之前包含unbuffer ...
  • @kabanus $1 是我将传递给脚本的变量
  • 也许这个答案可以解决你的问题https://unix.stackexchange.com/a/145654

标签: linux bash shell stdout stderr


【解决方案1】:

您可以使用 exec 内置的进程替换:

exec > >(tee trace.log) 2>&1

将 stdout 和 stderr 重定向到一个文件并在终端中显示。

【讨论】:

  • 如果我只想在执行exec 2> >(tee trace.log) 时重定向stderr 日志,它仍在输出到stdout
  • 我想将上述问题stderr 发送到控制台和重定向文件。我们怎样才能做到这一点?
  • exec 2> >(tee trace.log) 对我来说很好,可以仅将 stderr 重定向到文件和终端。
  • 在脚本中,如果stdout 出现失败消息,并且当我们将日志收集到单个文件时,我将作业状态显示为成功。当stdout 有错误消息时,作业应在收集日志时显示失败状态。 how can I do that?
  • 在上面的脚本中,如果我不使用LOG_LOCATION=/home/$USER/logs exec > >(tee /home/$USER/logs/"$1") 2>&1 这些并且如果作业失败,我将收到失败的状态消息。但是,如果我使用LOG_LOCATION=/home/$USER/logs exec > >(tee /home/$USER/logs/"$1") 2>&1,那么即使作业失败,我也会在状态日志中获得成功
【解决方案2】:

tee 命令的目的是专门用于将输出定向到文件和终端,这听起来像是您想要的。这可以通过以下方式轻松复制:

script.sh:

#!/usr/bin/bash
date 2>&1 | tee "$1"

然后,使用./script.sh abc.txt 运行命令将产生日期命令的输出到终端以及文件abc.txt

在您的情况下,exec 2>&1 | tee /home/logging/"$1" 应该正确地产生您想要的结果,但是您需要小心地使用该参数调用脚本。假设存在/home/logging 目录,并且您使用./script log.txt 之类的内容调用上面的脚本

【讨论】: