Skip to main content
5 of 18
Add missing word - "work"
Tom Hale
  • 33.3k
  • 42
  • 163
  • 257

The usual (1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ) trick to get the complete stdout of a command is to do:

output=$(cmd; ret=$?; echo .; exit "$ret")
ret=$?
output=${output%.}

The idea is to add and extra .\n. Command substitution will only strip that \n. And you strip the . with ${output%.}.

Note that in shells other than zsh, that will still not work if the output has NUL bytes. With yash, that won't work if the output is not text.

With bash and zsh, assuming the output has no NULs, you can also do:

IFS= read -rd '' output < <(cmd)

To get the exit status of cmd, you can do wait "$!"; ret=$? in bash but not in zsh.

Note that in some locales, it matters what character you use to insert at the end. . should generally be fine, but some other might not. For instance x (as used in some other answers) or @ would not work in a locale using the BIG5, GB18030 or BIG5HKSCS charsets. In those charsets, the encoding of a number of characters ends in the same byte as the encoding of x or @ (0x78, 0x40)

For instance, ū in BIG5HKSCS is 0x88 0x78 (and x is 0x78 like in ASCII, all charsets on a system must have the same encoding for all the characters of the portable character set which includes English letters, @ and .). So if cmd was printf '\x88' and we inserted x after it, ${output%x} would fail to strip that x as $output would actually contain ū.

For completeness, note that rc/es/akanga have an operator for that. In them, command substitution, expressed as `cmd (or `{cmd} for more complex commands) returns a list (by splitting on $ifs, space-tab-newline by default). In those shells (as opposed to Bourne-like shells), the stripping of newline is only done as part of that $ifs splitting. So you can either empty $ifs or use the ``(seps){cmd} form where you specify the separators:

ifs = ''; output = `cmd

or:

output = ``()cmd

In any case, the exit status of the command is lost. You'd need to embed it in the output and extract it afterwards which would become ugly.

Stéphane Chazelas
  • 584.8k
  • 96
  • 1.1k
  • 1.7k