단일 출력을 터미널에 쓰고 다른 모든 것을 파일로 보냅니다.

단일 출력을 터미널에 쓰고 다른 모든 것을 파일로 보냅니다.

나는 exec스크립트의 모든 출력을 파일로 보내는 데 사용합니다 exec > file.errout 2>&1. 그러나 스크립트 중간에 터미널과 파일에 여러 메시지를 보내고 싶습니다. 이 코드를 찾았어요여기, 그러나 각 터미널 메시지의 양쪽에 두 줄의 코드를 추가하고 다음에 파이핑해야 합니다 tee.

exec > file.errout 2>&1
...
echo "messages only directed to the file"
...
exec >/dev/tty
echo "message i want directed to the terminal" | tee file.errout
exec > file.errout 2>&1
...
echo "more messages only directed to the file"
...

이 작업을 수행하는 더 쉬운 방법이 있나요?

답변1

이렇게 할 필요는 없습니다. 다음을 사용하여 모든 표준 출력 내용을 파일 에 넣은 exectee/dev/tty

exec > file.errout 2>&1

echo "messages only directed to the file"

{
    echo "message i want directed to the terminal and file" ;
    echo "more more message i want directed to the terminal and file" ;
} | tee /dev/tty

echo "more messages only directed to the file"

exec >/dev/tty초기 exec라인에서 모든 표준 출력이 이미 파일에 기록되어 있으므로 매번 이 작업을 수행 할 필요는 없습니다 .

답변2

Bash와 zsh에서는 다음과 같이 시도해 볼 수 있습니다.

exec >file.errout 2>&1
  # ...
exec {foo}>&1 > >(tee /dev/tty) 2>&1   # temporarily redirect
echo bla
ls no_such_file
exec >&$foo 2>&1                       # restore
  # ... 

Redirect exec {var}>&1 ... exec >&$var/restore는 비슷합니다 . 단, bash 자체는 코드의 나머지 부분과 충돌할 수 있는 고정 숫자를 사용하는 대신 exec 7>&1 .. exec >&7사용되지 않는 파일 설명자를 가져와 변수에 저장합니다 . $var이러한 형태의 리디렉션은 ksh 확장이며 bash 및 zsh에서도 지원됩니다.

리디렉션 exec > >(...)+ 프로세스 교체 조합은 유용하지만 몇 가지 단점과 버그가 있습니다(ksh93에서는 작동하지 않을 수 있음).


물론 {...}블록의 명령을 그룹화하고 전체 블록의 출력을 파이프로 리디렉션할 수 있습니다 | tee /dev/tty. 이것은 가장 간단하고 이식성이 뛰어납니다.

문제는 모든 변수 할당이 기본 스크립트가 아닌 하위 쉘에서 발생한다는 것입니다.

a=before
{
   a=$(pwd)
   # ...
} | tee /dev/tty
echo "$a"  #  still "before"  

관련 정보