grep возвращает совпадение, когда оно не ожидается

avatar
sophist_pt
8 апреля 2018 в 04:22
75
1
3

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

0,2,468.000000
1,2,305.000000
2,5,2702.000000
3,3,1672.000000
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
    at java.util.ArrayList.rangeCheck(ArrayList.java:653)
    at java.util.ArrayList.get(ArrayList.java:429)
    at TestConverter.processPayments(TestConverter.java:113)
    at TestConverter.processFile(TestConverter.java:131)
    at TestConverter.main(TestConverter.java:142)

Я запускаю следующую команду:

java -classpath TestConverter.jar TestConverter test_xml.xml | grep "stringthatdoesnotmatch*"

Я получаю следующий вывод:

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 1, Size: 1
    at java.util.ArrayList.rangeCheck(ArrayList.java:653)
    at java.util.ArrayList.get(ArrayList.java:429)
    at TestConverter.processPayments(TestConverter.java:113)
    at TestConverter.processFile(TestConverter.java:131)
    at TestConverter.main(TestConverter.java:142)

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

.
*java.lang.IndexOutOfBoundsException*ArrayList.java:653*TestConverter.java:142*
Источник
Stephen Newell
8 апреля 2018 в 04:25
1

Вы уверены, что вывод исключения не будет stderr вместо stdout?

zwer
8 апреля 2018 в 04:28
1

Попробуйте также передать STDERR в grep: java -classpath TestConverter.jar TestConverter test_xml.xml |& grep "stringthatdoesnotmatch*"

sophist_pt
8 апреля 2018 в 04:29
0

@StephenNewell Не уверен, куда это идет. Но я чувствую, что это может быть stderr. Как я могу grep stderr?

sophist_pt
8 апреля 2018 в 04:30
0

@zwer Я попробовал это и получил -bash: syntax error near unexpected token `&'

zwer
8 апреля 2018 в 04:32
0

@sophist_pt - это странно, bash должен распознавать сокращение |&. В любом случае попробуйте: java -classpath TestConverter.jar TestConverter test_xml.xml 2>&1 | grep "stringthatdoesnotmatch*"

sophist_pt
8 апреля 2018 в 04:38
0

@zwer Кажется, это работает, однако сейчас я пытаюсь убедиться, что grep проверяет совпадение, которое гарантирует, что оно содержит *java.lang.IndexOutOfBoundsException*ArrayList.java:653*TestConverter.java:142* Знаете ли вы, как я могу этого добиться?

zwer
8 апреля 2018 в 04:45
0

@sophist_pt - grep по умолчанию работает построчно. Есть несколько подходов, которые вы можете использовать для многострочных совпадений, проверьте ответы на этот вопрос

sophist_pt
8 апреля 2018 в 04:58
0

@zwer Спасибо за помощь. Я передал вывод в xargs и сделал grep, и, похоже, он работает.

Ответы (1)

avatar
paxdiablo
8 апреля 2018 в 05:21
2

На самом деле вы не получили совпадение. Вы должны понимать разницу между стандартным выводом и стандартной ошибкой.

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

Итак, при добавлении конвейера:

program | grep xyzzy

символ | перенаправит стандартный выход program на стандартный ввод grep. Затем будут отфильтрованы все строки, не содержащие xyzzy, и переданы остальные в его стандартный вывод, в данном случае на терминал.

Стандартная ошибка из program по-прежнему подключена непосредственно к терминалу, поэтому будет появляться там независимо от того, что делает grep.

Если вы хотите, чтобы программа grep перехватывала как выходные данные , так и ошибки `program, сначала объедините их:

program 2>&1 | grep xyzzy

Этот 2>&1 означает взять то, что предназначалось для потока 2 (стандартная ошибка), и вместо этого отправить его в поток 1 (стандартный вывод). Затем | может принять все вывода/ошибки, поступающие от program.