Linux меньше поведения и stderr

11

Я наблюдаю за выводом моей сложной команды less, проблема в том, что stderrтеряется. stderrстроки обычно перечисляются между stdoutстроками внутри less. Я хотел бы, чтобы они были напечатаны на консоли, и когда я выйду less, чтобы увидеть их там вместе.

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

haelix
источник
2
Вы говорите мне, как перенаправить stderr на stdout, но это не то, что я хотел. Я не хочу, чтобы stderr смешивался с stdout внутри меньше. Я хотел бы, чтобы stderr был в терминале, когда я выхожу меньше.
Если stderrперенаправлено на stdout, все выходные данные stderr будут смешаны с включенным обычным выходом stdout. Трубопровод этого выхода lessпокажет оба.
Какой-то программист чувак
Если я игнорирую «stderr, чтобы быть в терминале, когда я выхожу меньше», я предлагаю нажать Ctrl-L, lessчтобы перекрасить экран.
Камае

Ответы:

10

Может быть

command 2> command.err | less; cat command.err; rm command.err

добавление

Ниже следует разъяснение для людей, которые не читают внимательно вопрос и не читают поясняющий комментарий ОП выше.

Хейликс указал:

Строки stderr обычно выводятся в списке между строками stdout внутри менее

и, в комментарии для первых ответивших, написал:

Вы говорите мне, как перенаправить stderr на stdout, но это не то, что я хотел. Я не хочу, чтобы stderr смешивался с stdout внутри меньше. Я хотел бы, чтобы stderr был в терминале, когда я выхожу меньше

Проблема, вероятно, специфична для конкретной платформы, это то, что я испытывал на старых платформах Unix SVR4.

Если на таких платформах вы делаете что-то вроде

 find / ... | less

любые сообщения об ошибках (например, права доступа к каталогу) выглядят так, как показано ниже

 stdout line 1
 stdout line 2
 error message text
 stdout line 4

так что выходные строки скрыты сообщениями об ошибках.

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

Если вы делаете что-то вроде

  find / ... 2>&1 | less

Сообщения об ошибках смешиваются со стандартным выводом. Опять же, когда вы выходите меньше, экран пуст.

Если вы хотите сначала просмотреть только стандартный вывод в less, а затем просмотреть сообщения об ошибках после выхода из less, вам нужно другое решение.

Это то, что я неуверенно предлагал в своем оригинальном ответе из двух строк.

RedGrittyBrick
источник
Это фигня. Ответ Иоахима должен быть принят.
Ванильное лицо
2
@VanillaFace: я добавил несколько разъясняющих материалов в свой ответ.
RedGrittyBrick
16

Вы должны перенаправить stderrна stdout:

$ ./somecommad 2>&1 | less

Проверьте руководство для вашей оболочки (например man bash.)

Какой-то программист чувак
источник
1
Комментарий для новых читателей этого старого вопроса (не для Иоахима, в частности). Это то, что все думают с первого взгляда на вопрос. Но проблема более тонкая - см. Обсуждение в комментариях после ответа dmckee
RedGrittyBrick
Сокращение для 2> & 1 - | & . Таким образом, это может быть упрощено как$ ./somecommad |& less
Мелвин Авраам
1

просто скажите оболочке перенаправить fd 2 на fd 1 (stderr на stdout)

 make 2>&1 | less
jackdoe
источник
1

Одна вещь, которой до сих пор не хватало во всех ответах, это причина, почему это происходит. Проблема здесь заключается в некотором состязании между процессом, выводящим данные на терминал stderrи lessотображающим выходные данные stdoutна терминале. Если lessначинает отображаться после того, как все выходные данные stderrбыли распечатаны на терминале, то lessсохраните это, и вы увидите сообщения после выхода less. OTOH, если lessуже началось отображение материала, то сообщения об ошибках смешиваются с lessвыходными данными, и после lessвыходов ничего не сохраняется (потому что lessпросто сохраняет терминал, каким он был до его запуска, и ничего не знает о сообщениях об ошибках, появившихся между ними).

Вы можете легко это увидеть, если, например,

grep foo -r /etc | less

Все сообщения об ошибках «Отказано в доступе» смешиваются с lessвыводом, и после выхода ничего не будет. Если вы делаете

grep foo -r /etc | (sleep 10; less)

все (или, по крайней мере, большинство) сообщений об ошибках были напечатаны на терминале, прежде чем lessпоявится возможность отобразить вывод, и вы увидите сообщения об ошибках позже.

Конечно, обычно вы не хотите ждать 10 секунд перед тем, как начать less, но в Linux вы также можете указывать дробные значения времени ожидания, а при быстром запуске процессов часто чего-то sleep 0.1достаточно, чтобы избежать состояния гонки. (Но, конечно, если вы хотите или должны быть на самом деле в безопасности, используйте решение RedGrittyBrick).

Эльмар Цандер
источник
0

Вам необходимо понять понятие «файловые дескрипторы». Обычно приложение unix запускается с тремя специальными файловыми дескрипторами:

  • Стандартный ввод
  • Стандартный вывод
  • Стандартная ошибка

«Труба» |в оболочке соединяется stdoutот одного процесса с другим stdin.

Ошибки - по замыслу - не передаются stdinв следующем процессе. Они часто не имеют смысла для следующего приложения и не должны быть скрыты от пользователя.

Если вы хотите смешать ошибки в стандартный вывод, вы можете использовать, например 2>&1, который говорит, по существу, «добавить stderr в стандартный вывод». Например

find /etc 2>&1 | less

также должен включать вывод ошибок из недоступных файлов.

find /etc 2>&1 >/dev/null | less

даст вам только ошибки.

ВЫЙТИ - Anony-Mousse
источник
0

Я запутался в вашем вопросе, поскольку я могу сказать, что желаемое поведение по умолчанию.

Когда я использую

#include <stdio.h>

int main(int argc, char**argv){
  for (int j=0; j<10; ++j){
    fprintf( (j%2 ? stdout : stderr) , "%d\n" , j);
  }
  return 0;
}

чтобы получить простой тест,

$ ./testredirection | less

делает только то, что вы просите. Это я вижу

1
3
5
7
9
(END) 

в lessи

$ ./testredirection | less
0
2
4
6
8
$ 

когда я ухожу less

dmckee --- котенок экс-модератора
источник
Странно, но все не всегда так. Попробуйте с помощью script ( echo info ; echo error 1>&2) и повторите тест: обе строки передаются меньше.
cYrus
@cYrus: Это работает, как и ожидалось, для меня тоже. «Конечно, я попробовал на коробке Mac OS. Bash 3.2.17, меньше 394. Может быть, что-то конкретное linux. В любом случае подход RedGrittyBrick должен работать нормально.
dmckee --- котенок экс-модератора
Weird! Debian Squeeze / Bash 4.1.5 / Less 436
cYrus
Да, я открыл оболочку Scientific Linux 5.3 на работе и получил ожидаемое поведение с bash 3.0.15 и менее 382. Может ли там быть регресс?
dmckee --- котенок экс-модератора
Я не знаю, я думаю, что это просто вопрос буферизации.
cYrus
0

Я случайно столкнулся с этой проблемой в одном из моих Debian 5.0 недавно. например, ls abc | Чем меньше я нахожу, что сообщение об ошибке идет в меньше, что вопреки моим знаниям.

После некоторых попыток я обнаружил, что это просто что-то, связанное с экранными буферами. На самом деле stderr НЕ входит в меньшее. Вы можете использовать стрелки вверх или вниз (или j / k) для демонстрации.

Ягода
источник