Как получить вывод функции оболочки без разветвления вложенной оболочки? - PullRequest
10 голосов
/ 21 сентября 2011

У меня есть следующие функции.

hello () {
        echo "Hello"
}
func () {
        hello
        echo "world"
}

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

func () {
        local Var=$(hello)
        echo "${Var/e/E} world"
}

Ответы [ 4 ]

3 голосов
/ 05 марта 2018

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

myfunc() { declare -g $1="hello"; }

Затем вызвать ее как:

myfunc mystring
echo "$mystring world" # gives "hello world"

Итак, ваши функции можно переписать так:

hello() {
    declare -g $1="Hello"
}

func() {
    hello Var
    echo "${Var/e/E} world"
}

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


Связанный пост, в котором говорится об использовании namerefs:

2 голосов
/ 05 марта 2018

Не ответ bash: по крайней мере одна оболочка, ksh оптимизирует подстановку команд $( ... ) в , а не , порождает подоболочку для встроенных команд.Это может быть полезно, когда ваш скрипт выполняет много из них.

2 голосов
/ 22 сентября 2011

Как насчет использования файлового дескриптора и строки Bash here?

hello () {
    exec 3<<<"Hello"
}

func () {
    local Var
    exec 3>&-
    hello && read Var <&3
    echo "${Var/e/E} world"
    exec 3>&-
}

func
2 голосов
/ 21 сентября 2011

Уродливое решение - временно заменить echo, чтобы он устанавливал глобальную переменную, к которой вы можете обращаться из своей функции:

func () {
  echo () {
    result="$@"
  }
  result=
  hello
  unset -f echo
  echo "Result is $result"
}

Я согласен, что это неприятно, но избегает подоболочки.*

...