명령이 성공한 경우에만 출력을 억제하려면 어떻게 해야 합니까?

명령이 성공한 경우에만 출력을 억제하려면 어떻게 해야 합니까?

일반적으로 성공하는 도우미 명령의 출력을 억제하여 스크립트 출력을 단순화하고 싶습니다.

그러나 -q가끔 실패할 경우 이를 사용하면 출력이 숨겨지므로 오류를 이해할 수 없습니다. 또한 이러한 명령은 출력을 stderr.

명령 출력을 억제하는 방법이 있습니까?성공하는 한?

예를 들어(그러나 이에 국한되지는 않음) 다음과 같습니다.

mycommand | fingerscrossed

모든 것이 순조롭게 진행되면 fingerscrossed출력을 캡처하여 폐기합니다. 그렇지 않으면 표준 또는 오류 출력(무엇이든)에 반영됩니다.

답변1

moreutils' chronic명령은 다음을 수행합니다.

chronic mycommand

출력은 실패하지 않는 한 삼켜지며 mycommand, 실패하는 경우 출력이 표시됩니다.

답변2

방금 이 간단한 답변을 찾았습니다.이것은 또 다른 질문입니다:

output=`mycommand 2>&1` || echo $output

기적적으로 작동합니다!

답변3

### do this bit once at the top of your script
divert=
exec 3<>"${divert:=$(mktmp)}" 4<>/dev/null
rm -- "$divert"; unset divert
### then do this bit as often as needed
command >&3 2>&3
cat <&3 >&"$(((RTN=$?)?2:4))"

이것은 트릭을 수행해야합니다. 각 출력을 버퍼링합니다.command삭제된 임시 파일에 저장한 다음 /dev/null반환 상태가 0이 아닌지에 따라 출력을 stderr로 사이펀합니다. 임시 파일은 조기에 삭제되므로 현재 셸과 하위 프로세스의 파일 설명자를 제외한 모든 프로세스에서 읽을 수 없습니다.( /proc/$pid/fd적절한 권한이 있는 경우 스누핑이 없습니다), 완료 후 정리가 필요하지 않습니다.

Linux 시스템에는 더 편리한 솔루션이 있을 수 있습니다.

divert(){
    "$@" >&3 2>&3 ||
    eval "cat <&3
          return $?"
}   3<<"" 3<>/dev/fd/3

...대부분의 쉘에서는 다음과 같이 호출한다는 점을 제외하면 다른 쉘과 매우 유사하게 작동합니다 divert some simple-command with args. "$@", 그러나 for dash, 또는 여기에서 문서를 실행하기 위해 파이프를 사용하는 다른 셸 의 높은 출력 명령에 유의하세요 yash. 해당 셸에서는 파이프 버퍼가 채워질 수 있다고 생각합니다.(Linux의 기본값은 약 128kb입니다.)교착상태입니다. 그러나 이것은 ksh, mksh, , 또는 Bourne 쉘의 bash문제가 되어서는 안 됩니다 zsh. 모두 위에서 명시적으로 수행한 것과 기본적으로 동일합니다 exec.

답변4

나만의 만성질환 만들기

my_chronic() {
  tmp=$(mktemp) || return # this will be the temp file w/ the output
  "$@"  > "$tmp" 2>&1 # this should run the command, respecting all arguments
  ret=$?
  [ "$ret" -eq 0 ] || cat "$tmp"  # if $? (the return of the last run command) is not zero, cat the temp file
  rm -f "$tmp"
  return "$ret" # return the exit status of the command
}

관련 정보