itsource

스크립트 자체 내에서 전체 셸 스크립트의 출력을 리디렉션하는 방법은 무엇입니까?

mycopycode 2023. 5. 12. 22:17
반응형

스크립트 자체 내에서 전체 셸 스크립트의 출력을 리디렉션하는 방법은 무엇입니까?

본 셸 스크립트의 모든 출력을 스크립트 내부의 셸 명령을 사용하여 어딘가로 리디렉션할 수 있습니까?

단일 명령의 출력을 리디렉션하는 것은 쉽지만 다음과 같은 작업이 필요합니다.

#!/bin/sh
if [ ! -t 0 ]; then
    # redirect all of my output to a file here
fi

# rest of script...

즉, 스크립트가 대화형이 아닌 방식으로 실행되는 경우(예: cron) 모든 항목의 출력을 파일에 저장합니다.셸에서 대화형으로 실행되는 경우 출력을 평소와 같이 stdout 상태로 둡니다.

일반적으로 FreeB에서 실행되는 스크립트에 대해 이 작업을 수행합니다.SD 정기 유틸리티.일상적인 작업의 일부입니다. 평소에는 이메일로 매일 보는 것을 꺼려서 보내지 않습니다.그러나 이 특정 스크립트 내에서 오류가 발생할 경우 이는 저에게 중요하며 일상 작업의 일부를 캡처하여 이메일로 보낼 수 있습니다.

업데이트: Joshua의 답변은 현장에서 확인할 수 있지만, 전체 스크립트에 대해 stdout 및 stderr을 저장하고 복원하고 싶었습니다. 이 작업은 다음과 같이 수행됩니다.

# save stdout and stderr to file 
# descriptors 3 and 4, 
# then redirect them to "foo"
exec 3>&1 4>&2 >foo 2>&1

# ...

# restore stdout and stderr
exec 1>&3 2>&4

질문을 업데이트된 대로 처리합니다.

#...part of script without redirection...

{
    #...part of script with redirection...
} > file1 2>file2 # ...and others as appropriate...

#...residue of script without redirection...

교정기 '{...I/O 리디렉션 단위를 제공합니다.중괄호는 명령이 나타날 수 있는 곳에 나타나야 합니다. 즉, 단순하게는 줄의 시작 부분이나 세미콜론 뒤에 나타납니다.(네, 그것은 더 정확하게 할 수 있습니다; 만약 당신이 불평하고 싶다면, 저에게 알려주세요.)

당신이 보여준 리디렉션으로 원본 stdout과 stderr를 보존할 수 있다는 것은 맞지만, 위와 같이 리디렉션된 코드의 범위를 지정하면 일반적으로 나중에 스크립트를 유지해야 하는 사람들이 무슨 일이 일어나고 있는지 이해하는 것이 더 간단합니다.

Bash 매뉴얼의 관련 섹션은 그룹화 명령 및 I/O 리디렉션입니다.POSIX 셸 사양의 관련 섹션은 복합 명령 및 I/O 리디렉션입니다.Bash에는 몇 가지 추가 표기법이 있지만 POSIX 셸 사양과 유사합니다.

일반적으로 이 중 하나를 스크립트의 맨 위 또는 맨 위에 배치합니다.명령줄을 구문 분석하는 스크립트는 구문 분석 후 리디렉션을 수행합니다.

파일로 stdout 보내기

exec > file

단호히

exec > file                                                                      
exec 2>&1

파일에 stdout 및 stderr 모두 추가

exec >> file
exec 2>&1

조나단 레플러가 논평에서 언급했듯이:

exec두 개의 별도 작업이 있습니다.첫 번째는 현재 실행 중인 셸(스크립트)을 새로운 프로그램으로 교체하는 것입니다.다른 하나는 현재 셸에서 I/O 리디렉션을 변경하는 것입니다.은 이은다음같없구것별다니됩으는에 대한 됩니다.exec.

전체 스크립트를 다음과 같은 기능으로 만들 수 있습니다.

main_function() {
  do_things_here
}

그런 다음 스크립트 끝에 다음과 같은 내용이 표시됩니다.

if [ -z $TERM ]; then
  # if not run via terminal, log everything into a log file
  main_function 2>&1 >> /var/log/my_uber_script.log
else
  # run via terminal, only output to screen
  main_function
fi

또는 실행할 때마다 모든 항목을 로그 파일에 기록하고 다음을 수행하여 stdout에 출력할 수 있습니다.

# log everything, but also output to stdout
main_function 2>&1 | tee -a /var/log/my_uber_script.log

원래 stdout 및 stderr을 저장하려면 다음을 사용할 수 있습니다.

exec [fd number]<&1 
exec [fd number]<&2

를 들어,는 " 파일walla1", "walla2")에합니다.a.txt " ".), "walla3"는 stdut, "walla4"는 stderr.

#!/bin/bash

exec 5<&1
exec 6<&2

exec 1> ~/a.txt 2>&1

echo "walla1"
echo "walla2" >&2
echo "walla3" >&5
echo "walla4" >&6
[ -t <&0 ] || exec >> test.log

저는 마침내 그것을 하는 방법을 알아냈습니다.출력을 파일에 저장할 뿐만 아니라 bash 스크립트가 성공적으로 실행되었는지 확인하고 싶었습니다!

를 함수 를 bash 명령함안에감싼다음호다니함습출했라고 main_function파일에 티 출력을 표시합니다.그 후에 다음을 사용하여 출력을 캡처했습니다.if [ $? -eq 0 ].

#! /bin/sh -

main_function() {
 python command.py
}

main_function > >(tee -a "/var/www/logs/output.txt") 2>&1

if [ $? -eq 0 ]
then
    echo 'Success!'
else
    echo 'Failure!'
fi

언급URL : https://stackoverflow.com/questions/314675/how-to-redirect-output-of-an-entire-shell-script-within-the-script-itself

반응형