如何使
Bash将变量的内容解释为I / O重定向,而不是简单地将这些内容传递给正在执行的命令.以此脚本为例:
#!/bin/bash test "$1" == '--log' && LOGGING="2>&1 | tee time.log" || LOGGING="" date $LOGGING
期望的行为是,当我使用–log选项运行此脚本时,bash将执行
$date 2>& 1 | tee time.log
如果我没有指定–log那么它只是输出日期而不创建日志.相反,它将$LOGGING的内容作为CLI参数传递给日期,从而导致错误:
date: extra operand `|' Try `date --help' for more information.
有没有办法做这个没有写一些像
#!/bin/bash test "$1" == '--log' && date 2>&1 | tee time.log || date
实际的应用程序显然要比调用“date”复杂得多,所以我想避免在if else中复制和粘贴该命令两次只是为了附加重定向和日志记录命令.
如果您的脚本相当长,并且您希望在传入–log时记录所有stdout和stderr,我建议使用exec重定向所有内容.看到这篇优秀的文章:
原文链接:https://www.f2er.com/bash/385225.htmlhttp://www.linuxjournal.com/content/bash-redirections-using-exec
#!/bin/bash if [[ "$1" == '--log' ]]; then npipe=/tmp/$$.tmp trap "rm -f $npipe" EXIT mknod $npipe p tee <$npipe log & exec 1>&- exec 1>$npipe fi date # and any other commands after this will be logged too.
这种方法的有趣之处在于,您还可以使用perl或gawk或其他一些实用程序为所有记录的行添加时间戳:
#!/bin/bash if [[ "$1" == '--log' ]]; then npipe=/tmp/$$.tmp trap "rm -f $npipe" EXIT mknod $npipe p perl -pne 'print scalar(localtime())," ";' < $npipe | tee time.log & exec 1>&- exec 1>$npipe 2>&1 fi echo hello world echo hello world 2
运行此命令后,time.log将包含:
$cat time.log Wed Jun 8 13:28:45 2011 hello world Wed Jun 8 13:28:45 2011 hello world 2
这里的缺点是时间戳也打印到您的终端.