bashkubernetes

How to pass a local script that requires an argument to Kubernetes pod?


I've seen this post which was incredibly helpful, but I am stuck with my particular problem.

Where my problem differs from that post is that the script I have locally requires an argument. The execution of this command takes place in another local script that has a variable $var which contains the argument. So in an ideal world, the following would work:

kubectl exec -i <pod> -c <container> -n "$namespace" -- bash -c "`sh script.sh "$var"`"

However, tried and did not succeed. Namely, $var is set properly in the caller script right before the command, but during the execution of the second script on the pod, $1 is empty, so the argument is not being passed correctly.

Other variations I tried, without success:

kubectl exec -i <pod> -c <container> -n "$namespace" -- bash -c "bash -s" -- "$var" < script.sh

kubectl exec -i <pod-name> -c <container-name> -n "$namespace" -- bash -c 'bash -s' < script.sh "$var"

Any help in getting the correct syntax would be greatly appreciated, bonus points if you can explain what's wrong with my current/previous approaches so I can understand what went wrong!


Solution

  • It's not clear why you using backticks in your first example:

    kubectl exec -i <pod> -c <container> -n "$namespace" -- bash -c "`sh script.sh "$var"`"
    

    That means "replace this command with the output of the command", which isn't what you want. I think what you're looking for is:

    kubectl exec -i mypod -- bash -s "$var" < script.sh
    

    If for example script.sh contains:

    echo Hello, $1
    

    Then running:

    kubectl exec -i example-pod -- bash -s world < script.sh
    

    Produces:

    Hello, world
    

    This isn't kubernetes-specific; that's the same syntax you would use if you wanted to run bash locally with a script on stdin that requires arguments.


    Could you clarify the difference between -c and -s and how that influences the function of the command?

    I think the man page is clear on that front:

    In other words, -c is about passing a command string on the command line while -s is about passing in commands via stdin.