etc./StackOverFlow

stderr로 출력하는 echo

청렴결백한 만능 재주꾼 2023. 4. 13. 10:23
반응형

질문자 :BCS


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

echo foo 1>&2 할 수 있다는 것을 알고 있지만 그것은 다소 추하고 오류가 발생하기 쉬운 것 같습니다(예: 상황이 변경될 때 잘못 편집될 가능성이 더 높음).



이렇게 하면 읽기가 쉬워집니다.

 >&2 echo "error"

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


Marco Aurelio

다음과 같이 함수를 정의할 수 있습니다.

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

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

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

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

Glenn Jackman의 솔루션은 인수 삼키는 문제도 방지합니다.

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

James

1 > 와 같은 출력 리디렉션 앞에 명시적으로 이름을 지정할 필요가 없습니다. 대신 다음을 간단히 입력할 수 있습니다.

 echo This message goes to stderr >&2

1>&2 는 확실하게 타이핑하기 어려울 것 같아서 1 없애는 것이 약간의 격려가 될 수 있습니다!


Brandon Rhodes

다른 옵션

 echo foo >>/dev/stderr

Steven Penny

아니요, 표준 방식입니다. 오류가 발생하지 않아야 합니다.


Matthew Flaschen

메시지를 syslog에도 기록하는 데 신경 쓰지 않는다면 not_so_ugly 방법은 다음과 같습니다.

 logger -s $msg

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


Grzegorz Luczywo

참고 : 나는 오해의 소지가있는 / 모호한 "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 도구는 아니지만 귀하 또는 귀하의 회사/조직을 위한 표준 셸 라이브러리가 될 수 있습니다.

다른 이유들:

  • 명확성 - 다른 유지 관리자에게 의도를 보여줍니다.
  • 속도 - 함수가 쉘 스크립트보다 빠릅니다.
  • 재사용성 - 함수가 다른 함수를 호출할 수 있음
  • 구성 가능성 - 원본 스크립트를 편집할 필요 없음
  • 디버깅 - 오류의 원인이 되는 라인을 더 쉽게 찾을 수 있습니다(특히 수많은 리디렉션/필터링 출력으로 치명적인 경우).
  • 견고성 - 함수가 누락되어 스크립트를 편집할 수 없는 경우 동일한 이름의 외부 도구를 사용하도록 대체할 수 있습니다(예: Linux에서 log_error는 로거에 별칭이 지정될 수 있음)
  • 구현 전환 - 라이브러리의 "x" 속성을 제거하여 외부 도구로 전환할 수 있습니다.
  • 출력 불가지론 - STDERR 또는 다른 곳으로 이동하는지 더 이상 신경 쓸 필요가 없습니다.
  • 개인화 - 환경 변수로 동작을 구성할 수 있습니다.

Cezary Baginski

내가 최근에 우연히 발견한 또 다른 옵션은 다음과 같습니다.

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

이것은 여러 줄 오류 출력을 오류가 덜 발생하도록 만드는 동안 Bash 내장만 사용합니다(모든 줄에 &>2


GuyPaddock

나의 제안:

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

또는

 echo "my errz" >> /dev/stderr

echo "my errz" > /proc/self/fd/2 /proc/self 가 현재 프로세스에 대한 링크이고 /proc/self/fd 가 열린 파일 0 이기 때문에 stderr 효과적으로 출력됩니다. , 12 stdin , stdoutstderr 나타냅니다.

/proc/self 링크는 MacOS에서 작동하지 않지만 /proc/self/fd/* 는 Android의 Termux에서 사용할 수 있지만 /dev/stderr 에서는 사용할 수 없습니다. Bash 스크립트에서 OS를 감지하는 방법은 무엇입니까? 사용할 변형을 결정하여 스크립트를 더 이식성 있게 만들어야 하는 경우 도움이 될 수 있습니다.


Sebastian

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

erselbst

일부가 여기에서 언급했듯이 cat 를 사용하지 마십시오. cat프로그램 이고 echoprintf 는 bash(쉘) 내장입니다. 프로그램 이나 다른 스크립트(위에서도 언급됨)를 시작하는 것은 모든 비용을 들여 새로운 프로세스를 생성하는 것을 의미합니다. 내장 함수를 사용하면 프로세스(-environment)를 생성(실행)할 필요가 없기 때문에 함수 작성 비용이 상당히 저렴합니다.

오프너는 " stderr로 출력(파이프 )할 표준 도구가 있습니까?"라고 묻고 짧은 대답은 다음과 같습니다. 아니요 ... 왜? ... 파이프 리디렉션은 유닉스(Linux...) 및 bash(sh)와 같은 시스템의 기본 개념입니다. 이러한 개념을 기반으로 합니다.

나는 다음과 같은 표기법으로 리디렉션하는 오프너에 동의합니다. &2>1 현대 프로그래머에게는 그다지 유쾌하지 않지만 bash입니다. Bash는 거대하고 강력한 프로그램을 작성하기 위한 것이 아니라 관리자가 키를 적게 눌러 작업할 수 있도록 돕기 위한 것입니다. ;-)

그리고 최소한 라인의 아무 곳에나 리디렉션을 배치할 수 있습니다.

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

return42

read 는 stderr로 인쇄하는 쉘 내장 명령이며 리디렉션 트릭을 수행하지 않고 echo처럼 사용할 수 있습니다.

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

-t 0.1 은 stdin의 한 줄을 변수에 저장하여 읽기의 주요 기능을 비활성화하는 시간 초과입니다.


Douglas Mayle

James RothGlenn Jackman이 제안한 결합 솔루션

  • 오류 메시지를 빨간색으로 표시하려면 ANSI 색상 코드를 추가하십시오.
 echoerr() { printf "\e[31;1m%s\e[0m\n" "$*" >&2; } # if somehow \e is not working on your terminal, use \u001b instead # echoerr() { printf "\u001b[31;1m%s\u001b[0m\n" "$*" >&2; } echoerr "This error message should be RED"

Polymerase

스크립트 만들기

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

그것이 당신의 도구가 될 것입니다.

또는 별도의 파일에 스크립트를 갖고 싶지 않다면 함수를 만드십시오.


n0rd

다음은 마지막 명령의 종료 상태를 확인하여 오류를 표시하고 스크립트를 종료하는 기능입니다.

 or_exit() { local exit_status=$? local message=$* if [ "$exit_status" -gt 0 ] then echo "$(date '+%F %T') [$(basename "$0" .sh)] [ERROR] $message" >&2 exit "$exit_status" fi }

용법:

 gzip "$data_dir" or_exit "Cannot gzip $data_dir" rm -rf "$junk" or_exit Cannot remove $junk folder

crontab 에서 스크립트를 호출하고 오류를 기록할 때 유용하도록 스크립트 이름과 날짜를 출력합니다.

 59 23 * * * /my/backup.sh 2>> /my/error.log

Miroslav Popov

Mac OS X: 허용된 답변과 몇 가지 다른 답변을 시도했지만 모두 내 Mac에서 STDERR이 아닌 STDOUT을 작성했습니다.

다음은 Perl을 사용하여 표준 오류에 쓰는 이식 가능한 방법입니다.

 echo WARNING! | perl -ne 'print STDERR'

Noah Sussman

출처 : http:www.stackoverflow.com/questions/2990414/echo-that-outputs-to-stderr

반응형