Вопрос или проблема
Для контекста :
$ hadoop version
Hadoop 2.7.3.2.6.5.0-292
Что я сделал :
$ hdfs dfs -rm -safely -r '/path/to/data/year=2022/month=10' 1>file1.log 2>file2.log
$ ls -l file*log
-rw-r--r-- 1 userName groupName 0 Окт 23 10:54 file1.log
-rw-r--r-- 1 userName groupName 294 Окт 23 10:54 file2.log
⇒ ничего не отправлено в stdout
, но stderr
получил данные
$ cat file2.log
24/10/23 10:58:19 INFO fs.TrashPolicyDefault: Перемещено: 'hdfs://HDFSROOT/path/to/data/year=2022/month=10' в корзину: hdfs://HDFSROOT/user/userName/.Trash/Current/path/to/data/year=2022/month=10
⇒ вывод, который не является сообщением об ошибке, был отправлен в stderr
: ПОЧЕМУ ? Я ожидал, что строка вывода будет отправлена в файл, подключенный к stdout
: file1.log
.
запуск той же команды снова на отсутствующем файле, чтобы вызвать ошибку :
$ hdfs dfs -rm -safely -r '/path/to/data/year=2022/month=10' 1>>file1.log 2>>file2.log
$ echo $?
1
$ ls -l file*log
-rw-r--r-- 1 userName groupName 0 Окт 23 10:58 file1.log
-rw-r--r-- 1 userName groupName 411 Окт 23 10:59 file2.log
$ cat file2.log
24/10/23 10:58:19 INFO fs.TrashPolicyDefault: Перемещено: 'hdfs://HDFSROOT/path/to/data/year=2022/month=10' в корзину: hdfs://HDFSROOT/user/userName/.Trash/Current/path/to/data/year=2022/month=10
rm: `/path/to/data/year=2022/month=10': Нет такого файла или каталога
⇒ сообщение об ошибке было добавлено в файл, получающий stderr
(как и ожидалось)
Документация говорит :
Информация об ошибках отправляется в stderr, а вывод отправляется в stdout.
Что я упускаю ?
Ответ или решение
Почему hdfs dfs -rm отправляет обычный вывод в stderr?
При работе с командами Hadoop, как в вашем случае с hdfs dfs -rm
, довольно часто возникают вопросы о поведении стандартного вывода (stdout
) и стандартного потока ошибок (stderr
). Ваша ситуация, когда информационные сообщения, такие как "Moved to trash", направляются в stderr
, требует более глубокого понимания.
Понимание стандартных потоков вывода
Существуют два основных потока вывода в Unix-подобных системах:
- Стандартный вывод (stdout) — используется для вывода основной информации программы, которая не относится к ошибкам. Например, успешные результаты выполнения команд.
- Стандартный поток ошибок (stderr) — предназначен для вывода сообщений об ошибках и предупреждений, которые могут возникнуть во время выполнения программы.
Документация Hadoop, как вы указали, говорит, что информация об ошибках отправляется в stderr
, а информация о выводе — в stdout
. Таким образом, поведение команды hdfs dfs -rm
не соответствует вашим ожиданиям, и это может вызывать путаницу.
Почему вывод ‘Moved to trash’ в stderr
?
В Hadoop команда hdfs dfs -rm
обрабатывает две категории сообщений:
- Информационные сообщения (например, подтверждение перемещения файла в корзину).
- Сообщения об ошибках (например, если файл не найден).
В отличие от традиционного подхода, в Hadoop команда использует stderr
для сообщения об информационных событиях, которые связаны с выполнением команд, чтобы подчеркнуть их важность. Это решение может быть обусловлено историческими факторами разработки или предназначено для системного администрирования, где информация о процессах может восприниматься всерьез и требует внимания. В результате, любые сообщения, которые могут быть полезны для диагностики или мониторинга, отправляются в stderr
.
Возможные решения
Если вы хотите разделить вывод и ошибки, и, по вашему мнению, информация должна быть записана в stdout
, вы можете воспользоваться следующими подходами:
-
Переопределение поведения: Вы можете использовать инструменты обработки потоков (например,
grep
,awk
илиsed
), чтобы фильтровать и направлять сообщения в нужные места.Пример:
hdfs dfs -rm -safely -r '/path/to/data/year=2022/month=10' 2>file2.log | grep "INFO" >file1.log
-
Анализ логов: Совместное использование
2>&1
для объединения потоков поможет вам визуализировать все данные в одном месте, но это не всегда желаемый результат, если вам все-таки необходимо разделение.
Заключение
Таким образом, поведение команды hdfs dfs -rm
, где обычный вывод и ошибки направляются в stderr
, является особенностью разработки Hadoop для обеспечения акцента на информационных сообщения. Этот подход может отличаться от традиционных практик в большинстве Unix-программ, что может вызвать недопонимание у пользователей. Правильное понимание этой концепции поможет вам более эффективно работать с инструментами Hadoop.
Если у вас есть дополнительные вопросы или необходима помощь по другим аспектам использования Hadoop, не стесняйтесь обращаться.