Самый безопасный способ вернуть строку из функции bash (<4.3), когда функция содержит другие эхо - PullRequest
0 голосов
/ 26 июня 2018

Я хочу напечатать некоторые сообщения в стиле логирования в моей функции, но мне также нужно вернуть строковое значение в конце функции.

Я сталкивался с пространствами имен, но, к сожалению, я не работаю с достаточно свежей версией bash.

Например:

doThing() {
   echo "stuff"
   echo "things"
   echo "usefulstring"
}

result=$( doThing )

[[ $result = "usefulstring" ]] && echo "Worked" || echo "Failed. :("

Я бы действительно предпочел избежать глобальных переменных, ииз того, что я прочитал, я должен избегать eval.Итак, какие еще есть варианты?

Кроме того - я хотел бы видеть эхо регистрации на stdout, но не возвращаемое значение.Можно ли использовать перенаправление внутри функции для достижения этой цели?

Ответы [ 3 ]

0 голосов
/ 26 июня 2018

Если вы в порядке с минимальным дисковым вводом / выводом, вы можете открыть дескриптор файла для записи в файл, а затем проанализировать его после завершения функции.

В этом примере fd 3 будет служить нашей цели

doThing() {
   echo "stuff"
   echo "things"

   exec 3<> /tmp/foo
   echo "usefulstring" >&3
   exec 3>&-
}

и теперь анализирует этот файл, используя read для одной переменной или mapfile, если вы передаете несколько словв массив.Таким образом, переменная содержит строковые значения, даже если они содержат пробелы между.

doThing
read -r str < /tmp/foo

Результат будет доступен в str, который вы можете заключить в кавычки в условных выражениях.Если ваша файловая система сохраняет занятость /tmp или /var, вы можете использовать mktemp, чтобы создать файл в локальном каталоге для использования для fd.

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

0 голосов
/ 26 июня 2018

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

doThing() {
   echo "stuff" >&2    # Logging output goes to stderr
   echo "things"  >&2
   echo "usefulstring"
}

... затем result=$( doThing ) выведет «вещи» и «вещи» в stderr и установит result в «полезную строку». Если вы хотите, чтобы выходные данные журналирования переходили к стандартному выводу скрипта, вы можете перенаправить его обратно так:

result=$( doThing ) 2>&1
0 голосов
/ 26 июня 2018

Вы можете использовать массив и получить последний элемент:

doThing() {
   echo "stuff"
   echo "things"
   echo "usefulstring"
}

# This creates an array
result=($( doThing ))
echo ${result[@]}    # Just for debugging

# This get the index of the last element
end=$(( ${#result[*]} - 1 ))
result=${result[$end]}

echo $result    # Just for debugging

[[ $result = "usefulstring" ]] && echo "Worked" || echo "Failed. :("

Дает:

stuff things usefulstring
usefulstring
Worked
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...