echo처럼 작동하지만 stdout이 아닌 stderr로 출력하는 표준 Bash 도구가 있습니까?
echo foo 1>&2
할 수 있다는 것을 알고 있지만 그것은 다소 추하고 오류가 발생하기 쉬운 것 같습니다(예: 상황이 변경될 때 잘못 편집될 가능성이 더 높음).
질문자 :BCS
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"을 사용하고 echo가 일반적으로 삼키는 인수(-n)를 포함하여 전달하는 모든 것을 인쇄합니다.
echoerr() { cat <<< "$@" 1>&2; }
Glenn Jackman의 솔루션은 인수 삼키는 문제도 방지합니다.
echoerr() { printf "%s\n" "$*" >&2; }
1
>
와 같은 출력 리디렉션 앞에 명시적으로 이름을 지정할 필요가 없습니다. 대신 다음을 간단히 입력할 수 있습니다.
echo This message goes to stderr >&2
1>&2
는 확실하게 타이핑하기 어려울 것 같아서 1
없애는 것이 약간의 격려가 될 수 있습니다!
다른 옵션
echo foo >>/dev/stderr
아니요, 표준 방식입니다. 오류가 발생하지 않아야 합니다.
메시지를 syslog에도 기록하는 데 신경 쓰지 않는다면 not_so_ugly 방법은 다음과 같습니다.
logger -s $msg
-s 옵션은 "메시지를 표준 오류와 시스템 로그에 출력합니다."를 의미합니다.
참고 : 나는 오해의 소지가있는 / 모호한 "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에서 문제를 처리하는 이유:
다른 이유들:
내가 최근에 우연히 발견한 또 다른 옵션은 다음과 같습니다.
{ echo "First error line" echo "Second error line" echo "Third error line" } >&2
이것은 여러 줄 오류 출력을 오류가 덜 발생하도록 만드는 동안 Bash 내장만 사용합니다(모든 줄에 &>2
나의 제안:
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
효과적으로 출력됩니다. , 1
및 2
stdin
, stdout
및 stderr
나타냅니다.
/proc/self
링크는 MacOS에서 작동하지 않지만 /proc/self/fd/*
는 Android의 Termux에서 사용할 수 있지만 /dev/stderr
에서는 사용할 수 없습니다. Bash 스크립트에서 OS를 감지하는 방법은 무엇입니까? 사용할 변형을 결정하여 스크립트를 더 이식성 있게 만들어야 하는 경우 도움이 될 수 있습니다.
이것은 파이프 입력을 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
를 사용하지 마십시오. cat
은 프로그램 이고 echo
와 printf
는 bash(쉘) 내장입니다. 프로그램 이나 다른 스크립트(위에서도 언급됨)를 시작하는 것은 모든 비용을 들여 새로운 프로세스를 생성하는 것을 의미합니다. 내장 함수를 사용하면 프로세스(-environment)를 생성(실행)할 필요가 없기 때문에 함수 작성 비용이 상당히 저렴합니다.
오프너는 " stderr로 출력(파이프 )할 표준 도구가 있습니까?"라고 묻고 짧은 대답은 다음과 같습니다. 아니요 ... 왜? ... 파이프 리디렉션은 유닉스(Linux...) 및 bash(sh)와 같은 시스템의 기본 개념입니다. 이러한 개념을 기반으로 합니다.
나는 다음과 같은 표기법으로 리디렉션하는 오프너에 동의합니다. &2>1
현대 프로그래머에게는 그다지 유쾌하지 않지만 bash입니다. Bash는 거대하고 강력한 프로그램을 작성하기 위한 것이 아니라 관리자가 키를 적게 눌러 작업할 수 있도록 돕기 위한 것입니다. ;-)
그리고 최소한 라인의 아무 곳에나 리디렉션을 배치할 수 있습니다.
$ echo This message >&2 goes to stderr This message goes to stderr
read
는 stderr로 인쇄하는 쉘 내장 명령이며 리디렉션 트릭을 수행하지 않고 echo처럼 사용할 수 있습니다.
read -t 0.1 -p "This will be sent to stderr"
-t 0.1
은 stdin의 한 줄을 변수에 저장하여 읽기의 주요 기능을 비활성화하는 시간 초과입니다.
James Roth 와 Glenn Jackman이 제안한 결합 솔루션
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"
스크립트 만들기
#!/bin/sh echo $* 1>&2
그것이 당신의 도구가 될 것입니다.
또는 별도의 파일에 스크립트를 갖고 싶지 않다면 함수를 만드십시오.
다음은 마지막 명령의 종료 상태를 확인하여 오류를 표시하고 스크립트를 종료하는 기능입니다.
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
Mac OS X: 허용된 답변과 몇 가지 다른 답변을 시도했지만 모두 내 Mac에서 STDERR이 아닌 STDOUT을 작성했습니다.
다음은 Perl을 사용하여 표준 오류에 쓰는 이식 가능한 방법입니다.
echo WARNING! | perl -ne 'print STDERR'
출처 : http:www.stackoverflow.com/questions/2990414/echo-that-outputs-to-stderr
Git 태그의 이름을 어떻게 바꾸나요? (0) | 2023.04.14 |
---|---|
Python에 디렉토리가 있는지 확인하는 방법 (0) | 2023.04.13 |
오래된 Docker 컨테이너를 제거하는 방법 (1) | 2023.04.13 |
디스크에서 이미 삭제된 Git 리포지토리에서 여러 파일 제거 (0) | 2023.04.13 |
프로젝트의 단일 파일에 대해 ARC를 비활성화하려면 어떻게 해야 합니까? (0) | 2023.04.13 |