LINUX.ORG.RU
ФорумAdmin

bash: сохранение потока ошибок функции в переменную


0

1

У юзера, от имени которого запускается скрипт нет прав на чтение файла filename. Соответственно, в поток ошибок идет мессага об этом. Задача стоит: сохранить поток ошибок всех команд функции в переменную (для последующей проверки того, что блок кода отработал безошибочно). Никак не выходит.

#!/bin/bash

a="a"

block_a() {
        cat filename
        echo "message2, a='$a'"
}

var=$( block_a > _out.txt 2>&1 )

echo "var = '$var'"

В том варианте, который используется сейчас, как и следовало ожидать, все (и вывод, и ошибки) уходит в файл. Использовать временный файл не хочется.

Как лучше поступить? Можно при помощи какого-нибудь хитрого перенаправления поменять местами потоки ошибок и вывода? Или block_a_std_errors.tmp неизбежен?

P.S. а вот стандартный вывод нужно кинуть именно в файл



Последнее исправление: Liber (всего исправлений: 1)
Ответ на: комментарий от blind_oracle

Дело в том, что идея использовать функцию у меня возникла уже во время написания поста... Изначально это был неименованный блок { ... } > filename

Разумеется, $? - первое, что я попробовал. Беда в том, что !=0 оно только если ошибка произошла в последней команде блока.

С функцией, как я понимаю, та же песня - придется проверять код возврата после каждой команды, при выполнении которой возможны ошибки. А их там совсем не 2, как в приведенном примерчике. Вся соль этой ереси в том, чтобы сделать все разом. Если подскажете, как это сделать более грамотно - буду благодарен.

Liber
() автор топика

Задача стоит: сохранить поток ошибок всех команд функции в переменную
а вот стандартный вывод нужно кинуть именно в файл

STDERR_VAR=$(cmd 2>&1 1>stdout_file.txt) Но это изврат.

NightSpamer
()
Ответ на: комментарий от zolden

Мать его! Вложенные блоки! Красиво! Спасибо! С инициализацией дополнительных дескрипторов тоже интересный вариант.

zolden, да видимо недостаточно хорошо гуглил. Вылезала всякая байда с элементарными примерами перенаправлений потоков.

Liber
() автор топика
Ответ на: комментарий от NightSpamer

NightSpamer, а разве в этом варианте не получится так, что в файл будут перенаправлены и поток вывода, и поток ошибок?..

Liber
() автор топика
Ответ на: комментарий от Liber

Это если перенаправления местами поменять. Т.е.

STDERR_VAR=$(cmd 2>&1 1>stdout_file.txt)
и
STDERR_VAR=$(cmd 1>stdout_file.txt 2>&1)
Дадут 2 разных результата.

NightSpamer
()
Ответ на: комментарий от Liber

С функцией, как я понимаю, та же песня - придется проверять код возврата после каждой команды, при выполнении которой возможны ошибки.

set -e?

AITap ★★★★★
()

Чем вы страдаете?

┌[lord] [home-hell-machine]:~ 
└>var=$(dd if=/dev/null of=/dev/null bs=100M count=1 2>&1)

┌[lord] [home-hell-machine]:~ 
└>echo $var
0+0 records in 0+0 records out 0 bytes (0 B) copied, 2.0516e-05 s, 0.0 kB/s

Spirit_of_Stallman ★★★
()
Ответ на: комментарий от Spirit_of_Stallman

И? stdout и stderr оказываются в одной переменной. А ТСу надо было stdout в файл, а stderr в переменную. Хотя, кажется, его отговорили.

NightSpamer
()
Ответ на: комментарий от NightSpamer

Уф. Или прочитал по-диагонали или был не внимателен.
Тут не прав, да.

Spirit_of_Stallman ★★★
()
Ответ на: комментарий от NightSpamer

NightSpamer:

Это если перенаправления местами поменять.

Ясно. Не знал, спасибо!

NightSpamer:

Хотя, кажется, его отговорили.

Нет, с вложенными блоками:

var=$( { block_a > _out.txt ; } 2>&1 )
получилось все как было мне нужно. Функция генерит необходимый файл, а поток ошибок сохраняется в переменной.

AITap:

set -e?

Не совсем подходит... В случае ошибки не безусловная остановка исполнения.

Liber
() автор топика
Ответ на: комментарий от NightSpamer

NightSpamer:

STDERR_VAR=$(cmd 2>&1 1>stdout_file.txt) Но это изврат.

Но все-таки чем плох такой вариант? Баш скрипты только-только осваиваю, поэтому, конечно, все получается довольно коряво.

В данном конкретом случае (функция генерит файл, если в процессе возникли ошибки - доступа, например - то отрабатывает определенная логика) можно было бы решить задачу красивее?

Можно, конечно, эту функциональность выделить в отдельный скрипт, но морочиться с параметрами и прочим ради такой ерунды не хочется.

Liber
() автор топика
Ответ на: комментарий от Liber

1) Содержимое stderr зависит от $LANG.
2) Наличие текста в stderr зависит от приложения. Например, dd будет писать туда при корректной работе.

NightSpamer
()
Ответ на: комментарий от NightSpamer

Понятно.

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

Или ты к тому, что код возврата можно под каждую конкретную команду «заточить»? Но по идее, то же самое можно сделать и с приложениями. Наверняка у них есть опции подавления лишнего вывода в поток ошибок.

Liber
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.