将用于运行脚本(stdin)、stdout 和 stderr 的命令打印到文件中的简洁方法

将用于运行脚本(stdin)、stdout 和 stderr 的命令打印到文件中的简洁方法

我试图在 bash 中运行脚本:cc.sh

运行 bash 脚本:

../cc.sh ../seq/ seqf

其中../seq/seqf都是必需的参数。

我想将用于运行脚本的命令(上面的命令)以及脚本的输出/结果一起保存到日志文件中。

我设法使用命令将输出打印到日志文件中tee

../cc.sh ../seq/ seqf 2<&1 | tee -a cc.log

cat抄送日志:

"here is where the output shown"

对于命令本身,我得到的最接近的是命令script。但是,它似乎将我用来运行的命令保存在二进制文件中。

除了打印命令之外还有其他更好的方法吗script?或者更好的是,将用于运行脚本文件的命令与输出/结果一起打印到日志文件中?

日志文件的预期输出:

COMMAND: ../cc.sh ../seq/ seqf
"here is where the output shown"

答案1

最简单的方法是修改脚本以使其将其名称和参数列表打印到标准输出。例如,如果您的脚本文件包含echo $0 $@第一行,它将打印您需要的信息(假设它使用 sh 并从 bash 启动):

#!/bin/sh
echo "$0 $@"

然后你可以将标准输出重定向到文件、tee 或任何你想要的东西。

答案2

使用数组来存储命令及其参数。将命令(数组)打印到输出文件,然后执行该命令。通过管道将所有输出tee附加到cc.log文件中:

mycommand=( ../cc.sh ../seq/ seqf )

{
    printf 'COMMAND: %s\n' "${mycommand[*]}"
    "${mycommand[@]}"
} | tee -a cc.log

这将创建数组mycommand并将其元素设置为命令及其参数。然后打印该命令,并以字符串 为前缀COMMAND:。扩展将是由第一个字符(通常是空格)"${mycommand[*]}"分隔的数组元素组成的单个字符串。$IFS

扩展"${mycommand[@]}"将是单独引用的字符串的列表,即命令及其单独引用的参数。使用这样的扩展将导致命令被正确调用。

两者的输出printf和 命令一起重定向到tee,一个接一个,因为它们是同一复合命令 ( {...;}) 的一部分。

或者,使用位置参数列表而不是命名数组,

set -- ../cc.sh ../seq/ seqf

{
    printf 'COMMAND: %s\n' "$*"
    "$@"
} | tee -a cc.log

请注意,这适用于任何命令,无论是 shell 脚本还是已编译的二进制可执行文件。

相关内容