Search code examples
bashkuberneteskubectl

Can you pass an environment variables into kubectl exec without bash -c?


I have a script in a pod called script01 and it can take parameters. I run the script through the following:

POD=<pod name>
runScript="kubectl -n nmspc exec $POD -- script01"
$runScript --command "do stuff"

The reason I run it this way is that I don't have access to create a script on the local machine but I do have access to the script on the pod.

The issue is I want to pass the IP of the host machine to the pod and wanted to do it using an environment variable. I've tried using bash -c to pass the parameters but when calling the script through the variable, it doesn't append the parameters.

runScript="kubectl -n nmspc exec $POD -- bash -c \"export curIP=123 && script01\""

but it does work if I run it with $runScript --command "do stuff"

How can I pass an environment variable to the pod but still be able to call the script through the variable?


Solution

  • /usr/bin/env exports values passed in key=value pairs into the environment of any program it's used to invoke.

    kubectl -n nmspc exec "$POD" -- env curIP=123 script01
    

    Note that you should never use $runScript or any other unquoted expansion to invoke a shell command. See BashFAQ #50 -- I'm trying to put a command in a variable, but the complex cases always fail!


    As an example of how you could keep bash -c in place but have your command work, consider:

    runScript() {
      kubectl -n nmspc exec "$POD" -- bash -c 'export curIP=123 && script01 "$@"' _ "$@"
    }
    
    runScript --command "do stuff"
    

    Here, runScript is a function, not a string variable, and it explicitly passes its entire argument list through to kubectl. Similarly, the copy of bash started by kubectl explicitly passes its argument list (after the $0 placeholder _) through to script01, so the end result is your arguments making it through to your final program.