bash 输出到 stderr 的 echo
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2990414/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
echo that outputs to stderr
提问by BCS
Is there a standard Bash tool that acts like echo but outputs to stderr rather than stdout?
是否有一个标准的 Bash 工具,它的作用类似于 echo 但输出到 stderr 而不是 stdout?
I know I can do echo foo 1>&2
but it's kinda ugly and, I suspect, error prone (e.g. more likely to get edited wrong when things change).
我知道我可以做,echo foo 1>&2
但它有点难看,而且我怀疑它容易出错(例如,当事情发生变化时,更可能被编辑错误)。
回答by Marco Aurelio
You could do this, which facilitates reading:
你可以这样做,这有利于阅读:
>&2 echo "error"
>&2
copies file descriptor #2 to file descriptor #1. Therefore, after this redirection is performed, both file descriptors will refer to the same file: the one file descriptor #2 was originallyreferring to. For more information see the Bash Hackers Illustrated Redirection Tutorial.
>&2
将文件描述符 #2 复制到文件描述符 #1。因此,在执行此重定向后,两个文件描述符将引用同一个文件:文件描述符 #2最初引用的文件描述符。有关更多信息,请参阅Bash 黑客图示重定向教程。
回答by James Roth
You could define a function:
你可以定义一个函数:
echoerr() { echo "$@" 1>&2; }
echoerr hello world
This would be faster than a script and have no dependencies.
这将比脚本更快并且没有依赖项。
Camilo Martin's bash specific suggestion uses a "here string" and will print anything you pass to it, including arguments (-n) that echo would normally swallow:
Camilo Martin 的 bash 特定建议使用“here string”并打印您传递给它的任何内容,包括 echo 通常会吞下的参数 (-n):
echoerr() { cat <<< "$@" 1>&2; }
Glenn Hymanman's solution also avoids the argument swallowing problem:
Glenn Hymanman 的解决方案也避免了论点吞咽问题:
echoerr() { printf "%s\n" "$*" >&2; }
回答by Brandon Rhodes
Since 1
is the standard output, you do not have to explicitly name it in front of an output redirection like >
but instead can simply type:
由于1
是标准输出,因此您不必在输出重定向前明确命名它,>
而只需键入:
echo This message goes to stderr >&2
Since you seem to be worried that 1>&2
will be difficult for you to reliably type, the elimination of the redundant 1
might be a slight encouragement to you!
既然您似乎担心1>&2
很难可靠地打字,那么消除多余的部分1
可能对您来说是一个小小的鼓励!
回答by Steven Penny
Another option
另外一个选项
echo foo >>/dev/stderr
回答by Matthew Flaschen
No, that's the standard way to do it. It shouldn't cause errors.
不,这是标准的做法。它不应该导致错误。
回答by Grzegorz Luczywo
If you don't mind logging the message also to syslog, the not_so_ugly way is:
如果您不介意将消息也记录到 syslog,那么 not_so_ugly 方法是:
logger -s $msg
The -s option means: "Output the message to standard error as well as to the system log."
-s 选项表示:“将消息输出到标准错误以及系统日志。”
回答by erselbst
This is a simple STDERR function, which redirect the pipe input to STDERR.
这是一个简单的 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
回答by Cezary Baginski
Note: I'm answering the post- not the misleading/vague "echo that outputs to stderr" question (already answered by OP).
注意:我正在回答帖子 - 而不是误导性/模糊的“输出到标准错误的回声”问题(已由 OP 回答)。
Use a function to show the intentionand source the implementation you want. E.g.
使用函数来显示意图并获取所需的实现。例如
#!/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!"
And error_handling
being:
并且error_handling
是:
ADMIN_EMAIL=root@localhost
config_error() { filename=""; 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"; }
Reasons that handle concerns in OP:
在 OP 中处理问题的原因:
- nicest syntax possible (meaningful words instead of ugly symbols)
- harder to make an error (especially if you reuse the script)
- it's not a standard Bash tool, but it can be a standard shell library for you or your company/organization
- 最好的语法(有意义的词而不是丑陋的符号)
- 更难出错(特别是如果你重用脚本)
- 它不是标准的 Bash 工具,但它可以是您或您的公司/组织的标准 shell 库
Other reasons:
其他原因:
- clarity - shows intention to other maintainers
- speed - functions are faster than shell scripts
- reusability - a function can call another function
- configurability - no need to edit original script
- debugging - easier to find the line responsible for an error (especially if you're deadling with a ton of redirecting/filtering output)
- robustness - if a function is missing and you can't edit the script, you can fall back to using external tool with the same name (e.g. log_error can be aliased to logger on Linux)
- switching implementations - you can switch to external tools by removing the "x" attribute of the library
- output agnostic - you no longer have to care if it goes to STDERR or elsewhere
- personalizing - you can configure behavior with environment variables
- 清晰 - 向其他维护者展示意图
- 速度 - 函数比 shell 脚本更快
- 可重用性 - 一个函数可以调用另一个函数
- 可配置性 - 无需编辑原始脚本
- 调试 - 更容易找到导致错误的行(特别是如果您正在处理大量重定向/过滤输出)
- 健壮性 - 如果缺少某个函数并且您无法编辑脚本,则可以回退到使用具有相同名称的外部工具(例如,在 Linux 上 log_error 可以别名为 logger)
- 切换实现 - 您可以通过删除库的“x”属性来切换到外部工具
- 输出不可知 - 您不再需要关心它是否转到 STDERR 或其他地方
- 个性化 - 您可以使用环境变量配置行为
回答by Sebastian
My suggestion:
我的建议:
echo "my errz" >> /proc/self/fd/2
or
或者
echo "my errz" >> /dev/stderr
echo "my errz" > /proc/self/fd/2
will effectively output to stderr
because /proc/self
is a link to the current process, and /proc/self/fd
holds the process opened file descriptors, and then, 0
, 1
, and 2
stand for stdin
, stdout
and stderr
respectively.
echo "my errz" > /proc/self/fd/2
将有效输出stderr
,因为/proc/self
是当前进程的链接,并/proc/self/fd
持有进程打开的文件描述符,然后0
,1
和2
代表stdin
,stdout
并stderr
分别。
The /proc/self
link doesn't work on MacOS, however, /proc/self/fd/*
is available on Termux on Android, but not /dev/stderr
. How to detect the OS from a Bash script?can help if you need to make your script more portable by determining which variant to use.
该/proc/self
链接在 MacOS/proc/self/fd/*
上不起作用,但在 Android 上的 Termux 上可用,但在/dev/stderr
. 如何从 Bash 脚本中检测操作系统?如果您需要通过确定要使用的变体来提高脚本的可移植性,可以提供帮助。
回答by return42
Don't use cat
as some are mentioned here. cat
is a programwhile echo
and printf
are bash (shell) builtins. Launching a programor an other script (also mentioned above) means create an new process with all it's costs. Using builtins, writing functions are quite cheap, because there is no need to create (execute) a process (-environment).
不要使用cat
这里提到的一些。cat
是一个程序whileecho
并且printf
是 bash (shell) 内置程序。启动一个程序或其他脚本(也在上面提到过)意味着创建一个新的进程,不惜一切代价。使用内置函数,编写函数非常便宜,因为不需要创建(执行)进程(-environment)。
The opner asks "is there any standard tool to output (pipe) to stderr", the schort answer is : NO ... why? ... rediredcting pipes is an elemantary concept in systems like unix (Linux...) and bash (sh) builds up on these concepts.
opner 询问“是否有任何标准工具可以将(管道)输出到 stderr”,而 schort 的回答是:NO ... 为什么?...重定向管道是 unix (Linux ...) 和 bash (sh) 等系统中的一个基本概念,它建立在这些概念之上。
I agree with the opener that redirecting with notations like this: &2>1
is not very pleasant for modern programmers, but that's bash. Bash was not intended to write huge and robust programs, it is intended to help the admins to get there work with less keypresses ;-)
我同意用这样的符号重定向的开场白:&2>1
对现代程序员来说不是很愉快,但那是 bash。Bash 并不是要编写庞大而强大的程序,它的目的是帮助管理员以更少的按键完成工作;-)
And at least, you can place the redirection anywhere in the line:
至少,您可以将重定向放在行中的任何位置:
$ echo This message >&2 goes to stderr
This message goes to stderr