'What is the difference of writing to files using ">>" vs using linefeed character "\n" in a string when loading text to Kubernetes secret?
I have observed that kubectl inserts an additional \ to linefeed characters when using the --from-literal option. It works as expected when loading "the same" content from a file. Clearly, there must be a difference because the stdout looks different but I fail to see why.
echo "api_key" >> .tmp
echo "api_value" >> .tmp
cat -e .tmp
kubectl delete secrets api-env
kubectl create secret generic api-env --from-file=.api=.tmp
rm .tmp
kubectl get secret api-env -o json | jq '.data | map_values(@base64d)'
#prints:
#api_key$
#api_value$
#secret "api-env" deleted
#secret/api-env created
#{
# ".api": "api_key\napi_value\n"
#}
The commands above create a single linefeed character on each line. Demonstrated by cat -e there are two linefeed characters in the file, each at the end.
Doing the same using a string results in the \n to be escaped.
api="api_key\napi_value\n"
echo $api
kubectl delete secrets api-env
kubectl create secret generic api-env --from-literal=.api=$api
kubectl get secret api-env -o json | jq '.data | map_values(@base64d)'
#prints:
#api_key\napi_value\n
#secret "api-env" deleted
#secret/api-env created
#{
# ".api": "api_key\\napi_value\\n"
#}
The echo command shows the string as it was supplied to the variable, however after loading that to kubernetes the \n are escaped and the content is considered to be a single line.
This is important because in several instances where I am working with kubectl I am not allowed to write to the local file system.
What is happening here and how to stop kubernetes from escaping the \n character?
Environment:
- zsh 5.8 (x86_64-apple-darwin21.0)
- Darwin Kernel Version 21.4.0: root:xnu-8020.101.4~15/RELEASE_X86_64 x86_64
- kubectl Client:"v1.20.10"
- kubectl Server: "v1.23.3"
- minikube version: v1.25.2
Solution 1:[1]
When you use echo $api, echo itself changes the contents: On POSIX-compliant shells with XSI extensions enabled (and while zsh isn't POSIX-compliant in general, it does implement this aspect), the \ns are replaced with literal newlines.
That doesn't happen with --from-literal=.api=$api; there, your \ns are still two-character sequences, first a backslash, then a n.
Given that you're on a shell that supports using $'\n' as a way to represent a newline literal directly, consider --from-literal=.api="api_key"$'\n'"api_value"
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
