Эхо, который выводит на stderr

Есть ли стандартный инструмент Bash, который действует как эхо, но выводит на stderr, а не на stdout?

Я знаю, что могу сделать echo foo 1>&2, но это довольно уродливо и, я подозреваю, склонность к ошибкам (например, с большей вероятностью будет отредактировано неправильно, когда ситуация изменится).

Ответ 1

Вы можете сделать это, что облегчает чтение:

>&2 echo "error"

>&2 копирует дескриптор файла № 2 в дескриптор файла № 1. Следовательно, после выполнения этого перенаправления оба дескриптора файла будут ссылаться на один и тот же файл: один дескриптор файла № 2 изначально ссылался на него. Для получения дополнительной информации см. Учебное пособие по перенаправлению Bash Hackers.

Ответ 2

Вы можете определить функцию:

echoerr() { echo "[email protected]" 1>&2; }
echoerr hello world

Это будет быстрее, чем script и не имеет зависимостей.

Камило Мартин bash конкретное предложение использует "здесь строку" и будет печатать все, что вы передаете ему, включая аргументы (-n), которые эхо обычно проглатывало:

echoerr() { cat <<< "[email protected]" 1>&2; }

Решение Гленна Джекмана также позволяет избежать проблемы с глотанием аргумента:

echoerr() { printf "%s\n" "$*" >&2; }

Ответ 3

Так как 1 - стандартный вывод, вам не нужно явно указывать его перед перенаправлением вывода, например >, но вместо этого можно просто ввести:

echo This message goes to stderr >&2

Поскольку вы, похоже, обеспокоены тем, что 1>&2 вам будет трудно надежно напечатать, устранение избыточного 1 может быть для вас небольшим поощрением!

Ответ 4

Другой вариант

echo foo >>/dev/stderr

Ответ 5

Нет, это стандартный способ сделать это. Это не должно вызывать ошибок.

Ответ 6

Это простая функция STDERR, которая перенаправляет входной канал в STDERR.

#!/bin/bash
# *************************************************************
# This function redirect the pipe input to STDERR.
#
# @param stream
# @return string
#
function STDERR () {

cat - 1>&2

}

# remove the directory /bubu
if rm /bubu 2>/dev/null; then
    echo "Bubu is gone."
else
    echo "Has anyone seen Bubu?" | STDERR
fi


# run the bubu.sh and redirect you output
[email protected]:~$ ./bubu.sh >/tmp/bubu.log 2>/tmp/bubu.err

Ответ 7

Если вы не имеете права записывать сообщение также в syslog, путь not_so_ugly следующий:

logger -s $msg

Опция -s означает: "Вывести сообщение на стандартную ошибку, а также на системный журнал".

Ответ 8

Не используйте cat, поскольку некоторые из них упоминаются здесь. cat - это программа а echo и printf - это встроенные функции bash (shell). Запуск программы или другого script (также упоминалось выше) означает создание нового процесса со всеми его затратами. Использование встроенных функций записи довольно дешево, потому что нет необходимости создавать (выполнять) процесс (-environment).

Опнер спрашивает: "Есть ли какой-либо стандартный инструмент для вывода (pipe) в stderr", ответ schort: NO... почему?... rediredcting pipes - это концептуальная концепция в таких системах, как unix (Linux...) и bash (sh), которая основывается на этих концепциях.

Я согласен с разработчиком в том, что перенаправление с такими обозначениями: &2>1 для современных программистов не очень приятен, но это bash. bash не предназначался для создания огромных и надежных программ, он призван помочь администраторам работать с меньшими нажатиями клавиш; -)

И, по крайней мере, вы можете поместить перенаправление в любом месте строки:

$ echo This message >&2 goes to stderr 
This message goes to stderr

Ответ 9

Примечание. Я отвечаю на пост-не вводящее в заблуждение/неопределенное "эхо, которое выводит на stderr" (уже ответил OP).

Используйте функцию, чтобы показать намерение и укажите нужную реализацию. Например.

#!/bin/bash

[ -x error_handling ] && . error_handling

filename="foobar.txt"
config_error $filename "invalid value!"

output_xml_error "No such account"

debug_output "Skipping cache"

log_error "Timeout downloading archive"

notify_admin "Out of disk space!"

fatal "failed to open logger!"

И error_handling:

[email protected]

config_error() { filename="$1"; shift; echo "Config error in $filename: $*" 2>&1; }

output_xml_error() { echo "<error>$*</error>" 2>&1; }

debug_output() { [ "$DEBUG"=="1" ] && echo "DEBUG: $*"; }

log_error() { logger -s "$*"; }

fatal() { which logger >/dev/null && logger -s "FATAL: $*" || echo "FATAL: $*"; exit 100; }

notify_admin() { echo "$*" | mail -s "Error from script" "$ADMIN_EMAIL"; }

Причины, которые обрабатывают проблемы в OP:

  • Самый красивый синтаксис (значимые слова вместо уродливых символов)
  • сложнее сделать ошибку (особенно если вы повторно используете script)
  • это не стандартный инструмент Bash, но он может быть стандартной библиотекой оболочки для вас или вашей компании/организации.

Другие причины:

  • Ясность - показывает намерение другим сопровождающим
  • скорость - функции быстрее, чем shell-скрипты
  • reusability - функция может вызывать другую функцию
  • Конфигурируемость - нет необходимости редактировать оригинал script
  • отладка - проще найти строку, ответственную за ошибку (особенно, если вы пытаетесь выполнить тонну перенаправления/фильтрации)
  • надежность - если функция отсутствует, и вы не можете отредактировать script, вы можете вернуться к использованию внешнего инструмента с тем же именем (например, log_error может быть псевдонимом для регистрации в Linux)
  • переключения - вы можете переключиться на внешние инструменты, удалив атрибут "x" библиотеки
  • output agnostic - вам больше не нужно заботиться, попадает ли он в STDERR или где-либо еще.
  • персонализация - вы можете настроить поведение с переменными среды

Ответ 10

Об этом уже ответили и много голосов. Только для записи:

echo "my errz" > /proc/self/fd/2

будет эффективно выводиться на stderr. Объяснение: /proc/self - это ссылка на текущий процесс, а /proc/self/fd содержит дескрипторы открытых файлов процесса. Затем 0, 1 и 2 означают stdin, stdout и stderr соответственно.

Я нашел его более читаемым. Также это может работать в большинстве дистрибутивов Linux:

echo "my errz" > /dev/stderr

Сделать его более читаемым.

Ответ 11

read - это встроенная команда оболочки, которая печатает на stderr и может использоваться как эхо без выполнения трюков перенаправления:

read -t 0.1 -p "This will be sent to stderr"

-t 0.1 - это таймаут, который отключает чтение основных функций, сохраняя одну строку stdin в переменной.

Ответ 12

Сделайте script

#!/bin/sh
echo $* 1>&2

который будет вашим инструментом.

Или создайте функцию, если вы не хотите иметь script в отдельном файле.

Ответ 13

Другой вариант, на который я недавно наткнулся, это:

    {
        echo "First error line"
        echo "Second error line"
        echo "Third error line"
    } >&2

При этом используются только встроенные средства Bash, при этом вывод многострочных ошибок менее подвержен ошибкам (поскольку вам не нужно добавлять &>2 к каждой строке).

Ответ 14

Mac OS X: Я попробовал принятый ответ и пару других ответов, и все они привели к написанию STDOUT, а не STDERR на моем Mac.

Вот переносимый способ записи стандартной ошибки с использованием Perl:

echo WARNING! | perl -ne 'print STDERR'