Skip to main content
We’ve updated our Terms of Service. A new AI Addendum clarifies how Stack Overflow utilizes AI interactions.
added 15 characters in body
Source Link
Stéphane Chazelas
  • 586k
  • 96
  • 1.1k
  • 1.7k

chronic from moreutils does almost what you want:

chronic cmd

Will discard cmd's stdout and stderr unless cmd fails or is killed, in which case chronic displayswrites the stdout output followed byon stdout and then the stderr output on stderr which it has saved in memory.

chronic is written in perl which can deal with arbitrary data and can read from two streams independently. Shells other than zsh on the other hand cannot store arbitrary output in their variables as they choke or NUL characters. Also, command substitution, even in zsh, strips trailing newline characters.

Here, you can still use a temp filesfile and remove most of the problems associated with it if you delete it from the start. (that's what most shells do for their here-documents for instance):

#! /bin/bash -
set -o nounset -o errexit -o pipefail

tmp=$(mktemp)
exec 3>&2 2> "$tmp" 4< "$tmp"
rm -f -- "$tmp"
trap '[ "$?" -eq 0 ] || cat <&4 >&3' EXIT

cmd1
cmd2

chronic from moreutils does almost what you want:

chronic cmd

Will discard cmd's stdout and stderr unless cmd fails or is killed, in which case chronic displays the stdout output followed by the stderr output which it has saved in memory.

Shells other than zsh cannot store arbitrary output as they choke or NUL characters. Also, command substitution, even in zsh, strips trailing newline characters.

Here, you can still use a temp files and remove most of the problems associated with it if you delete it from the start.

#! /bin/bash -
set -o nounset -o errexit -o pipefail

tmp=$(mktemp)
exec 3>&2 2> "$tmp" 4< "$tmp"
rm -f -- "$tmp"
trap '[ "$?" -eq 0 ] || cat <&4 >&3' EXIT

cmd1
cmd2

chronic from moreutils does almost what you want:

chronic cmd

Will discard cmd's stdout and stderr unless cmd fails or is killed, in which case chronic writes the stdout output on stdout and then the stderr output on stderr which it has saved in memory.

chronic is written in perl which can deal with arbitrary data and can read from two streams independently. Shells other than zsh on the other hand cannot store arbitrary output in their variables as they choke or NUL characters. Also, command substitution, even in zsh, strips trailing newline characters.

Here, you can still use a temp file and remove most of the problems associated with it if you delete it from the start (that's what most shells do for their here-documents for instance):

#! /bin/bash -
set -o nounset -o errexit -o pipefail

tmp=$(mktemp)
exec 3>&2 2> "$tmp" 4< "$tmp"
rm -f -- "$tmp"
trap '[ "$?" -eq 0 ] || cat <&4 >&3' EXIT

cmd1
cmd2
deleted 9 characters in body
Source Link
Stéphane Chazelas
  • 586k
  • 96
  • 1.1k
  • 1.7k

chronic from moreutils does almost what you want:

chronic cmd

Will discard cmd's stdout and stderr unless cmd fails or is killed, in which case chronic displays the stdout output followed by the stderr output which it has saved in memory.

Shells other than zsh cannot store arbitrary output as they choke or NUL characters. Also, command substitution, even in zsh, strips trailing newline characters.

Here, you can still use a temp files and remove most of the problems associated with it if you delete it from the start.

#! /bin/bash -
set -o nounset -o errexit -o pipefail

tmp=$(mktemp)
exec 3>3>&2 2> "$tmp" 4< "$tmp"
rm -f -- "$tmp"
trap 'cat'[ <&4"$?" >&2'-eq EXIT

{
0 ] cmd1
|| cat cmd2
<&4 >&3' ...EXIT
} 2>&3 3>&- 4<&-
cmd1
cmd2

chronic from moreutils does almost what you want:

chronic cmd

Will discard cmd's stdout and stderr unless cmd fails or is killed, in which case chronic displays the stdout output followed by the stderr output which it has saved in memory.

Shells other than zsh cannot store arbitrary output as they choke or NUL characters. Also, command substitution, even in zsh, strips trailing newline characters.

Here, you can still use a temp files and remove most of the problems associated with it if you delete it from the start.

#! /bin/bash -
set -o nounset -o errexit -o pipefail

tmp=$(mktemp)
exec 3> "$tmp" 4< "$tmp"
rm -f -- "$tmp"
trap 'cat <&4 >&2' EXIT

{
  cmd1
  cmd2
  ...
} 2>&3 3>&- 4<&-

chronic from moreutils does almost what you want:

chronic cmd

Will discard cmd's stdout and stderr unless cmd fails or is killed, in which case chronic displays the stdout output followed by the stderr output which it has saved in memory.

Shells other than zsh cannot store arbitrary output as they choke or NUL characters. Also, command substitution, even in zsh, strips trailing newline characters.

Here, you can still use a temp files and remove most of the problems associated with it if you delete it from the start.

#! /bin/bash -
set -o nounset -o errexit -o pipefail

tmp=$(mktemp)
exec 3>&2 2> "$tmp" 4< "$tmp"
rm -f -- "$tmp"
trap '[ "$?" -eq 0 ] || cat <&4 >&3' EXIT

cmd1
cmd2
Source Link
Stéphane Chazelas
  • 586k
  • 96
  • 1.1k
  • 1.7k

chronic from moreutils does almost what you want:

chronic cmd

Will discard cmd's stdout and stderr unless cmd fails or is killed, in which case chronic displays the stdout output followed by the stderr output which it has saved in memory.

Shells other than zsh cannot store arbitrary output as they choke or NUL characters. Also, command substitution, even in zsh, strips trailing newline characters.

Here, you can still use a temp files and remove most of the problems associated with it if you delete it from the start.

#! /bin/bash -
set -o nounset -o errexit -o pipefail

tmp=$(mktemp)
exec 3> "$tmp" 4< "$tmp"
rm -f -- "$tmp"
trap 'cat <&4 >&2' EXIT

{
  cmd1
  cmd2
  ...
} 2>&3 3>&- 4<&-