Unix - 두 파일의 stderr 및 stdout

Unix - 두 파일의 stderr 및 stdout

일부 기능을 갖춘 쉘 스크립트가 있습니다. 각 명령의 성공적인 실행을 파일 및 stderr/echo 문에 캡처하고 오류 메시지를 다른 파일에 복사하려고 합니다. 그러나 오류 설명은 오류 파일로 리디렉션되지 않고 실제 로그 파일로 리디렉션됩니다. 아래는 참고용 코드입니다.

Bash script 
***********
#! /bin/sh
Function_1()
{
now=$( date '+%Y%m%d%H%M' )
eval logfile="$1"_"$now".log
exec 2>&1 1>>$logfile     
echo " "
echo "############################"
echo "Function execution Begins"
echo "############################"
echo "Log file got created with file name as $1.log"
eval number=$1
eval  path=$2
echo "number= $number"
ls -lR $path >> temp.txt
    if [ $? -eq 0 ]; then
    echo " Above query executed."
    else
    echo "Query execution failed"
    fi
    echo "############################"
    echo "Function execution Ends"
    echo "############################"
    echo " "
}

답변1

exec 2>&1 1>>$logfile 

이는 먼저 stderr를 당시 stdout이 있는 곳으로 리디렉션하고,그 다음에표준 출력을 로그 파일로 리디렉션합니다. 결과적으로 stderr은 터미널로 이동하고 stdout은 로그 파일로 이동하게 될 수 있습니다.

(실제로 하나만 언급되기 때문에 출력을 두 개의 파일로 생성하는 방법을 잘 모르겠습니다. 스크립트를 로 실행하는 것이 아니라면 script.sh > errorfile이상해 보입니다.)

물론 모든 echo명령은 표준 출력으로 인쇄되므로 해당 출력은 모두 동일한 위치로 전송됩니다. ls그러나 오류가 생성되어 터미널로 이동하게 될 수 있습니다.

일반 출력과 오류 출력을 서로 다른 두 파일로 리디렉션하려면 다음을 수행하세요.

exec 1>>"$logfile" 2>>"$errorfile"

이제 다음을 사용할 수 있습니다.

echo "Something worked normally"

그리고

echo "This is an error message" >&2

로그에 정상 상태를 출력하고 오류 파일에 오류를 출력합니다. (리디렉션에 유의하세요.)


또 다른 점은:

eval logfile="$1"_"$now".log
eval number=$1
eval path=$2

여기의 s는 쓸모가 없으며 예를 들어 공백이 포함되거나 더 나쁜 경우 명령 대체가 포함되면 eval문제가 발생합니다 . $1그러니 그들을 죽여라. 셸에서의 할당은 이므로 var=value다음과 같습니다.

logfile="$1"_"$now".log
number=$1
path=$2

첫 번째는 그냥이라고 쓸 수도 있지만 logfile=$1_$now.log어느 것이 더 예쁜지 결정하는 것은 여러분의 몫입니다.

답변2

echo "Query execution failed"

이것은 단지 의미론적 오류 메시지일 뿐입니다.

exec 2>&1 1>>$logfile

이것은 말이 됩니다. 첫 번째 부분은 아무 작업도 수행하지 않습니다. 최근에 bobdylan으로 테스트했습니다. 그런데 언급한 오류 파일은 어디에 있습니까?


댓글을 이해합니다. 이 스크립트는 설명하기가 쉽지 않습니다.


다음은 몇 가지 기본적인 예입니다. 사용자 bodylan을 찾을 수 없습니다.

]# ls . NOsuch         
ls: cannot access 'NOsuch': No such file or directory
.:
foo

둘 다 표준 출력 장치 "터미널" STDOUT 1로 이동합니다.STDERR 2

이제 둘을 분리하겠습니다. /dev/null 대신 임의의 파일 이름을 입력할 수 있습니다.

]# ls . NOsuch >/dev/null
ls: cannot access 'NOsuch': No such file or directory

]# ls . NOsuch 2>/dev/null
.:
foo
]# ls . NOsuch >/dev/null 2>&1
(EMPTY)

]# ls . NOsuch 2>&1 >/dev/null     
ls: cannot access 'NOsuch': No such file or directory

(2>&1 has no effect)  

그리고

ls ... >ls.out 2>ls.ERRORS

...출력은 생성하지 않지만 두 개의 "스트림"을 별도로 저장해야 합니다.


스크립트를 단순하게 유지하고 호출할 때 차이를 만드세요.

답변3

앞에서 언급한 것처럼 STDERR과 STDOUT을 동일한 파일로 리디렉션합니다. ... exec 2>&1 1>>$logfile

이 줄은 STDERR을 STDOUT으로 리디렉션한 다음 STDOUT(또는 STDERR)을 파일 설명자 $logfile로 리디렉션합니다. 리디렉션과 파일 설명자는 혼란스러울 수 있습니다. 그러나 몇 가지 유용한 정보는 다음을 확인하십시오.

https://likegeeks.com/shell-scripting-awesome-guide-part4/

또한 Linux 리디렉션 및 Linux 파일 설명자를 인터넷 검색하는 것이 도움이 될 수 있습니다.

건배,

조호르

관련 정보