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

3700
haelix

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

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

8
Вы говорите мне, как перенаправить stderr на stdout, но это не то, что я хотел. Я не хочу, чтобы stderr смешивался с stdout внутри меньше. Я хотел бы, чтобы stderr был в терминале, когда я выхожу меньше. 12 лет назад 1
Если `stderr` перенаправлен на` stdout`, весь вывод в `stderr` _will_ будет смешан с обычным выводом в` stdout`. Передача этого вывода в `less` покажет оба. Some programmer dude 12 лет назад 0
Если я игнорирую «stderr, чтобы быть в терминале, когда я выхожу меньше», я предлагаю нажать Ctrl-L в «less», чтобы перекрасить экран. kamae 12 лет назад 0

7 ответов на вопрос

14
Some programmer dude

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

$ ./somecommad 2>&1 | less 

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

Комментарий для новых читателей этого старого вопроса (не для Иоахима, в частности) Это то, что все думают с первого взгляда на вопрос. Но проблема более тонкая - см. Обсуждение в комментариях после [ответа dmckee] (http://superuser.com/a/366615/52492) RedGrittyBrick 7 лет назад 1
7
RedGrittyBrick

Может быть

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

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

Это фигня. Ответ Иоахима должен быть принят. Vanilla Face 7 лет назад 0
@VanillaFace: я добавил несколько разъясняющих материалов к своему ответу. RedGrittyBrick 7 лет назад 0
1
jackdoe

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

 make 2>&1 | less 
1
Elmar Zander

Одна вещь, которой до сих пор не хватало во всех ответах, это причина, почему это происходит. Проблема здесь заключается в некой гонке между процессом, который выводит данные на терминал 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
Anony-Mousse

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

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

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

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

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

find /etc 2>&1 | less 

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

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

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

0
dmckee

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

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

#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

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

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

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