내 목표는 명령을 호출하고 변수에서 stderr을 가져오되 화면에는 stdout(및 stdout만)을 유지하는 것입니다. 예, 그것은 대부분의 사람들이 하는 것과 반대입니다 :)
현재 내가 가진 최고는 다음과 같습니다.
#!/bin/bash
pull=$(sudo ./pull "${TAG}" 2>&1)
pull_code=$?
if [[ ! "${pull_code}" -eq 0 ]]; then
error "[${pull_code}] ${pull}"
exit "${E_PULL_FAILED}"
fi
echo "${pull}"
그러나 이는 성공 시와 명령이 완료된 후에만 표준 출력을 표시합니다. 표준 출력을 스트리밍하고 싶습니다. 이것이 가능합니까?
편집하다
@sebasth와 도움을 받아 감사드립니다.임시 파일 없이 STDERR 및 STDOUT을 다른 변수로 리디렉션, 나는 다음과 같이 씁니다.
#!/bin/bash
{
sudo ./pull "${TAG}" 2> /dev/fd/3
pull_code=$?
if [[ ! "${pull_code}" -eq 0 ]]; then
echo "[${pull_code}] $(cat<&3)"
exit "${E_PULL_FAILED}"
fi
} 3<<EOF
EOF
나는 이것이 실제로 "아름답지" 않다는 것을 인정하고, 까다로워 보이며, heredoc이 왜 필요한지 정말로 이해하지 못합니다...
이것이 이것을 달성하는 더 좋은 방법입니까?
답변1
그냥 사용:
{ err=$(cmd 2>&1 >&3 3>&-); } 3>&1
cmd
stdout을 변경하지 않고 stderr을 얻으려면 (여기서 fd 3을 사용하여)가져오다3>&1
명령 대체의 원본 stdout(복사본)( >&3
fd 2를 명령 대체에 의해 생성된 파이프로 리디렉션한 후 복원됨 2>&1
)).
답변2
아래 제공된 답변을 사용할 수 있습니다스티븐 차제라스약간의 수정: stderr를 리디렉션하고 명령 대체 없이 명령을 실행합니다.
{
command 2> /dev/fd/3
res=$?
err=$(cat<&3)
} 3<<EOF
EOF
printf 'stderr: %s\n' "$err"
의 출력은 command
일반적으로 stdout에 있고 stderr은 err
변수에 있습니다.
답변3
stderr을 캡처하는 명령으로 stdout과 stderr을 바꾸십시오.
pull=$(sudo ./pull "${TAG}" 3>&2 2>&1 1>&3)
그런 다음 stderr를 다시 stdout으로 리디렉션합니다.
{ pull=$(sudo ./pull "${TAG}" 3>&2 2>&1 1>&3; } 2>&1
설명하다:
명령의 표준 출력만 캡처할 때와 같은 방식으로:
var=$(cmd)
stderr에 대한 출력은 여전히 명령줄로 이동합니다. 두 채널을 교환하여 stderr만 캡처할 수 있습니다.
var=$(cmd 3>&2 2>&1 1>&3)
그런 다음 stderr를 다시 stdout으로 리디렉션합니다(출력이 있는 경우 표시하기 위해).
{ var=$(f 3>&2 2>&1 1>&3); } 2>&1
답변4
양쪽의 답변을 결합하세요출력을 화면 오버레이로 리디렉션하는 방법그리고bash 키워드(예: 시간)의 표준 오류를 캡처하는 방법은 무엇입니까?,나는 얻다
var=$( (cmd >/dev/tty) 2>&1)
내장된 함수나 키워드를 사용하지 않는 경우 다음과 같이 단순화할 수 있습니다.
var=$( cmd 2>&1 >/dev/tty )