4

Bash is “kind of function programming language” it dose not have classes. I managed to use encapsulation with Closures, but I want also to do some introspection to find also docker_ parent/super/base function (If you know add comments to define this correctly).

I managed this but with a dirty hack super=${FUNCNAME}. Is there any solution to use kind of PARENT_FUNCNAME? I have such file docker_.sh:

#!/usr/bin/env bash
function docker_ {
    local super=${FUNCNAME}
    function hello {
        echo "INFO" "do ${super}${FUNCNAME}"
    }
    function install {
        echo "INFO" "do ${super}${FUNCNAME}"
        #sudo curl -sSL https://get.docker.com/ | sh || exit 1
    }
    function run {
        echo "INFO" "do ${super}${FUNCNAME}"
        #docker run -d -p 3306:3306 ${DOCKER_IMAGE_NAME} /docker.sh run_mysql
    }
    ${@}
}
${@}

Got some results:

$ ./docker_.sh docker_ hello
INFO do docker_hello

$ ./docker_.sh docker_ run
INFO do docker_run

$ ./docker_.sh docker_ install
INFO do docker_install

Solved

use

${FUNCNAME[1]}
${FUNCNAME[@]:0:${#FUNCNAME[@]}-1} get all list beside main

code:

#!/usr/bin/env bash
function docker_ {
    function hello {
        echo "INFO" "do ${FUNCNAME[1]} ${FUNCNAME}"
    }
    function install {
        echo "INFO" "do > ${FUNCNAME[@]:0:${#FUNCNAME[@]}-1} "
        #sudo curl -sSL https://get.docker.com/ | sh || exit 1
    }
    function run {
        echo "INFO" "do > ${FUNCNAME[@]:0:${#FUNCNAME[@]}-1} "
        #docker run -d -p 3306:3306 ${DOCKER_IMAGE_NAME} /docker.sh run_mysql
    }
    ${@}
}
${@}

Got some results:

    ➜ ./docker_.sh docker_ hello  
    INFO do docker_ hello
    ➜ ./docker_.sh docker_ install
    INFO do > install docker_ 
    ➜ ./docker_.sh docker_ run    
    INFO do > run docker_ 
Community
  • 1
  • 1
Andrei.Danciuc
  • 1,000
  • 10
  • 24
  • Thanks, i was looking for how to get the parent function that calls a function, from without that child function. Works great! `${FUNCNAME[1]}` – blamb Aug 30 '23 at 21:26

1 Answers1

3

Bash really isn't a functional programming language. To start with, functions are not first-class objects; you cannot pass a function around. You can pass around the name of a function, but it's just a name; if the name is given a new value, then the old value is lost.

Bash does not have lexical scoping: bash scoping is dynamic. The local command is a command, like any other command. It is not syntactic. If it is not executed, the name is not made local. For example:

f() {
  if [[ $1 == local ]]; then local myvar=local; fi
  myvar=changed
}

$ var=original
$ f local
$ echo $myvar
original
$ f global
$ echo $myvar
changed

And bash does not have closures. You can define a function inside a function, but the function so defined does not carry the scope with it.

$ g() {
>   local myvar=inner
>    f() { echo $myvar; }
>    f
> }
$ myvar=outer
$ g
inner
$ f
outer
$ h() { local myvar=inside_h; f; }
$ h
inside_h
$ f
outer
rici
  • 234,347
  • 28
  • 237
  • 341
  • for @rici 1. I did not ask about what is "local"; 2. I did not receive answer to "Is there any solution to use kind of PARENT_FUNCNAME" – Andrei.Danciuc Oct 10 '15 at 16:57
  • @andrei Because it has no answer. There is no parent scope because bash doesnt really have scopes. If your question is, "can I find the name of the caller?" then ask that. But there is no way to find the name of the function in which the current function was defined, and the solution you propose won't work for reasons I tried to explain. – rici Oct 10 '15 at 17:06
  • Ok, then I ask. @riki can I find the name of the caller? from "./docker_.sh docker_ hello" to get caller name "docker_" ? – Andrei.Danciuc Oct 11 '15 at 18:19
  • @andrei: `${FUNCNAME[1]}` – rici Oct 11 '15 at 19:28