Skip to content
Advertisement

How to replicate bash’s escaping on commands passed as arguments to other commands

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.

Advertisement

Answer

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>

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement