Это потому, что элементы конвейера выполняются параллельно и потому что echo
справа не ожидает триггера;он не ждет ввода перед выполнением действия вывода.
Если мы сделаем это так:
( echo "1" > file ) | ( read; echo "2" > file)
, тогда мы получим 2
в файле. Второй конвейерный элемент имеет read
, который блокируется до тех пор, пока не получит ввод, или индикация окончания ввода. Таким образом, элемент конвейера приостанавливается в read
, пока не выйдет левый echo
. Затем он выполняет echo "2" > file
, который предсказуемо перезаписывает 1
. К тому времени левый echo
больше не работает, поэтому гонка разрешена.
Кстати, нам не нужны скобки в нижнем регистре в исходной версии. Это эквивалентно:
echo "1" > file | echo "2" > file
и моя измененная версия может быть:
echo "1" > file | ( read; echo "2" > file)