Sample Header Ad - 728x90

Why does MacOS always append to a redirected file descriptor even when told to overwrite? Ubuntu only appends when strictly told to append

7 votes
1 answer
1396 views
**Given the following code:**
bash
out="$(mktemp)"
rm -f "$out"
clear

printf '%s\n' 0 >"$out"
{
	printf '%s\n' '1' >/dev/stdout
	printf '%s\n' '2' >/dev/stdout
} >"$out"
cat -e -- "$out"
rm -f "$out"
On Ubuntu this outputs:
2$
On MacOS this outputs:
1$
2$
**When explicitly appending, they behave consistently:**
bash
out="$(mktemp)"
rm -f "$out"
clear

printf '%s\n' 0 >"$out"
{
	printf '%s\n' '1' >/dev/stdout
	printf '%s\n' '2' >>/dev/stdout
} >"$out"
cat -e -- "$out"
rm -f "$out"
On MacOS and Ubuntu this outputs:
1$
2$
**The most confusing example to me is this one:**
bash
out="$(mktemp)"
rm -f "$out"
clear

printf '%s\n' 0 >"$out"
exec 3>>"$out"
{
	printf '%s\n' '1' >/dev/stdout
	printf '%s\n' '2' >/dev/stdout
} >&3
{
	printf '%s\n' '3' >/dev/stdout
	printf '%s\n' '4' >/dev/stdout
} >&3
cat -e -- "$out"
rm -f "$out"
exec 3>&-
Which on MacOS outputs:
0$
1$
2$
3$
4$
Which on Ubuntu outputs:
4$
I was expecting this on Ubuntu:
0$
2$
4$
--- I am thoroughly confused why this behaviour occurs, in this example, and [all the other examples I've devised to illustrate this discrepancy.](https://gist.github.com/balupton/cd779f3a39507f75d5956a67e5543ab8) My questions: - What is this descrepancy? What is happening? Is this descrepancy intentional? - Where else does this descrepancy apply? What is its origins? - If this descrepancy is intentional, why was it justified? Which one should be the correct behaviour? - What can be done to mitigate these differences when writing cross-OS scripts? - Is shopt -o noclobber the appropriate response? Is this the true necessity of noclobber?
Asked by balupton (634 rep)
Feb 11, 2025, 08:17 PM
Last activity: Feb 14, 2025, 08:18 AM