Чтобы ответить на первый вопрос более подробно: когда вы запускаете ls file{1..4}.txt 1>res.txt 2>res.txt
, он открывает res.txt дважды, независимо . Это означает, что каждый записывающий в него файловый дескриптор имеет разное представление о том, где он находится (его смещение или позиция) в файле.
Когда команда запускается, у вас есть пустой файл с двумя файловыми дескрипторами , оба из которых готовы к записи в начало файла. Пока все хорошо.
ls
затем выводит сообщения об ошибках на стандартный вывод, и они сохраняются в файле, начиная с самого начала. Мы все еще в порядке; файл выглядит так:
ls: cannot access 'file2.txt': No such file or directory
ls: cannot access 'file3.txt': No such file or directory
После этого ls
начинает записывать найденные файлы в стандартный вывод. И здесь возникает проблема: дескриптор файла stdout все еще указывает на начало файла, поэтому он начинает перезаписывать файл с самого начала. Он записывает первое имя файла, давая:
file1.txtt access 'file2.txt': No such file or directory
ls: cannot access 'file3.txt': No such file or directory
Затем он записывает новую строку, которая заменяет "t" на "невозможно", давая:
file1.txt
access 'file2.txt': No such file or directory
ls: cannot access 'file3.txt': No such file or directory
Затем он записывает следующий имя файла, что дает:
file1.txt
file4.txtfile2.txt': No such file or directory
ls: cannot access 'file3.txt': No such file or directory
И затем последний символ новой строки, на этот раз над «f» в «file2»:
file1.txt
file4.txt
ile2.txt': No such file or directory
ls: cannot access 'file3.txt': No such file or directory
... и это конечный результат, который вы видите .
По сути, оба дескриптора пытаются одновременно изменить один и тот же файл, но не скоординированы должным образом (как если бы один был копией другого), поэтому они спотыкаются. друг друга.