LINUX.ORG.RU

Как получить доступ к локальным переменным в двух функциях?

 


0

1

Только локальные переменные нужны. Никаких глобальных

function f1 () {
   local var1 = some1
   local var2 = some2
}

function f2 () {
    f1  # <-- хотелось бы что-то такое. Типа загрузили f1 и имеем доступ к переменным, чтобы по 10 раз не дублировать var1 и var2 в f1...fx
    echo ${var1}
    echo ${var2}
}

function f3 () {
    f1
    echo ${var1}
    echo ${var2}
}
★★★★

Последнее исправление: bryak (всего исправлений: 4)

Понимаю, что вы спрашиваете совсем не об этом, но не могу молчать: вы где-то в жизни свернули не туда, если вам такое нужно в bash’е. Либо шелл смените на язык программирования, либо попытайтесь решить чего вы там делаете более идиоматичным образом.

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

Понимаю, что вы спрашиваете совсем не об этом, но не могу молчать: вы где-то в жизни свернули не туда, если вам такое нужно в bash’е. Либо шелл смените на язык программирования, либо попытайтесь решить чего вы там делаете более идиоматичным образом.

Изначально это всё задумывалось как штука, для запуска которой не надо устанавливать какие-то пакеты. Но потом, когда начал расширять функциональность, чтобы это стало удобным - все «прелести» баш сразу вылезли наружу. Сейчас я бы это сделал на каком-то lua(и горя бы не знал)

bryak ★★★★
() автор топика
Последнее исправление: bryak (всего исправлений: 2)

по 10 раз не дублировать var1 и var2

Сделать им общее имя (объединить в структуру).

В параметры f1…fx передавать одно это общее имя (и за счёт этого не дублировать при передаче var1 и var2)

«В Bash нет структур данных (struct) в стиле языков C или C++, но существуют механизмы для организации сложных данных: ассоциативные массивы (хэш-таблицы), обычные одномерные массивы, а также переменные, эмулирующие структуры через соглашения об именовании (например, user1_name, user1_id).»

Saakx
()
Последнее исправление: Saakx (всего исправлений: 1)
Ответ на: комментарий от bryak

Bash — не про красоту. Ты хочешь странного, и такой способ решает твою проблему.

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

CrX ★★★★★
()
Последнее исправление: CrX (всего исправлений: 1)
Ответ на: комментарий от bryak

Резать не дожидаясь перетонита! Но если уж никак, то можно запихнуть разделяемые данные в массив, который передавать через nameref.

#!/usr/bin/env bash

f1() {
    local -n result="$1"
    local var1=some1
    local var2=some2
    result=($var1 $var2)
}

f2() {
    local vars
    f1 vars
    declare -p vars
}

f2

Ничего лучше что-то не придумывается.

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

Еще можно так))

function f1 () {
    local SRV_NAME='gpm'
    local SRV_NAME_PKG=(
        gpm
    )

    echo "SRV_NAME=$SRV_NAME"
    echo "SRV_NAME_PKG=(${SRV_NAME_PKG[@]})"
}

function f2 () {
    eval "$(f1)"

    echo "${SRV_NAME_PKG[@]}"
}

f2
bryak ★★★★
() автор топика
Последнее исправление: bryak (всего исправлений: 1)
Ответ на: комментарий от bryak

Они же локальные. Не позатирают.

Во всех нормальных ЯП локльные переменные явно объявляют и всё прекрасон работает. Не всегда повторяющиеся строки в программе - ошибка, от которой надо избавляться.

legolegs ★★★★★
()

я конечно баш не особо хорошо знаю, но вот возникает чисто технический вопрос

вот в этом случае


function f1 () {
   local var1 = some1
   local var2 = some2
}

function f3 () {
    f1
    echo ${var1}
    echo ${var2}
}

что собственно говоря должна вывести на экран echo? f1 ведь не вызывалась и значения не присвоены, вроде как

anonymous
()

Гм, ты что куришь? То у тебя «строки многострочные» то «нелокальные локальные переменные»… Лучше б ты маны курил, ей богу.

И, кстати, в перле есть то, что ты хочешь. ;-) Я тебе говорил: бери перл…

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

Гм, ты что куришь? То у тебя «строки многострочные» то «нелокальные локальные переменные»… Лучше б ты маны курил, ей богу.

Ты же видишь, что я делаю так, чтобы было удобно. Пофигу на архитектуру самого баша. Являются какие-то там переменные локальными по отношению к каким-то там функциям архитектурно или нет - главное чтобы мне удобно было

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

bryak ★★★★
() автор топика
Последнее исправление: bryak (всего исправлений: 1)

Если действительно нужно сделать как требуется, то нужно писать маленькую программку на С, читать указатель стека, брать правильное смещение учитывая эпилог, линк-энд-джамп адрес возврата, неволотайл регистры, и вот они ваши var1, var2 от функции f1. Но как уже справедливо заметили, где-то вы пропустили поворот, раз понадобилось такое дело.

VIT ★★
()
function f1 () {
   local var1 = some1
   local var2 = some2
   echo "${var1}" "${var2}"
}

function f2 () {
#    f1  # <-- хотелось бы что-то такое. Типа загрузили f1 и имеем доступ к переменным, чтобы по 10 раз не дублировать var1 и var2 в f1...fx
    array=($( f1 ))
    local var1 = "${array[0]}"
    local var2 = "${array[1]}"
    echo ${var1}
    echo ${var2}
}

Не проверял

А, можно как Aceler писал, через параметры. Что-то типа: f2 $( f1 ) , при вызове, а внутри использовать «${1}» «${2}».

sin_a ★★★★★
()
Последнее исправление: sin_a (всего исправлений: 1)
Ответ на: комментарий от sin_a

А потом ты скажешь что переменные с пробелами, а я тебе скажу перебирать их в цикле, а ты скажешь что они в несколько строк а я скажу про жейсон, и короче придём к тому что он сказал – к временному файлу. К набору временных файлов…

sin_a ★★★★★
()
Последнее исправление: sin_a (всего исправлений: 1)