Есть ли стандартный инструмент Bash, который действует как эхо, но выводит на stderr, а не на stdout?
Я знаю, что могу сделать echo foo 1>&2
, но это довольно уродливо и, я подозреваю, склонность к ошибкам (например, с большей вероятностью будет отредактировано неправильно, когда ситуация изменится).
Этот вопрос старый, но вы можете сделать это, что облегчает чтение:
>&2 echo "error"
Оператор >&2
буквально означает перенаправление адреса дескриптора файла 1 (stdout
) на адрес файлового дескриптора 2 (stderr
) для этой команды 1. В зависимости от того, насколько глубоко вы хотите это понять, прочтите следующее: http://wiki.bash-hackers.org/howto/redirection_tutorial
Чтобы избежать взаимодействия с другими перенаправлениями, используйте subshell
(>&2 echo "error")
1>&2
копирует дескриптор файла №2 в дескриптор файла # 1. Поэтому после выполнения этого перенаправления оба файловых дескриптора будут ссылаться на один и тот же файл: дескриптор 1 одного файла был изначально, ссылаясь на.
alias errcho='>&2 echo'
Вы можете определить функцию:
echoerr() { echo "$@" 1>&2; }
echoerr hello world
Это будет быстрее, чем script и не имеет зависимостей.
Камило Мартин bash конкретное предложение использует "здесь строку" и будет печатать все, что вы передаете ему, включая аргументы (-n), которые эхо обычно проглатывало:
echoerr() { cat <<< "$@" 1>&2; }
Решение Гленна Джекмана также позволяет избежать проблемы с глотанием аргумента:
echoerr() { printf "%s\n" "$*" >&2; }
echoerr -ne xt
не собирается печатать "-ne xt". Лучше использовать printf
для этого.
echoerr() { cat <<< "$@" 1>&2; }
Так как 1
- стандартный вывод, вам не нужно явно указывать его перед перенаправлением вывода, например >
, но вместо этого можно просто ввести:
echo This message goes to stderr >&2
Поскольку вы, похоже, обеспокоены тем, что 1>&2
вам будет трудно надежно напечатать, устранение избыточного 1
может быть для вас небольшим поощрением!
echo >&2 some message
или echo >&2 "some message"
?
Другой вариант
echo foo >>/dev/stderr
Нет, это стандартный способ сделать это. Это не должно вызывать ошибок.
Это простая функция 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
tux@earth:~$ ./bubu.sh >/tmp/bubu.log 2>/tmp/bubu.err
Не используйте 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
Если вы не имеете права записывать сообщение также в syslog, путь not_so_ugly следующий:
logger -s $msg
Опция -s означает: "Вывести сообщение на стандартную ошибку, а также на системный журнал".
Примечание. Я отвечаю на пост-не вводящее в заблуждение/неопределенное "эхо, которое выводит на 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
:
ADMIN_EMAIL=root@localhost
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:
Другие причины:
read
- это встроенная команда оболочки, которая печатает на stderr и может использоваться как эхо без выполнения трюков перенаправления:
read -t 0.1 -p "This will be sent to stderr"
-t 0.1
- это таймаут, который отключает чтение основных функций, сохраняя одну строку stdin в переменной.
Сделайте script
#!/bin/sh
echo $* 1>&2
который будет вашим инструментом.
Или создайте функцию, если вы не хотите иметь script в отдельном файле.
Об этом уже ответили и много голосов. Только для записи:
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
Сделать его более читаемым.
/proc/self
не работает на MacOS, поэтому я остановлюсь на более прямолинейном методе /dev/stderr
. Также, как отмечено в других ответах / комментариях, вероятно, лучше использовать >>
для добавления.
/proc/self/fd/*
доступен в Termux для Android, но не /dev/stderr
.
Mac OS X: Я попробовал принятый ответ и пару других ответов, и все они привели к написанию STDOUT, а не STDERR на моем Mac.
Вот переносимый способ записи стандартной ошибки с использованием Perl:
echo WARNING! | perl -ne 'print STDERR'
echo "foo" > /dev/stderr
? Илиecho "foo" >&2
? То же самое, я думаю.