Quoting a command substitution preserves embedded newlines from word splitting, but it does not restore final newlines removed by the substitution itself. Use a file or direct stream when the exact ending bytes matter.
Reproduce in an empty temporary directory
This isolated example creates only fixture data in its working directory or runs local JavaScript. Run it separately from your project so the named files cannot overwrite real work.
printf 'alpha\n\n' > original.txt
captured=$(cat original.txt)
printf '%s' "$captured" > captured.txt
printf 'original bytes: '; wc -c < original.txt
printf 'captured bytes: '; wc -c < captured.txt
cat original.txt > streamed.txt
cmp original.txt streamed.txt
test "$(wc -c < captured.txt | tr -d ' ')" = 5Observed local output
original bytes: 7
captured bytes: 5What to compare
The fixture writes seven bytes, captures five, and preserves all seven through the direct file copy. Both ending newline characters disappear from the variable. This is different from losing line breaks because an unquoted expansion was split into words. Inspect a byte count or a hex dump instead of judging the result by the terminal prompt position.
Choose the next action
Keep exact document, checksum input or generated file content in a file and pass the filename to the next tool. If the consumer reads standard input, connect the stream directly rather than storing it in a shell variable first. If you deliberately want one logical text value without record terminators, command substitution is useful; document that contract and print with an explicit format. Adding one newline later is only correct if the contract requires exactly one, not an unknown number.
Limits and verification
Bash variables are not a general binary container and cannot represent embedded NUL bytes. A sentinel workaround for trailing newlines still needs deliberate status handling and does not solve that binary limitation. This isolated fixture demonstrates the ending-byte boundary with Bash on macOS; it does not validate a remote command or transport.
Related: Bash Read Skips the Last Line: Preserve a Partial Record at EOF.
Isolated example executed on macOS on November 10, 2026 (KST), using Bash 3.2, Python 3 for the byte fixture, and Node v26.5.0. Results describe the example, not your application or every runtime version.