Я сомневаюсь, что это поведение предсказуемо (и, конечно, не будет зависеть от этого). Команда tee
вероятно, запускает новый процесс для отправки своего ввода в «другое» место назначения. Операционная система будет «буферизовать» выходные данные до тех пор, пока не достигнет точки, в которой будет создан целевой файл и записан в него временный буфер. Точный момент, когда это происходит (и перезаписывает источник), вероятно, зависит от:
- Размер файла и доступная память для буфера
- Прошедшее время
- Если вход от трубы до
tee
заканчивается
Это идет глубже, чем bash
: так работает программа, которая запускает bash
. Оболочка просто интерпретирует введенные вами команды и запускает программы, необходимые для выполнения команд. Оболочка не имеет никакого контроля над тем, как работает каждая программа, и еще меньше - как эти программы взаимодействуют. Пользователь просит программу (или набор программ) взять данные из входного файла и записать результат в один и тот же входной файл в одном предложении.
Не забывайте, что bash - это просто интерпретатор пользовательских команд: это всего лишь shell
операционной системы для преобразования намерений пользователя в системные вызовы.
И это тоже задокументировано ! Или это письмо, которое решает подобные проблемы. Или этот поток StackOverflow. Или этот поток Serverfault.
Обратите внимание, что это также может произойти с перенаправлением stdin
: если вы берете команды ввода из файла: $ myprog < commandfile
. Если myprog
пишет в командный файл, нет гарантии, что все команды commandfile
будут выполнены.
Действительно простая аналогия была бы чем-то вроде этого списка инструкций:
- Execute the instructions step by step
- Dip this instruction list in a bucket of black paint
- Type in the following commands:
find /etc -type f -exec cat '{}' \; | tr -c '.[:digit:]' '\n' \
| grep '^[^.][^.]*\.[^.][^.]*\.[^.][^.]*\.[^.][^.]*$'
Я полагаю, вы сделали бы копию в первую очередь? (команда взята из Advanced Bash-Scripting Guide)