Как определить, находятся ли cout и cerr в одном месте? - PullRequest
4 голосов
/ 26 июня 2019

Есть ли способ в C ++, чтобы сказать, указывают ли std :: cout и std :: cerr на одно и то же место назначения?

То есть я хотел бы иметь возможность различать, когда программазапускается как

program или program > log 2>&1 или program &> log

против

program > log или program 2> errors или program > log 2> errors

(Вариант использования - это ситуация, когда мы хотели бы, чтобы информация об ошибках выводилась на stdout и stderr, когда они разделены, но мы хотим вывести вывод в несколько отличном формате (не просто конкатенацию), если они оба переходят ктот же пункт назначения. - Да, я знаю, что это не идеально, и не является официально рекомендованным способом делать вещи, и его не следует рассматривать как стандартный способ делать вещи. Но, пожалуйста, просто поверьте мне,тем не менее, что мы потратили время на то, чтобы все обдумать, и для нашего конкретного варианта использования это лучший вариант.)

Для наших целей мы можем предположить, что ничего не было сделано с помощью cout /перенаправление cerr внутри самой программы (простоl перенаправление командной строки на уровне оболочки), поэтому, если есть функциональность уровня C, которая смотрит непосредственно на stdout / stderr (а не на потоки std :: cout и std :: cerr), это, вероятно, тоже будет работать.

Ответы [ 2 ]

0 голосов
/ 26 июня 2019

Если вы действительно хотите узнать о linux , /proc/self/fd раскроет все! Попробуйте ls -l /proc/self/fd сегодня ...

Кроме того, если вы действительно хотите выдать ошибку на консоль, определив, что перенаправления украли ваш вывод, вы всегда можете отправить ее на /dev/tty. Не беспокойтесь о /dev/stderr, так как это просто ссылка на /proc/self/fd/2! Единственная проблема, связанная с этим, заключается в том, что если ваша программа отсоединена от консоли с hup или аналогичной, то вы не можете использовать /dev/tty, очевидно.

0 голосов
/ 26 июня 2019

Это еще один случай проблемы XY .

Что вы действительно пытаетесь достичь:

Для наших вариантов использования для конечного пользователя:мы хотим быть уверены, что сообщения, указывающие, какая ошибка произошла, заканчиваются как в stderr, так и в stdout (потому что в зависимости от того, как наши пользователи настроили или не настроили перенаправление вывода, они могут видеть или не видеть его в одном или другом). Мы могли быпросто распечатывайте вещи по одному разу (фактически то, что мы делаем в настоящее время), но если stdout и stderr идут в одно и то же место, было бы понятнее и удобнее для пользователя, если бы мы могли переформатировать вещи, чтобы удалить избыточную печать.

Принимая во внимание эту цель, более понятный механизм позволил бы пользователю указать, куда он хотел бы отправлять сообщения об ошибках.Например,

the-program --error-destination "stdout"
the-program --error-destination "stderr"
the-program --error-destination "stdout,stderr"
the-program --error-destination "/tmp/errro-messages.txt"
the-program --error-destination "stdout,/tmp/errro-messages.txt"

С пониманием, что "stdout" и "stderr" являются особыми направлениями.Все остальное - файл.

...