0

Let's say I have two files main.sh and sub.sh in the same folder with the following contents:

main.sh:

#!/usr/bin/env bash

export PARAMETER="main"
my_func(){
  echo "$PARAMETER $1"
}
export -f my_func

# Run the other script
./sub.sh

sub.sh:

#!/usr/bin/env bash

PARAMETER="sub"
my_func $PARAMETER

If we run main.sh, it will output sub sub, but I want it to output main sub.

Is there a way for the function defined in main.sh to always use the value which was declared in main.sh, without restricting the usage of that parameter name in scripts started by main.sh? I'm looking for solutions where I don't need to modify sub.sh, as in my real life problem there are plenty of sub.sh-like functions.

Edit:
Although I already got my question answered, here is a bit background:
main.sh is an entrypoint script for a docker image. This entrypoint is basically a big case statement, and chooses which sub.sh scripts to run based on $1.
I was thinking about creating a utility function in main.sh to avoid retyping a repetitive routine in sub.sh scripts. I'm not the only one who will add sub.sh-like scripts to the image, and that's why I wanted to avoid touching those scripts - I wanted to give other developers a tool, without them needing to be aware of it.
My first thought was copying the value of PARAMETER to a parameter with a unique name, like my_func_PARAMETER. This would most likely ensure that the function always works as expected. That's when it came to my mind if it was possible to export functions with parameters already expanded.

3
  • I'd suggest create an alias instead of a function, but it looks like you can't export aliases. Commented Nov 26, 2021 at 18:41
  • 1. Use lower case variables in your main.sh and avoid overloading the same global name. 2. Rewrite the sub.sh functions so that they use local variables instead of global ones Commented Nov 26, 2021 at 18:48
  • You export the PARAMETER variable when defining your exported function, which means that the variable exists in the environment when your sub.sh script executes. Simply don't change its value, would be one solution, and instead just my_func sub. Or, sub_param=sub; my_func "$sub_param". It's unclear what the purpose of your environment variable PARAMETER is supposed to be, so I'm not turning this into an answer.
    – Kusalananda
    Commented Nov 26, 2021 at 20:14

1 Answer 1

0

You can create functions with parameters already expanded. And as you can overwrite them later (globally or in a subshell) you can kind of "export them with parameters already expanded".

#!/usr/bin/env bash

export PARAMETER="main"

eval "my_func(){
  echo \"$PARAMETER \$1\"
}"

export -f my_func

# Run the other script
./sub.sh

or

#!/usr/bin/env bash

export PARAMETER="main"

my_func(){
  echo "$PARAMETER $1"
}

export -f my_func

# Run the other script
(
eval "my_func(){
  echo \"$PARAMETER \$1\"
}"

./sub.sh
)

Obviously that doesn't make much sense. As doesn't overwriting a variable before you want to use its old content.

#!/usr/bin/env bash

LOCAL_PARAMETER="sub"
my_func "$LOCAL_PARAMETER"
2
  • Perfect, just what I wanted without touching the second function. Thank you very much! One small note, the 2nd works even without the parentheses. I'll edit my question to explain why I'm asking this.
    – cotty
    Commented Nov 29, 2021 at 7:29
  • @cotty I am aware that it kind of works without the parentheses, too, but in that case the function is overwritten in the main context. The subshell is a clean "export". Commented Nov 29, 2021 at 10:27

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .