Подтвердить что ты не робот

Как отличает STDERR.puts от puts в Ruby?

Я изучаю язык программирования Programming Ruby 1.9, и они забрасывают STDERR.puts в блок кода в начале книги, не объясняя, почему они используют его или как он отличается от puts.

Я придумал этот термин, но все, что я могу извлечь из своих исследований, заключается в том, что он связан с диагностикой. Нигде в коде, предоставленном Programming Ruby, похоже, есть ссылка на обработку исключений ошибок.

Вот код.

require_relative 'csv_reader'
reader = CsvReader.new
ARGV.each do |csv_file_name|
  STDERR.puts "Processing #{csv_file_name}"
  reader.read_in_csv_data(csv_file_name)
end

Мне удалось где-то прочитать, что STDERR.puts используется для обработки ошибок вне соглашения, но я думаю, что я спрашиваю, действует ли он иначе, чем puts.

4b9b3361

Ответ 1

По умолчанию puts записывается в STDOUT. Указав STDERR.puts, вы отправляете свой вывод в дескриптор STDERR. Хотя поведение реализации одинаково, использование STDERR вместо STDOUT, безусловно, повлияет на потребителей вашей программы, поскольку они будут пытаться захватить вывод из вашей программы из STDOUT, по соглашению. Лучшей практикой является регистрация информации отладки, ошибок, предупреждений, статуса и т.д. До STDERR и фактического выхода программы в STDOUT.

Ответ 2

В системе, основанной на * nix при запуске нового процесса, по умолчанию будут иметься три открытых дескриптора файлов:

0 - STDIN
1 - STDOUT
2 - STDERR

Эти числа, вызывают их файловые дескрипторы, важны для оболочки unix, которую вы используете для запуска вашей программы. STDIN - это то, где ваша программа рассчитывает получить свой вход (обычно клавиатура, если вы не изменили ее). STDOUT - это то, где ваша программа будет писать свой вывод (обычно экран, если вы не изменили его), и STDERR - это то место, где он будет писать свои ошибки (снова обычно экран, если вы не изменили его).

Общее утверждение сверху - "Если вы его не изменили". Если вы выполните команду, подобную этой

command > file.out

Затем вывод (все, записанные в STDOUT) не будет отображаться на экране, он появится в файле file.out. Если вы запустите свою команду следующим образом

command 2> file.err

Затем ваш вывод снова появится на экране, но любые ошибки, записанные в STDERR, появятся в файле file.err. Фактически command > file.out действительно сокращается для command 1>file.out. Все, что относится к символу > (Перенаправление), также относится к | символ для трубопроводов. Это означает, что если вы запускаете свою программу в качестве фильтра, получая данные по STDIN и записывая в STDOUT, тогда другие программы могут получать свои данные из вашей программы, но они не будут получать данные, записанные в STDERR. (Если вы не попросили его)

Вы можете использовать обе эти команды вместе.

command 1> file.out 2> file.err  # Generally you would leave out the 1

В этом случае не удивительно, что вывод и ошибка будут в двух отдельных файлах. Bash также имеет понятие дублирования дескрипторов файлов. Это делается с помощью > & оператор. Следующая команда поместит оба STDOUT и STDERR в один и тот же файл.

command > file.out 2>&1

Эта команда говорит, что запускает команду setup STDOUT для перенаправления на file.out, затем дублирует ( > &) дескриптор файла 2 (STDERR), чтобы перейти туда, куда будет идти файл дескриптора 1 (file.out)

Вы должны быть немного осторожны с порядком использования этих аргументов. Сравните приведенное выше с этой командой.

command 2>&1 > file.out

Это имеет совершенно другой результат. Эта команда говорит, что запустите команду и дублируйте STDERR на STDOUT (в этот момент времени терминал) перенаправляет STDOUT в файл .out. Текст ошибки останется на экране.

Ответ 3

Каждая программа запускается с тремя стандартными дескрипторами файлов, когда они порождены: стандартный ввод, вывод и потоки ошибок.

Стандартный поток ввода - это общий поток, из которого следует считывать ввод программы. Аналогично, стандартный поток вывода представляет собой общий поток, к которому может быть записан выход программы. Итак, что такое стандартная ошибка?

Разница между стандартным выходом и стандартной ошибкой является тонкой, но чрезвычайно важной в системах UNIX из-за того, как программы используются вместе через каналы. Программы часто предназначены для использования в качестве входных данных других программ; это делается путем перенаправления стандартного вывода одной программы на стандартный ввод другого, часто через оператора трубы (|). Это оставляет стандартную ошибку, все еще связанную с терминалом. Пользователь может выбрать просмотр данных, отправленных в этот поток в самом терминале, или перенаправить его в файл журнала, или на /dev/null, все, что пожелает пользователь. Обратите внимание, что данные, отправленные на stderr, необязательно должны быть сообщениями об ошибках; это просто данные, которые отделены от фактического вывода программы.

Поддержка этой парадигмы чрезвычайно важна для удобства использования программ, поскольку она обеспечивает предсказуемый пользовательский интерфейс для ввода, вывода и сообщений программы. Пользователь может манипулировать ими по своему усмотрению, и часто интересные приложения возникают непредвиденным образом.

Итак, в общем случае стандартный вывод предназначен для фактического вывода, а стандартная ошибка - для связи с пользователем.