Есть ли какие-либо идиомы для того, чтобы возвратить несколько значений от функции удара в рамках сценария?
http://tldp.org/LDP/abs/html/assortedtips.html описывает, как повторить несколько значений и обработать результаты (например, пример 35-17), но это становится хитрым, если некоторые возвращаемые значения являются строками с пробелами в.
Более структурированный способ возвратиться состоял бы в том, чтобы присвоить глобальным переменным, как
foo () {
FOO_RV1="bob"
FOO_RV2="bill"
}
foo
echo "foo returned ${FOO_RV1} and ${FOO_RV2}"
Я понимаю, что, если мне нужна повторная входимость в сценарии оболочки, я, вероятно, делаю ее неправильно, но я все еще чувствую себя, очень неловко бросая глобальные переменные вокруг только для содержания возвращаемых значений.
Существует ли лучший путь? Я предпочел бы мобильность, но это - вероятно, не реальное ограничение, если я должен указать #!/bin/bash
.
Как бы мне ни нравилась оболочка, вероятно, дело в том, что как только вы разбрасываете произвольно структурированные данные, оболочка Unix bourne / posix не подходит выбор.
Если есть символы, которые не встречаются внутри полей, разделите их одним из них. Классическим примером является / etc / passwd
, / etc / group
и различные другие файлы, в которых двоеточие используется в качестве разделителя полей.
Если используется оболочка, которая может обрабатывать символ NUL внутри строк, то соединение по NUL и разделение по нему (через $ IFS или что-то еще) может работать хорошо. Но несколько распространенных оболочек, включая bash, ломаются на NUL. Тестом был бы мой старый .sig:
foo=$'a\0b'; [ ${#foo} -eq 3 ] && echo "$0 rocks"
Даже если это сработает для вас, вы только что достигли одного из предупреждающих знаков о том, что пора перейти на более структурированный язык (Python, Perl, Ruby, Lua , Javascript ... выберите предпочитаемый яд). Ваш код, вероятно, станет трудно поддерживать; даже если вы можете, есть меньший круг людей, которые поймут это достаточно хорошо, чтобы поддерживать его.
Функции сценария оболочки могут возвращать только статус завершения последней выполненной команды или статус выхода этой функции, явно заданный оператором return.
Один из способов возврата строки может быть следующим:
function fun()
{
echo "a+b"
}
var=`fun` # Invoke the function in a new child shell and capture the results
echo $var # use the stored result
Это может уменьшить ваш дискомфорт, хотя добавляет накладные расходы на создание новой оболочки и, следовательно, будет немного медленнее.
вы можете используйте ассоциативные массивы, у вас есть bash 4, например
declare -A ARR
function foo(){
...
ARR["foo_return_value_1"]="VAR1"
ARR["foo_return_value_2"]="VAR2"
}
, вы можете комбинировать их как строки.
function foo(){
...
echo "$var1|$var2|$var3"
}
тогда всякий раз, когда вам нужно использовать эти возвращаемые значения,
ret="$(foo)"
IFS="|"
set -- $ret
echo "var1 one is: $1"
echo "var2 one is: $2"
echo "var3 one is: $3"