Edit 2: Bit of a late edit to summarise the comments on this question. I misunderstood how bash works, and confused it with how python works. I presumed Bash escaped the output of the kubectl
command, so it wouldn't be broken up into multiple arguments when passed to the python command. (i.e. how you would escape quotes in python strings to stop the string being broken up.)
Actually, when surrounding the output of a command in quotes, Bash is able to pass the output of the execution of a command, as a single argument. It does not escape anything, it simply doesn't try and interpret it all either. The issue I was having is actually PyCharm's lack of functionality to pass complex strings as a single argument, and it is PyCharm that parses strings with spaces as multiple arguments.
I'm passing the result of the execution of a command to python as input, like so:
$ python parse_ips.py "$(kubectl get configmap ...)"
This works fine when executing from the command line, however I'm now trying to edit the file using PyCharm. Therefore I need the escaped version of the result of this command which I can paste into PyCharm's debug configuration, as I can't execute the command in real-time like I can do on the command line.
However, I am struggling to find a way to replicate the escaping bash does behind the scenes, so I can use the result as an argument within the PyCharm configuration. Running the above kubectl
command results in a multi-line string which includes spaces and quotes. When I paste this into PyCharm it just interprets it as multiple arguments. I'm looking for the escaped result, which I could paste directly into the command line, or into PyCharm's debug configuration, to achieve the same result with a fixed parameter for testing.
Any help would be greatly appreciated!
Edit: To clarify, I mean on the command line the result of the $(kubectl ...)
command is passed into the python program as a single command line argument when it is surrounded by quotes ("$(kubectl ...)"
). So in the python program, you can access sys.argv[1]
and it will contain the entire execution output of $(kubectl get configmap ...)
. However, if I execute that command myself on the command line, the result is a multi-line string.
If I then copy the result of that into PyCharm (or even on the command line again), it is interpreted as many command line arguments. E.g. it would look something like this:
$ python parse_ips.py apiVersion: v1
data:
item1: ifconfig-push 127.0.0.0 255.255.0.0
item2: ifconfig-push 127.0.0.1 255.255.0.0
item3: ifconfig-push 127.0.0.2 255.255.0.0
...
And so on. This obviously doesn't work in the same way as it did before. So I am unable to test my program without making the kubectl
call from the command line each time. I was looking to replicate what "$(kubectl ...)"
gets converted into so it is able to pass the entire output as a single command line entry.
I am struggling to find a way to replicate the escaping bash does behind the scenes
Typically use printf "%q"
to escape stuff.
printf "%q" "$(kubectl get configmap ....)"
This is printf
as the bash builtin command. It differs from coreutils printf
, and newest ones also support %q
with different quoting style:
/usr/bin/printf "%q" "$(kubectl get configmap ....)"
Modern bash also has quoting expansion:
var="$(kubectl get configmap ....)"
echo "${var@Q}"
And there is also the quoting style outputted by set -x
.
I would suggest to use a file:
kubectl get configmap ... > /tmp/tempfile
python parse_ips.py "$(cat /tmp/tempfile)"
With xclip
you can copy command output straight to the X server clipboard, which is handy:
printf "%q" "$(kubectl get configmap ...)" | xclip -selection clipboard
# then in another window:
python parse_ips.py <right mouse click><select paste>