Issue
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:
-c
-- If the-c
option is present, then commands are read from the first non-option argument command string. If there are arguments after the command string, the first argument is assigned to$0
and any remaining arguments are assigned to the positional parameters. The assignment to$0
sets the name of the shell, which is used in warning and error messages.-s
-- If the-s
option is present, or if no arguments remain after option processing, then commands are read from the standard input. This option allows the positional parameters to be set when invoking an interactive shell or when reading input through a pipe.
In other words, -c
is about passing a command string on the command line while -s
is about passing in commands via stdin.
Answered By - larsks Answer Checked By - David Goodson (WPSolving Volunteer)