Решение, которое вы показали выше, является общим и охватывает множество случаев. Если вы не знаете, что у вас есть проблема, вы можете принять позу YAGNI (You Ain't Gonna Need It) и просто перенаправить выбранные строки на /dev/tty.
Если вы хотите избежать этого, то вам нужно понять, как происходит жонглирование файловыми дескрипторами (fd).
Функция 3>&1
копирует stdout вызывающего контекста в "ячейку", чтобы функция могла вывести данные на любой stdout вызывающего контекста. В данном случае это /dev/tty. Помните, что функция будет вызвана с stdout, принадлежащим вложенной оболочке для подстановки ${}.
Команда exec 4>&1
создает копию fd1, которая является stdout функции. fd4 используется как ячейка для stdout, с которого начинается функция. >&3
устанавливает stdout функции/подшивки на stdout вызывающей стороны. Таким образом, весь вывод будет идти в stdoout вызывающей стороны. До конца, где >&4-
перемещает сохраненный stdout назад к началу, позволяя последнему echo "$s"
быть в stdout функции (и под-оболочки).
Ух ты!
Функции >&3
и >&4-
также можно записать более четко как 1>&3
и 1>&4-
.
В разделе руководства bash
, посвященном РЕДИРЕКЦИИ, объясняется вся эта номенклатура. Я был рад и удивлен, увидев, что на самом деле можно использовать формы {name} для замены чисел на слова.
"Каждое перенаправление, которому может предшествовать номер дескриптора файла, может вместо этого предшествовать слово формы {varname}. В этом случае для каждого оператора перенаправления, кроме >&- и <&-, оболочка выделит файловый дескриптор больше 10 и присвоит его varname. Если >&- или <&- предшествует {varname}, значение varname определяет дескриптор файла для закрытия."
Я не проверял это, но это предполагает, что вы можете закодировать это так:
#!/bin/bash
exec {caller_stdio}>&1
returnString() {
exec {func_stdio}>&1 1>&{caller_stdio}
local s=$1
s=${s:="some default string"}
echo "writing to stdout"
echo "writing to stderr" >&2
exec 1>&{func_stdio}-
echo "$s"
}
my_string=$(returnString "$*")
echo "my_string: [$my_string]"
Мои собственные заметки об использовании набора ключей ядра и его использовании через «keyctl»
http://www.ict.griffith.edu.au/anthony/info/crypto/passwd_caching.txt
Я сделал это для хранения паролей при редактировании зашифрованных файлов!