РЕДАКТИРОВАТЬ
Пожалуйста, просмотрите не только принятый ответ, но и другие.
Вопрос
Почему перенаправление STDOUT и STDERR в один и тот же файл не работает, хотя выглядит так же, как 1>[FILENAME] 2>&1 ?
Вот пример:
perl -e 'print "1\n" ; warn "2\n";' 1>a.txt 2>a.txt
cat a.txt
# outputs '1' only.
Ну, почему? Я думал, что это работает, потому что... STDOUT перенаправляется в a.txt, как и STDERR. Что случилось с STDERR?
решение1
Оба ваших перенаправления обрезают файл, поэтому второе (в хронологическом порядке выполнения) перезапишет первое. Попробуйте
rm a.txt ; touch a.txt ; perl -e 'print "1\n" ; warn "2\n";' 1>>a.txt 2>>a.txt
Или просто используйте тот же дескриптор файла
perl -e 'print "1\n" ; warn "2\n";' 1>a.txt 2>&1
решение2
При этом 1>a.txt 2>&1
дескриптор файла №1 равендублированныйк № 2. Они оба ссылаются на один и тот же «открытый файл», и оба имеют общую текущую позицию и режим чтения/записи. (На самом деле нет никакой разницы между использованием 2>&1 и 2<&1.)
При использовании 1>a.txt 2>a.txt
оба файловых дескриптора являютсяоткрылся независимои имеют отдельные позиции курсора. (Файл также усекается дважды.) Если вы напишете «Hello» в fd #1, его позиция переместится на байт 5, но fd #2 останется на байте 0. Печать в fd #2 просто перезапишет данные, начиная с 0.
Это легко увидеть, если вторая запись короче:
$ perl -e 'STDOUT->print("abcdefg\n"); STDOUT->flush; STDERR->print("123");' >a.txt 2>a.txt
$ cat a.txt
123defg
Обратите внимание, что Perl имеет внутреннюю буферизацию, поэтому в этом примере явный flush() необходим для того, чтобы гарантировать, что данные fd #1 будут записаны до данных fd #2. В противном случае потоки будут сброшены в непредсказуемом порядке при выходе.
Для сравнения, если дескрипторы файлов являются общими, записи просто следуют друг за другом:
$ perl -e 'STDOUT->print("abcdefg\n"); STDOUT->flush; STDERR->print("123");' >a.txt 2>&1
$ cat a.txt
abcdefg
123