2023-03-22 10:00:09

输出到stderr的echo

是否有一个标准的Bash工具,其行为类似于echo,但输出到stderr而不是stdout?

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


当前回答

您可以定义函数:

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

这将比脚本更快,并且没有依赖关系。

卡米洛·马丁的bash特定建议使用“here字符串”,并将打印传递给它的任何内容,包括echo通常会接受的参数(-n):

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

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

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

其他回答

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

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

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

您可以定义函数:

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

这将比脚本更快,并且没有依赖关系。

卡米洛·马丁的bash特定建议使用“here字符串”,并将打印传递给它的任何内容,包括echo通常会接受的参数(-n):

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

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

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

制作脚本

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

那将是你的工具。

或者,如果您不想在单独的文件中有脚本,则生成一个函数。

我的建议:

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

or

echo "my errz" >> /dev/stderr

echo“myerrz”>/proc/self/fd/2将有效地输出到stderr,因为/proc/self是当前进程的链接,/proc/sell/fd保存进程打开的文件描述符,然后,0、1和2分别代表stdin、stdout和stderr。

/proc/self链接在MacOS上不起作用,但是,/proc/self/fd/*在Android上的Termux上可用,但在/dev/stderr上不可用。如何从Bash脚本检测操作系统?如果您需要通过确定要使用的变量来使脚本更具可移植性,可以提供帮助。

注意:我回答的是帖子,而不是误导性/模糊的“输出到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!"

错误处理为:

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可以别名为logger)切换实现-通过删除库的“x”属性,可以切换到外部工具输出不可知-您不再需要关心它是否到达STDERR或其他地方个性化-您可以使用环境变量配置行为