echo输出到stderr

这篇博客讨论了在Bash中如何将输出重定向到标准错误(stderr)而不是标准输出(stdout)。文章中提到了多种方法,包括使用`echo`配合重定向符号,使用`printf`,定义函数等。还提到了一些注意事项,如避免使用`>`和`echo`结合的技巧,以及使用Perl等其他工具实现。博主强调了在脚本中明确表达意图的重要性,以及使用函数或自定义工具的可读性、可重用性和可维护性优势。
摘要由CSDN通过智能技术生成

是否有一个标准的Bash工具,它像echo一样输出到stderr而不是stdout?

我知道我可以做echo foo 1>&2但它有点难看,我怀疑,容易出错(例如,当事情发生变化时更有可能被编辑错误)。


#1楼

由于1是标准输出,因此您不必在输出重定向(如>前面明确命名,而只需键入:

echo This message goes to stderr >&2

由于您似乎担心1>&2将难以可靠地键入,因此消除冗余1可能对您有点鼓励!


#2楼

另外一个选项

echo foo >>/dev/stderr

#3楼

read是一个shell内置命令,可以打印到stderr,并且可以像echo一样使用而不执行重定向技巧:

read -t 0.1 -p "This will be sent to stderr"

-t 0.1是一个超时,它禁用read的主要功能,将一行stdin存储到一个变量中。


#4楼

你可以这样做,这有助于阅读:

>&2 echo "error"

>&2文件描述符# >&2复制到文件描述符#1。 因此,在执行此重定向之后,两个文件描述符将引用相同的文件:一个文件描述符#2 最初是指。 有关更多信息,请参阅Bash Hackers Illustrated Redirection Tutorial


#5楼

如果您不介意将消息记录到syslog中,则not_so_ugly方式为:

logger -s $msg

-s选项表示:“将消息输出到标准错误以及系统日志。”


#6楼

不要使用cat因为这里提到的一些。 cat是一个程序,echoprintf是bash(shell)内置的。 启动程序或其他脚本(也在上面提到)意味着创建一个包含所有成本的新流程。 使用内置函数,编写函数非常便宜,因为不需要创建(执行)进程(-environment)。

opner问“是否有任何标准工具输出( 管道 )到stderr”,schort答案是:NO ...为什么? ... rediredcting管道是像unix(Linux ...)和bash(sh)这些概念的系统中的一个元素概念。

我赞同用这样的符号重定向的开场白: &2>1对现代程序员来说不是很愉快,但那是bash。 Bash并不打算编写庞大而强大的程序,它旨在帮助管理员用更少的按键来完成工作;-)

至少,您可以将重定向放在行中的任何位置:

$ echo This message >&2 goes to stderr 
This message goes to stderr

#7楼

不,这是执行此操作的标准方法。 它不应该导致错误。


#8楼

制作一个剧本

#!/bin/sh
echo $* 1>&2

这将是你的工具。

如果您不希望在单独的文件中包含脚本,请创建一个函数。


#9楼

你可以定义一个函数:

echoerr() { echo "$@" 1>&2; }
echoerr hello world

这比脚本更快,没有依赖性。

Camilo Martin的bash特定建议使用“here string”并将打印传递给它的任何内容,包括echo通常会吞下的参数(-n):

echoerr() { cat <<< "$@" 1>&2; }

格伦杰克曼的解决方案也避免了吞咽问题:

echoerr() { printf "%s\n" "$*" >&2; }

#10楼

Mac OS X:我尝试了接受的答案和其他几个答案,所有这些答案导致在我的Mac上写STDOUT而不是STDERR。

以下是使用Perl写入标准错误的可移植方法:

echo WARNING! | perl -ne 'print STDERR'

#11楼

注意:我正在回答帖子 - 而不是误导/模糊的“输出到stderr的回声”问题(已经由OP回答)。

使用函数来显示意图并获得所需的实现。 例如

#!/bin/bash

[ -x error_handling ] && . error_handling

filename="foobar.txt"
config_error $filename "invalid value!"

output_xml_error "No such account"

debug_output "Skipping cache"

log_error "Timeout downloading archive"

notify_admin "Out of disk space!"

fatal "failed to open logger!"

error_handling是:

ADMIN_EMAIL=root@localhost

config_error() { filename="$1"; shift; echo "Config error in $filename: $*" 2>&1; }

output_xml_error() { echo "<error>$*</error>" 2>&1; }

debug_output() { [ "$DEBUG"=="1" ] && echo "DEBUG: $*"; }

log_error() { logger -s "$*"; }

fatal() { which logger >/dev/null && logger -s "FATAL: $*" || echo "FATAL: $*"; exit 100; }

notify_admin() { echo "$*" | mail -s "Error from script" "$ADMIN_EMAIL"; }

处理OP问题的原因:

  • 最好的语法可能(有意义的单词而不是丑陋的符号)
  • 更难出错(特别是如果你重用脚本)
  • 它不是标准的Bash工具,但它可以是您或您的公司/组织的标准shell库

其他原因:

  • 清晰度 - 显示其他维护者的意图
  • 速度 - 函数比shell脚本更快
  • 可重用性 - 一个函数可以调用另一个函数
  • 可配置性 - 无需编辑原始脚本
  • 调试 - 更容易找到导致错误的行(特别是如果你有大量的重定向/过滤输出)
  • 健壮性 - 如果缺少一个函数并且您无法编辑脚本,您可以回退使用具有相同名称的外部工具(例如,log_error可以别名为Linux上的记录器)
  • 切换实现 - 您可以通过删除库的“x”属性来切换到外部工具
  • 输出不可知 - 你不再需要关心它是否转到STDERR或其他地方
  • 个性化 - 您可以使用环境变量配置行为

#12楼

这已经得到了很好的回答。 仅供记录:

echo "my errz" > /proc/self/fd/2

将有效输出到stderr 。 说明: /proc/self是当前进程的链接,而/proc/self/fd包含进程打开的文件描述符。 然后, 01 ,和2代表stdinstdoutstderr分别。

我发现它更具可读性。 这也适用于大多数Linux分发:

echo "my errz" > /dev/stderr

使它更具可读性。


#13楼

我最近偶然发现的另一个选择是:

    {
        echo "First error line"
        echo "Second error line"
        echo "Third error line"
    } >&2

这只使用Bash内置函数,同时使多行错误输出不易出错(因为您不必记住在每行中添加&>2 )。


#14楼

这是一个简单的STDERR函数,它将管道输入重定向到STDERR。

#!/bin/bash
# *************************************************************
# This function redirect the pipe input to STDERR.
#
# @param stream
# @return string
#
function STDERR () {

cat - 1>&2

}

# remove the directory /bubu
if rm /bubu 2>/dev/null; then
    echo "Bubu is gone."
else
    echo "Has anyone seen Bubu?" | STDERR
fi


# run the bubu.sh and redirect you output
tux@earth:~$ ./bubu.sh >/tmp/bubu.log 2>/tmp/bubu.err
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值