다음을 사용하여 스크립트 내부의 스크립트 출력을 로그 파일로 리디렉션할 수 있습니다 exec
.
#!/bin/bash
exec > stdout.log 2>&1
echo hello world
less
파일 대신 출력을 리디렉션할 수 있습니까 ? 나는 노력했다
#!/bin/bash
exec > >(less) 2>&1
# output some text
for (( i=1; i <= 500; i++ )); do echo "hello world $i"; done
하지만 이상한 방식으로 실패합니다. 프롬프트가 덜 표시되지만 터미널로 다시 돌아오게 됩니다.
이를 스크립트 시작 부분에 설정하고 싶습니다(매개변수, tty 등에 따라 조건부로 설정될 수 있음).
답변1
스크립트가 less
하위 프로세스를 기다리도록 해야 합니다. 그렇지 않으면 스크립트가 종료되기 전에 종료되어 less
갑자기 포그라운드 프로세스 그룹 외부에 있게 되어 더 이상 터미널에서 명령을 읽거나 터미널 설정을 복원할 수 없게 됩니다.
또한 입력이 완료될 때까지 영원히 기다리지 않으려면 less
스크립트가 파이프를 닫아야 합니다.
이 모든 것을 종합하면 다음과 같습니다.
exec > >(less) 2>&1
trap 'exec >&- 2>&-; wait' EXIT
# >&- 2>&- => close stdout and stderr => cause EOF on less' stdin
seq 1 50000
# the rest of your script
그러나 이것은 그다지 좋지 않고 대부분의 다른 쉘로 이식 가능하지 않으며 문서화되지 않은 (신뢰할 수 없는) bash 동작에 의존합니다. wait
스크립트에 둘 이상이 있으면 exec > >(...)
작동하지 않으며 대기합니다. 다른 백그라운드 프로세스는 로 시작됩니다 &
.
더 좋은 아이디어는 무한 재귀를 피하기 위해 환경 변수를 사용하여 스크립트 자체를 호출하는 것입니다.
if [ ! "$CALLED_MYSELF" ]; then
set -o pipefail # supported in bash, but not in all the shells
CALLED_MYSELF=1 "$0" "$@" 2>&1 | less
exit
fi
seq 1 50000
# the rest of your script
답변2
다음을 시도해 보십시오( 줄 제외 exec
).
for (( i=1; i <= 500; i++ )); do echo "hello world $i"; done | less
(고쳐 쓰다)
전체 스크립트를 포함하려면 스크립트를 다음과 같이 래핑하면 됩니다.{ ... }
#!/bin/bash
{
# output some text
for (( i=1; i <= 500; i++)) do echo "hello world $i"; done
# whatever output you want...
} | less