идиомы для того, чтобы возвратить несколько значений в сценариях оболочки

Есть ли какие-либо идиомы для того, чтобы возвратить несколько значений от функции удара в рамках сценария?

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.

24
задан Wang 21 March 2010 в 21:06
поделиться

3 ответа

Как бы мне ни нравилась оболочка, вероятно, дело в том, что как только вы разбрасываете произвольно структурированные данные, оболочка 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 ... выберите предпочитаемый яд). Ваш код, вероятно, станет трудно поддерживать; даже если вы можете, есть меньший круг людей, которые поймут это достаточно хорошо, чтобы поддерживать его.

9
ответ дан 28 November 2019 в 23:30
поделиться

Функции сценария оболочки могут возвращать только статус завершения последней выполненной команды или статус выхода этой функции, явно заданный оператором 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

Это может уменьшить ваш дискомфорт, хотя добавляет накладные расходы на создание новой оболочки и, следовательно, будет немного медленнее.

0
ответ дан 28 November 2019 в 23:30
поделиться

вы можете используйте ассоциативные массивы, у вас есть 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"
1
ответ дан 28 November 2019 в 23:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: