skarnet / execline

The execline scripting language
https://skarnet.org/software/execline/
ISC License
149 stars 19 forks source link

How to have a `MY_VAR=${MY_VAR:-default}` in execline? #16

Closed endersonmaia closed 4 months ago

endersonmaia commented 4 months ago

I'm buildind a "distroless" container without a shell, for reduced attack surface, but I want to provide some variable manipulation convenience at startup.

Since I don't want a #!/bin/sh ENTRYPOINT, I was thinking in using execline for this.

Basically I need something like:

MY_VAR=${MY_VAR:-default}

To provide default values.

CURRENT_NAME=${OLD_NAME:-default}

To translate variable names for backward compatibility.


Sorry if this isn't the channel for questions, if there's a better place for this, just tell me.

skarnet commented 4 months ago

The usual place for these questions is the skaware mailing-list: https://skarnet.org/lists/#skaware

But I can answer your question here: what you're trying to do isn't straightforward with execline because it modifies state, and execline has no state. It can modify its own command line, and modify the environment it transmits, but that's about it. So, you have to use substitution commands to import the environment into the command line with the modifications you want, then re-export the environment variable with the new value.

MY_VAR=${MY_VAR:-default} would look like this:

importas -D default MY_VAR MY_VAR
export MY_VAR ${MY_VAR}

and CURRENT_NAME=${OLD_NAME:-default} would look like this:

importas -D default CURRENT_NAME OLD_NAME
export CURRENT_NAME ${CURRENT_NAME}
endersonmaia commented 4 months ago

I'm using something like this:

#!/bin/execlineb

multisubstitute
{
    importas -D info    RUST_LOG            LOG_LEVEL
    importas -D false   ENABLE_TIMESTAMP    LOG_ENABLE_TIMESTAMP
    importas            HTTP_ENDPOINT       SERVER_HTTP_ENDPOINT
}

export RUST_LOG         ${RUST_LOG}
export ENABLE_TIMESTAMP ${ENABLE_TIMESTAMP}
export HTTP_ENDPOINT    ${HTTP_ENDPOINT}

exit 0

But it fails at export HTTP_ENDPOINT... because it has no default value nor $SERVER_HTTP_ENDPOINT is defined.

So, how could I make sure I only try to export HTTP_ENDPOINT... if ${HTTP_ENDPOINT} is defined.

I tried eltest -v but I'm failing to make it work.

skarnet commented 4 months ago

Yeah, execline has no official method for conditional exports, because it favors having a predictable state. If defining HTTP_ENDPOINT as an empty variable isn't possible for you, try replacing the export HTTP_ENDPOINT line with

ifthenelse -s { eltest -v SERVER_HTTP_ENDPOINT } { export HTTP_ENDPOINT } { }

and that should do what you want.

endersonmaia commented 4 months ago
ifthenelse -s { eltest -v SERVER_HTTP_ENDPOINT } { export HTTP_ENDPOINT } { }

I'm assuming I should do this:

ifthenelse -s { eltest -v SERVER_HTTP_ENDPOINT } { export HTTP_ENDPOINT $SERVER_HTTP_ENDPOINT } { }

When I define SERVER_HTTP_ENDOPINT= and export doesn't have the value I'm getting export: usage: export variable value prog...

But when trying with $SERVER_HTTP_ENDPOINT or ${SERVER_HTTP_ENDPOINT} and retrieving the variable value I get $SERVER_HTTP_ENDPOINT or ${SERVER_HTTP_ENDPOINT} as values.

endersonmaia commented 4 months ago

Ignore my last comment, I was drunk.

skarnet commented 4 months ago

If it's working for you, can I close this?