Abh*_*pta 8 shell logs io-redirection shell-script
如何从脚本内部将 stdout 和 stderr 重定向到文件和终端。
#!/bin/sh
LOG_FILE="/tmp/abc.log"
exec &> >(tee -a $LOG_FILE)
echo "Start"
echo "Hi" 1>&2
echo "End"
Run Code Online (Sandbox Code Playgroud)
我找到了上面的脚本。但是这个脚本只适用于 bash。使用 sh shell 会出现以下错误:
./abc.sh: 5: Syntax error: redirection unexpected (expecting word)
Run Code Online (Sandbox Code Playgroud)
我想要一个同时适用于 sh 和 bash shell 的脚本。
Sté*_*las 10
是的,&>
是一个bash
运算符(现在也被 支持zsh
,虽然zsh
总是>&
像 in 一样csh
)和>(...)
一个ksh
运算符(现在也被zsh
和支持bash
),两者都不是sh
运算符。那个未加引号的 $LOG_FILE 显然不希望在此处使用 split+glob,这使其成为 zsh 语法(唯一一种在未加引号的扩展中不隐式执行 split+glob 的 shell,尽管在 中zsh
,您只需执行exec >&1 > $LOG_FILE 2>&1
)。
在sh
语法上,您可以执行以下操作:
#! /bin/sh -
LOG_FILE="/tmp/abc.log"
{
# your script here
} 2>&1 | tee -- "$LOG_FILE"
Run Code Online (Sandbox Code Playgroud)
或者把所有东西都放在一个函数中:
#! /bin/sh -
LOG_FILE="/tmp/abc.log"
main() {
# your script here
}
main "$@" 2>&1 | tee -- "$LOG_FILE"
Run Code Online (Sandbox Code Playgroud)
在任何情况下,这种方法和您的zsh
风格方法最终都会在与在 stdout 上打开的资源相同的资源上打印错误消息。因此,如果有人这样做your-script > out 2> err
, ,err
将是空的,并且out
将包含正常输出和错误。
为确保保留输出和错误的原始目的地,您可以改为:
{
{
main "$@" 3>&- | tee -a -- "$LOG_FILE" >&3 3>&-
} 2>&1 | tee -a -- "$LOG_FILE" >&2 3>&-
} 3> "$LOG_FILE" 3>&1
Run Code Online (Sandbox Code Playgroud)
(未经测试)。
归档时间: |
|
查看次数: |
432 次 |
最近记录: |