我有具有某些功能的 shell 脚本。我试图将每个命令的成功执行捕获到一个文件和 stderr/echo 语句,并将错误消息复制到另一个文件。但错误语句不会重定向到错误文件,而是重定向到实际的日志文件。下面是我的代码供参考。
Bash script
***********
#! /bin/sh
Function_1()
{
now=$( date '+%Y%m%d%H%M' )
eval logfile="$1"_"$now".log
exec 2>&1 1>>$logfile
echo " "
echo "############################"
echo "Function execution Begins"
echo "############################"
echo "Log file got created with file name as $1.log"
eval number=$1
eval path=$2
echo "number= $number"
ls -lR $path >> temp.txt
if [ $? -eq 0 ]; then
echo " Above query executed."
else
echo "Query execution failed"
fi
echo "############################"
echo "Function execution Ends"
echo "############################"
echo " "
}
答案1
exec 2>&1 1>>$logfile
这将首先将 stderr 重定向到当时 stdout 所在的位置,并且仅然后将标准输出重定向到日志文件。结果可能是 stderr 转到终端,stdout 转到日志文件。
(我不确定您如何将输出生成到两个文件中,因为实际上只提到了一个。除非想法是将脚本运行为script.sh > errorfile
,但这看起来很奇怪。)
当然,所有echo
命令都只是打印到标准输出,因此它们的输出将全部发送到同一个地方。ls
但可能会产生错误,然后他们会进入终端。
如果您想将正常输出和错误输出重定向到两个不同的文件,只需执行以下操作:
exec 1>>"$logfile" 2>>"$errorfile"
现在您可以使用:
echo "Something worked normally"
和
echo "This is an error message" >&2
将正常状态输出到日志,将错误输出到错误文件。 (注意重定向。)
作为另一件事:
eval logfile="$1"_"$now".log
eval number=$1
eval path=$2
这里的seval
是无用的,并且会破坏一些东西,例如,如果$1
包含空格,或者更糟糕的是命令替换。所以,干掉他们吧。 shell 中的赋值就是var=value
,所以:
logfile="$1"_"$now".log
number=$1
path=$2
第一个也可以写成 just,logfile=$1_$now.log
但由你来决定哪个更漂亮。
答案2
echo "Query execution failed"
这只是语义上的错误消息。
exec 2>&1 1>>$logfile
这是有道理的——第一部分什么也不做,我最近对 bobdylan 进行了测试——但是你提到的错误文件在哪里?
我理解这些评论:这个脚本不太好解释。
这里有一些基本的例子。用户 bodylan 我找不到了。
]# ls . NOsuch
ls: cannot access 'NOsuch': No such file or directory
.:
foo
两者STDOUT 1
都STDERR 2
转到标准输出设备“终端”。
现在我将两者分开。您可以输入任何文件名,而不是 /dev/null。
]# ls . NOsuch >/dev/null
ls: cannot access 'NOsuch': No such file or directory
]# ls . NOsuch 2>/dev/null
.:
foo
]# ls . NOsuch >/dev/null 2>&1
(EMPTY)
]# ls . NOsuch 2>&1 >/dev/null
ls: cannot access 'NOsuch': No such file or directory
(2>&1 has no effect)
和
ls ... >ls.out 2>ls.ERRORS
...不应产生任何输出,但单独保存两个“流”。
让脚本保持简单,并在调用它时有所不同。
答案3
如前所述,您将 STDERR 和 STDOUT 重定向到同一个文件。
... exec 2>&1 1>>$logfile
此行将 STDERR 重定向到 STDOUT,然后将 STDOUT (也是 STDERR )重定向到文件描述符 $logfile。重定向和文件描述符可能会令人困惑。但是,请查看以下内容以获取一些有用的信息:
https://likegeeks.com/shell-scripting-awesome-guide-part4/
此外,谷歌搜索 Linux 重定向和 Linux 文件描述符可能会有所帮助。
干杯,
柔佛州