Как изменить значение глобальной переменной внутри функции, которая передается в качестве параметра в wapper (например, обратный вызов)? - PullRequest
0 голосов
/ 15 мая 2018

У меня есть вопрос о функции в качестве параметра bash.

Если выполняется следующая логика:

Var=5
Step=2

funct() {
    echo "[Line = $LINENO] $Var"
    Var=$(($Var+$Step))
    echo "[Line = $LINENO] $Var"
}

main()
{
    echo "[Line = $LINENO] $Var"
    funct
    echo "[Line = $LINENO] $Var"
}

main

вывод равен

[Line = 13] 5
[Line = 6] 5
[Line = 8] 7
[Line = 15] 7

, как вы видите, Var изменяется, как и ожидалось.

Однако, пожалуйста, проверьте следующий пример, где функция передается в качестве параметра для оболочки.

Var=5
Step=2

funct() {
    echo "[Line = $LINENO] $Var"
    Var=$(($Var+$Step))
    echo "[Line = $LINENO] $Var"
}

main()
{
    echo "[Line = $LINENO] $Var"
    funct
    echo "[Line = $LINENO] $Var"
}



main2()
{
    echo "[Line = $LINENO] $Var"
    ($1)
    echo "[Line = $LINENO] $Var"
}

main

main2 funct

результат равен

[Line = 12] 5
[Line = 5] 5
[Line = 7] 7
[Line = 14] 7
[Line = 21] 7
[Line = 5] 7
[Line = 7] 9
[Line = 23] 7

Пожалуйста, обратите внимание, что оболочка обратного вызова НЕ МОЖЕТ фактически изменить Var.

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

Как мне сделать обертку, которая принимает функцию в качестве параметра для реального изменения глобальной переменной?

Спасибо ~

Ответы [ 2 ]

0 голосов
/ 15 мая 2018
($1)

Запускает $1 в подоболочке, потому что это , что круглые скобки делают в оболочке. Если вы запускаете функцию в подоболочке, она не может изменять глобальные переменные (хотя ее среда выполнения инициализируется переменными родительской оболочки, поэтому она может их видеть).

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

"$1"

Кавычки позволяют избежать проблем с $1, содержащим пробельные символы или символы глобуса.

Более распространенная идиома

"$@"

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

0 голосов
/ 15 мая 2018
main2()
{
    echo "[Line = $LINENO] $Var"
    $1
    echo "[Line = $LINENO] $Var"
}

Я обнаружил, что удаление () работает, но НЕ знаю почему ...

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