LINUX.ORG.RU

bash как вернуть строку из функции

 ,


0

1

Решил структурировать скрипт-портянку, но столкнулся с такой штукой, что директива return принимает число и заполняет им переменную $?

На ум пришло создание глобальной переменной для передачи данных, но за такой рефакторинг Фаулер бы руку не пожал. Еще вариант это использовать конвеер, но выглядит как-то не очень.

f1(){
    echo "str1"
}


if [[ $(f1) == "str1" ]]; then
    echo this is good
fi
★★

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

mky ★★★★★
()

В bash функция должна возвращать 0 если она завершилась успешно, и не-0 если была ошибка. То есть это статус завершения. Результат - только через конвеер, глобальную переменную, временный файл и т. п.

Kroz ★★★★★
()
$ cat test.sh 
#!/bin/bash

function xtest()
{
        if [ "${1}" == "1" ];
        then
                echo "error";
                return 1;
        fi

        return 0;
}


OUT=$(xtest "0");
if [ "${?}" != "0" ];
then
        echo "${OUT}";
fi

OUT=$(xtest "1");
if [ "${?}" != "0" ];
then
        echo "${OUT}";
fi
$ ./test.sh 
error
quest ★★★★
()

Решил структурировать скрипт-портянку, но столкнулся с такой штукой, что директива return принимает число и заполняет им переменную $?

На ум пришло создание глобальной переменной для передачи данных, но за такой рефакторинг Фаулер бы руку не пожал. Еще вариант это использовать конвеер, но выглядит как-то не очень.

ну это таки лучше, чем передавать строковую переменную через код возврата.

emulek
()

echo это природный, очень даже нормальный способ возвращения результата в шелле.

val-amart ★★★★★
()
Ответ на: комментарий от quest

Сформулировал что именно меня смущает

#!/bin/bash

VERBOSE=yes

log()
{
    if [[ $VERBOSE == "yes" ]]; then
        echo $*
    fi
}

function xtest()
{
        log xtest ${1}
        if [ "${1}" == "1" ];
        then
                echo "error";
                return 1;
        fi

        return 0;
}


OUT=$(xtest "0");
if [ "${?}" != "0" ];
then
        echo "${OUT}";
fi

OUT=$(xtest "1");
if [ "${?}" != "0" ];
then
        echo "${OUT}";
fi

Yur4eg ★★
() автор топика
Ответ на: комментарий от Yur4eg
OUT=$(xtest "0");
if [ "${?}" != "0" ];
then
        echo "${OUT}";
fi

Делать так:

if xtest "0"; then
    echo ...
fi

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

log()
function xtest()
[[ $VERBOSE == «yes» ]]
[ «${1}» == «1» ]
[ «${?}» != «0» ]

Жуткий разнобой, как будто из других скриптов повыдергивано: 2,3 - bash-специфично, 4 - зря в баш зачем-то добавили (по-посиксу =). В конце строки ; не принято ставить, ну и на всякий случай: echo $* - если, скажем $1 = '-e' будет плохо, лучше printf «%s». И вообще для такого случая есть getopt.

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

Жуткий разнобой, как будто из других скриптов

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

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

как bash-специфично разделить вывод результата фунции и отладочной информации

Совершенно внезапно, код, возвращаемый return'ом, можно и нужно преобразовать в строку сообщения об ошибке. По-моему так в большинстве языков программирования вменяемые люди делают?

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

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

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

Если уже хочешь Унтерпрайз логгирование, то оно должно быть в другой файловый дексриптор (например в STDERR)

# инициализируем дескриптор для логгирования
if [ -f "$LOG_FILE" ]; then
    exec 3>"$LOG_FILE" # в файл
else
    exec 3>&2 # на STDERR
fi

log() {
   # используем специальный дескриптор для логгирования
   [ "$VERBOSE" = "true" ] && echo $* >&3
}

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

Совершенно внезапно, код, возвращаемый return'ом, можно и нужно преобразовать в строку сообщения об ошибке. По-моему так в большинстве языков программирования вменяемые люди делают?

Точно! Что-то такое на Си сделано, там одна функция открывает файл, а потом другой можно посмотреть код возврата, вроде, правда на Си 10 лет назад в универе писал, может что и путаю. Сейчас в основном на Питоне, а в нем кидаешь исключение и все.

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

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

Там выше есть пример функции xtest и log я не понимаю как их изменить.

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

Там выше есть пример функции xtest и log я не понимаю как их изменить.

Два раза уже намекнули, про /dev/stderr: добавляешь после echo "$*" >&2. И отладочная инф-ия идем мимо конвеера по stderr (если надо ее использовать внутри, можно поплясать с перенаправлениями). И $(xtest ..) для получения полезного выхлопа, а не errmsg.

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

Я обычно пишу в какой-нибудь 4-й дескриптор, который на самом деле - обычный файл лога. Это не самый правильный подход, лучше бы набор именованных дескрипторов, позволяющих отладочной функции писать сразу в несколько источников, но такой необходимости не было пока, поэтому лень дописывать этот функционал :) Хотя иногда не хватает возможности видеть на терминале то, что пишется в лог.

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

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

Золотые слова! Функция должна возвращать код ошибки, а за преобразование кода ошибки в строку описания должна отвечать другая функция модуля/пакета/другой метод объекта.

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