Скрытие вывода команды оболочки обычно включает перенаправление stderr и stdout. Есть ли встроенное средство или команда, которая по умолчанию скрывает вывод, но при ошибке сбрасывает весь накопленный вывод? Я хотел бы запустить это как оболочку для удаленного ssh
команды. Теперь у меня они используют перенаправление, но я не понимаю, что их привело к сбою, и они слишком многословны.
РЕДАКТИРОВАТЬ: В конце я создал следующий шаблон на основе ответа @Belmin, который я немного изменил, чтобы собрать все предыдущие команды из сценария, использовать текущий идентификатор процесса, автоматически удалить журнал и добавить сообщение об ошибке красного цвета, когда что-то идет не так. В этом шаблоне начальная silent
обертки завершатся успешно, а затем не выполнят третью команду, потому что каталог уже существует:
#!/bin/sh
set -e
SILENT_LOG=/tmp/silent_log_$$.txt
trap "/bin/rm -f $SILENT_LOG" EXIT
function report_and_exit {
cat "${SILENT_LOG}";
echo "\033[91mError running command.\033[39m"
exit 1;
}
function silent {
$* 2>>"${SILENT_LOG}" >> "${SILENT_LOG}" || report_and_exit;
}
silent mkdir -v pepe
silent mkdir -v pepe2
silent mkdir -v pepe
silent mkdir -v pepe2
Написание сценария для этой цели должно быть достаточно простым.
Что-то вроде этого совершенно непроверенного скрипта.
OUTPUT=`tempfile`
program_we_want_to_capture &2>1 > $OUTPUT
[ $? -ne 0 ]; then
cat $OUTPUT
exit 1
fi
rm $OUTPUT
С другой стороны, для команд, которые я запускаю как часть сценария, мне обычно нужно что-то получше, чем просто распечатать весь вывод. Я часто ограничиваю то, что вижу, неизвестным. Вот сценарий, который я адаптировал из того, что я прочитал более десяти лет назад.
#!/bin/bash
the_command 2>&1 | awk '
BEGIN \
{
# Initialize our error-detection flag.
ErrorDetected = 0
}
# Following are regex that will simply skip all lines
# which are good and we never want to see
/ Added UserList source/ || \
/ Added User/ || \
/ init domainlist / || \
/ init iplist / || \
/ init urllist / || \
/ loading dbfile / || \
/^$/ {next} # Uninteresting message. Skip it.
# Following are lines that we good and we always want to see
/ INFO: ready for requests / \
{
print " " $0 # Expected message we want to see.
next
}
# any remaining lines are unexpected, and probably error messages. These will be printed out and highlighted.
{
print "->" $0 # Unexpected message. Print it
ErrorDetected=1
}
END \
{
if (ErrorDetected == 1) {
print "Unexpected messages (\"->\") detected in execution."
exit 2
}
}
'
exit $?
Я не думаю, что есть чистый способ сделать это, единственное, что я могу придумать, это
Реализация этого может быть интересным проектом, но, возможно, выходит за рамки вопросов и ответов.
Я бы установил функция bash как это:
function suppress { /bin/rm --force /tmp/suppress.out 2> /dev/null; ${1+"$@"} > /tmp/suppress.out 2>&1 || cat /tmp/suppress.out; /bin/rm /tmp/suppress.out; }
Затем вы можете просто запустить команду:
suppress foo -a bar
заканчиваться чем-то вроде tehcommand &>/tmp/$$ || cat /tmp/$$
зависит от того, насколько удобство использования / набора текста вы хотите / нуждаетесь. (например, используя его как канал или передавая команду по аргументу)
Короткий скрипт @zoredache - это, по сути, прото-оболочка для этого, которая обеспечит большую надежность, обеспечит параллелизм и т. д.
Попробуйте так:
out=`command args...` || echo $out