shellescapingshquotes

How do I preserve double quotes when executing kubectl exec over ssh?


The context is that I want to write a /tmp/policy.hcl file inside a HashiCorp Vault container from a remote machine that I can then use to write a policy. I am struggling to preserve the double quotes in the file.

#!/bin/sh

function send {
    sshpass -p mypassword ssh -o "UserKnownHostsFile=/dev/null" -o "StrictHostKeyChecking=no" "root@${1}" "${2}"
}

send "${host}" "kubectl -n ${namespace} exec pod/vault-0 -- sh -c 'echo path \"secret/*\" { capabilities = [\"create\", \"read\", \"update\", \"delete\", \"list\"]} > /tmp/policy.hcl'"
# kubectl -n vault exec -it pod/vault-0 -- cat /tmp/policy.hcl
path secret/* { capabilities = [create, read, update, delete, list]}

The content should be path "secret/*" { capabilities = ["create", "read", "update", "delete", "list"]}. I've tried various combinations of escaping and single/double quote usage but they all have similar results.


Solution

  • I am assuming bash is available locally. Note your script is /bin/sh. declare -p, Bash array and printf "%q" I used below are available in Bash.

    First create a function with the work you want to do.

    kubework() {
        echo path \"secret/*\" { capabilities = [\"create\", \"read\", \"update\", \"delete\", \"list\"]} > /tmp/policy.hcl
    }
    

    Then use declare -p to properly serialize the work for remote shell execution.

    sshfunc() {
       namespace=$1
       kubectl -n "${namespace}" exec pod/vault-0 -- sh -c "$(declare -p kubework); kubework"
    }
    

    Then use declare -p and re-quote the command for ssh execution. Pass variables using declare -p or as positional arguments.

    sshcmd=(sh -c "$(declare -p kubework sshfunc);"' sshfunc "$1"' -- "$namespace")
    ssh ... host "$(printf "%q " "${sshcmd[@]}")"
    

    Note that at every stage you have to transfer all functions and required context.