명령이 성공한 경우에만 출력을 억제하려면 어떻게해야합니까? 보조 명령의 출력을 억제하여 스크립트 출력을

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

그러나 -q그것들을 사용 하면 때때로 실패 할 때 출력을 숨기므로 오류를 이해할 방법이 없습니다. 또한이 명령은 출력을에 로그온합니다 stderr.

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

예를 들면 다음과 같습니다 (단, 이에 한하지 않음).

mycommand | fingerscrossed

모든 것이 잘 진행 fingerscrossed되면 출력을 잡아서 버립니다. 그렇지 않으면 표준 또는 오류 출력 (무엇이든)에 반영됩니다.



답변

moreutilschronic명령은 다음을 수행합니다.

chronic mycommand

mycommand실패하지 않는 한 출력 을 삼켜 서 출력이 표시됩니다.


답변

### 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적절한 권한이있는 몰래 스 누프 제외) 끝날 때 정리할 필요가 없습니다.

아마도 리눅스 시스템에서보다 편리한 솔루션 일 것입니다 :

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

… 대부분의 쉘에서 다음과 같이 호출 할 수 있다는 점을 제외하면 다른 쉘과 매우 유사하게 작동합니다 divert some simple-command with args. 높은 출력 명령을 조심 "$@"하지만 위해 dash, yash또는 파이프 여기-문서를 할 다른 쉘 – 나는 파이프 버퍼 채우기 위해 그 껍질에 가능하다 생각 (linuxes에 주위의 1백28킬로바이트의 기본에서)을 하고 교착 상태 때문에 . 즉에 대한 걱정 안 ksh, mksh, bash, zsh불구 또는 Bourne 쉘 – 그 모두가 기본적으로 같은 일을 내가 명시 적으로 위처럼 exec.


답변

일반적으로 오류가 발생하면 명령이 메시지를 출력 stderr하므로 작업을 수행하기 위해stdout

mycommand > /dev/null

답변

자신의 만성을 만들기 위해

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
}

답변

내 makefile에서 이와 같은 작업을 수행합니다.

if (mycommand) &> mycommand.log; then
  echo success
else
  c=$?;
  echo;echo -e "Bad result from previous command, see mycommand.log for more details";echo;
  command_to_run_on_fail
  (exit $c)
fi

상황에 맞게 다음과 같이 할 수 있습니다.

if ! (mycommand) &> mycommand.log; then
  c=$?;
  cat mycommand.log
  rm mycommand.log
  (exit $c)
fi

따라서 “if”는 명령을 실행하고 출력을 mycommand.log로 파이프합니다. stdout vs stdout vs 무엇이든 잡아야하는 경우 파이프 명령 ‘&>’을 ‘>’로 변경해야 할 수도 있습니다. 명령이 실패하면 오류 코드를 캡처하고 mycommand.log의 내용을 인쇄하고 mycommand.log를 제거한 후 원래 오류 코드와 함께 리턴하십시오.

(exit $ c)가 없으면 ‘rm’명령이 반환 한 것과 일치하는 종료 코드와 함께 반환됩니다.

마지막으로, 하나의 라이너를 원한다면 이와 같은 것이 효과적입니다.

mycommand &> mycommand.log || cat mycommand.log; rm mycommand.log

답변

나는 이 다른 질문대해 훨씬 간단한 대답을 찾았습니다 .

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

매력처럼 작동합니다!