명령 출력에 접두어를 붙이지만 반환 값을 확인할 수 있는 아래 코드보다 더 좋은 방법이 있습니까?
command > "$tmpfile" 2>&1
ret=$?
sed 's/^/ | /' "$tmpfile"
if [[ ! "$ret" -eq 0 ]]; then
rm "$tmpfile"
exit 1
fi
답변1
일부 다른 셸 의 경우 bash
이 옵션을 사용할 수 있습니다 pipefail
. 이 옵션을 사용하면 파이프의 종료 상태가 맨 오른쪽 구성 요소의 종료 상태가 아닌 실패한 가장 오른쪽 구성 요소의 종료 상태가 됩니다.
(set -o pipefail; cmd | sed 's/^/ | /') || exit
또 다른 옵션은 파이프를 사용하는 대신 stdout을 프로세스 교체로 리디렉션하는 것입니다.
cmd > >(sed 's/^/ | /') || exit
이 경우에는 백그라운드에서 시작되어 기다리지 않지만 sed
다음 명령이 실행될 때까지 쓰기가 완료되지 않았을 수 있습니다.
특히 파이프라인의 각 구성요소의 종료 상태를 기록하는 특수 배열(zsh에는 이에 상응하는 배열이 있음 ) bash
이 있습니다 .$PIPESTATUS
$pipestatus
cmd | sed 's/^/ | /'; ret=${PIPESTATUS[0]}
[ "$ret" -eq 0 ] || exit "$ret"
POSIXly에서는 다음과 같이 할 수 있습니다.
{
ret=$(
exec 4>&1
{
cmd 3>&- 4>&-
echo "$?" >&4
} | sed 's/^/ | /' >&3 3>&- 4>&-
)
} 3>&1
[ "$ret" -eq 0 ] || exit "$ret"
도우미 기능을 사용할 수 있습니다.
prefix() (
prefix=$1; shift
exit "$(
exec 4>&1
{
"$@" 3>&- 4>&-
echo "$?" >&4 3>&- 4>&-
} | PREFIX=$prefix awk '{print ENVIRON["PREFIX"] $0}' >&3 3>&- 4>&-
)"
) 3>&1
prefix ' | ' cmd
awk
( 임의의 접두사를 사용할 수 있도록 전환됩니다 .