8

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

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

7 ответов7

14

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

$ ./somecommad 2>&1 | less

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

7

Может быть

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, вам нужно другое решение.

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

1

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

 make 2>&1 | less
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 в стандартный процесс следующего процесса. Они часто не имеют смысла для следующего приложения и не должны быть скрыты от пользователя.

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

find /etc 2>&1 | less

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

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

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

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

0

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

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .