Я начинаю в пустой директории.
$ touch aFile
$ ls
aFile
Тогда у меня есть ls
два аргумента, один из которых отсутствует в этом каталоге. Я перенаправляю оба выходных потока в файл с именем output
. Я использую >>
, чтобы не писать одновременно.
$ ls aFile not_exist >>output 2>>output
$ cat output
ls: cannot access 'not_exist': No such file or directory
aFile
Который, кажется, работает. Есть ли опасность для этого подхода?
io-redirection
stdout
stderr
exit_status
источник
источник
ls aFile not_exist &>>output
здесь? (Обратите внимание, я предполагаю, что вы используете Bash .)&>>
НЕ является стандартным. Это УСТАРЕВШИЙ, неоднозначный синтаксис, который по-разному работает в разных оболочках. Интересно, откуда вы, ребята, берете свои вещи?ls &>>foo ...
должны быть разобраны как два comandsls &
и>>foo ...
, и это путь , другие оболочки вроде/bin/sh
с Ubuntu разбирает его. Поскольку это устарело, вы можете посмотреть здесь - хотя я не претендую на то, что это какой-то авторитет. Вы можете спроситьbash
сопровождающих, считают ли они, что это хорошая идея.Ответы:
Нет, это не так безопасно, как стандарт
>>bar 2>&1
.Когда пишешь
вы
bar
дважды открываете файлO_APPEND
, создавая два полностью независимых файловых объекта [1], каждый со своим собственным состоянием (указатель, режимы открытия и т. д.).Это очень отличается от того,
2>&1
который просто вызываетdup(2)
системный вызов, и делает взаимозаменяемыми псевдонимы stderr и stdout для одного и того же файлового объекта.Теперь есть проблема с этим:
Обычно вы можете рассчитывать на вероятности файла , как
bar
вfoo >>bar 2>&1
записываются одновременно с двух разных мест , являющихся довольно низкими. Но по вашему,>>bar 2>>bar
вы только что увеличили его на десятки порядков без всякой причины.[1] «Открытые описания файлов» на языке POSIX.
источник
O_APPEND
в любом случае это своего рода обман - довольно обременительно для правильной реализации.O_APPEND
, клиент сначала извлекает «реальный» размер файла с сервера («повторно проверяет» индекс), а затем выполняет обновление индексируемого поиска + запись +, и только последняя часть сделано под блокировками, что означает, что первая часть может все еще получить устаревший размер с сервера и переопределить правильный размер из локального / кэшированного индекса. Та же проблема сlseek(SEEK_END)
.Что происходит, когда вы делаете
это
file
будет открыто для добавления дважды. Это безопасно делать в файловой системе POSIX. Любая запись, которая происходит с файлом, когда он открывается для добавления, будет происходить в конце файла, независимо от того, поступают ли данные через стандартный поток вывода или стандартный поток ошибок.Это опирается на поддержку атомарных операций записи в основной файловой системе. Некоторые файловые системы, такие как NFS, не поддерживают атомарное добавление. См., Например, вопрос «Является ли добавление файла атомарным в UNIX?» В StackOverflow.
С помощью
будет работать даже на NFS, хотя.
Однако, используя
небезопасно, так как оболочка будет усекать выходной файл (дважды), и любая запись, происходящая в любом потоке, будет перезаписывать данные, уже записанные другим потоком.
Пример:
hello
Строка записывается первым (с оконечным новой строки), а затем строка сabc
последующим переводом строки записывается из стандартной ошибки, перезаписыванияhell
. Результатом является строкаabc
с символом новой строки, за которым следуют то, что осталось от первогоecho
вывода, иo
и символ новой строки.Замена двух
echo
вокруг намотки производит толькоhello
в выходном файле, так как эта строка записывается последней и длиннееabc
строки. Порядок, в котором происходит перенаправление, не имеет значения.Было бы лучше и безопаснее использовать более идиоматический
источник
>>
взялась), где>>
открывался бы для записи и стремился к концу (я полагаю, потому что O_APPEND еще не был изобретен). Даже на Солярисе 10,/bin/sh -c '(echo a; echo b >&2) >> file 2>> file; cat file'
выходыb
.sh
или с ее файловой системой?>>
изначально делалось, оно не открывалось с O_APPEND, оно открывалось без и стремилось к концу. Это не столько проблема, это то, что он делал и был задокументирован.Это зависит от того, чего вы хотите достичь. Вам решать, нормально ли иметь ошибки в том же файле, что и выходные данные. Это просто сохранение текста в файле с функциональностью оболочки, которая позволяет вам перенаправлять по своему усмотрению. Нет абсолютного да или нет. Поскольку все в Linux это можно сделать несколькими способами, это мой способ.
ls notExistingFile existingFile >> output 2>&1
Ответить на вопрос: с точки зрения самого перенаправления, да, это совершенно безопасно.источник
>
вместо вместо>>
перезапишет некоторые символы. Так что не только оболочка позволяет мне перенаправлять, потому что когда я перенаправляю с>
, результат отличается. Так есть нюансы с>
, есть ли с>>
?>
- перезаписать.>>
- добавь