LINUX.ORG.RU

[шъ] Присваивание значения глобальной переменной в функции, чей stdout присваевается другой переменной в качестве значения


0

0

Не работает присваивание значения глобальной переменной в функции, чей stdout присваевается другой переменной в качестве значения. Глядите:

 $ G=1
 $ f2() { (( G++ )); echo 'foo'; };
 $ f1() { echo $G; var=`f2`; echo $G; };
 $ f1
1
1
 $

А должно бы быть 1 2, по идее, т.е. конструкция (( G++ )) не срабатывает, из-за того, что результат echo 'foo' в f1() присваивается var в f2().

Как это можно обойти? Пример реальный, в G хранится оффсет, с которым работает f2(), ожидающая, что на следующем вызове он будет инкрементирован (чего не выходит из-за данной проблемы).


Вместо передачи через stdout можно использовать ${!ref}=bla (баш) или eval $ref=bla (шъ) - и передавать в функцию имя переменной, куда надо присвоить значение.

const86 ★★★★★
()
Ответ на: комментарий от const86

А, в глобальную переменную писать? Понятно, хорошо, а насколько, интересно, в баше верно правило "Global variables ARE EVIL?" :) Я их использование стремлюсь к минимуму свести, просто, а может зря это и делаю.

xio
() автор топика
Ответ на: комментарий от xio

Bash оперирует с переменными среды (environment variables), а они наследуются только от родительского процесса дочерним, но не обратно. Так что в форкнутом процессе баша (например в конструкции `do smthng`) будут изменяться локальные для нового процесса копии переменных среды, а в родительском процессе ничего не изменится.

Deleted
()
Ответ на: комментарий от Deleted

Ну да, да, писать из двух функций в одну переменную, без использования бэктиков, функции ведь не форкают новый шелл.

xio
() автор топика
Ответ на: комментарий от xio

> Ваня, ты сейчас сам на чем пишешь, если пишешь вообще?

/* старательно делает умный вид */
На том, что под руку попадётся *).

Deleted
()
Ответ на: комментарий от xio

> функции ведь не форкают новый шелл.

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

Из стандарта:

The shell shall expand the command substitution by executing command in a subshell environment

dilmah ★★★★★
()
Ответ на: комментарий от dilmah

Ну, я так понимаю, "command substitution" это как раз и есть `` и $(), а не функции, которые суть просто именованные "compound commands" (или даже "group commands").

xio
() автор топика
Ответ на: комментарий от xio

я думал ты имеешь в виду функцию в бэктиках. Если просто функции, то да.

dilmah ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.