Development Tip

stderr로 출력하는 에코

yourdevel 2020. 9. 27. 14:06
반응형

stderr로 출력하는 에코


echo처럼 작동하지만 stdout이 아닌 stderr로 출력하는 표준 Bash 도구가 있습니까?

나는 내가 할 수 있다는 것을 알고 echo foo 1>&2있지만 그것은 다소 추하고 오류가 발생하기 쉽다고 생각한다 (예 : 상황이 바뀔 때 잘못 편집 될 가능성이 더 높다).


이렇게하면 쉽게 읽을 수 있습니다.

>&2 echo "error"

>&2파일 설명자 # 2를 파일 설명자 # 1에 복사합니다. 따라서이 리디렉션이 수행 된 후 두 파일 설명자는 동일한 파일을 참조합니다. 하나의 파일 설명자 # 2가 원래 참조 하던 파일 입니다. 자세한 내용은 Bash Hackers Illustrated Redirection Tutorial을 참조하십시오 .


함수를 정의 할 수 있습니다.

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

이것은 스크립트보다 빠르며 종속성이 없습니다.

Camilo Martin의 bash 특정 제안은 "here string"을 사용하고 에코가 일반적으로 삼키는 인수 (-n)를 포함하여 전달하는 모든 항목을 인쇄합니다.

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

Glenn Jackman의 솔루션은 또한 논쟁 삼키는 문제를 피합니다.

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

1표준 출력 이므로 출력 리디렉션 앞에 명시 적으로 이름을 지정할 필요는 >없지만 다음 과 같이 간단히 입력 할 수 있습니다.

echo이 메시지는 stderr> & 2로 이동합니다.

1>&2안정적으로 타이핑하기 어려울까 걱정되는 것 같으니 중복 제거 1는 약간의 격려가 될 수 있습니다!


다른 옵션

echo foo >>/dev/stderr

아니, 그게 표준 방법입니다. 오류를 일으키지 않아야합니다.


메시지를 syslog에도 기록해도 괜찮다면 not_so_ugly 방법은 다음과 같습니다.

logger -s $msg

-s 옵션은 "메시지를 표준 오류 및 시스템 로그로 출력"을 의미합니다.


이것은 파이프 입력을 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

cat일부는 여기에 언급되어 있으므로 사용하지 마십시오 . catA는 프로그램 상태 echoprintf(쉘) 내장 매크로 배시이다. 발사 프로그램 (또한 위에서 언급 한) 또는 다른 스크립트 수단이 그것의 비용을 모두 가진 새로운 프로세스를 생성합니다. 내장 기능을 사용하면 프로세스 (-환경)를 생성 (실행) 할 필요가 없기 때문에 함수 작성 비용이 상당히 저렴합니다.

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.

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 ;-)

And at least, you can place the redirection anywhere in the line:

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

Note: I'm answering the post- not the misleading/vague "echo that outputs to stderr" question (already answered by OP).

Use a function to show the intention and 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:

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"; }

Reasons that handle concerns in 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

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

This has been answered already and with a lot of votes. Just for the record:

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

will effectively output to stderr. Explanation: /proc/self is a link to the current process and /proc/self/fd holds the process opened file descriptors. Then, 0, 1, and 2 stands for stdin, stdout and stderr respectively.

I found it more readable. Also this may work in most linux distibutions:

echo "my errz" > /dev/stderr

Making it a lot more readable.


read is a shell builtin command that prints to stderr, and can be used like echo without performing redirection tricks:

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

The -t 0.1 is a timeout that disables read's main functionality, storing one line of stdin into a variable.


Another option that I recently stumbled on is this:

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

This uses only Bash built-ins while making multi-line error output less error prone (since you don't have to remember to add &>2 to every line).


Make a script

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

that would be your tool.

Or make a function if you don't want to have a script in separate file.


Mac OS X: I tried the accepted answer and a couple of other answers and all of them resulted in writing STDOUT not STDERR on my Mac.

Here is a portable way to write to standard error using Perl:

echo WARNING! | perl -ne 'print STDERR'

참고URL : https://stackoverflow.com/questions/2990414/echo-that-outputs-to-stderr

반응형