Tampa
Tampa

Reputation: 78352

Python - Placing a string that looks like json on a remote server but quotes are being stripped

I am placing a file on a remote machine using paramiko ssh as follows.

rl = str(""" {"run_list":["role[monitor_server]"]}""")
cmd = """sudo touch /etc/chef/first-boot.json;sudo su - -c 'echo "%s" >> /etc/chef/first-boot.json'""" % (rl)
ssh.exec_command(cmd)

However, when I look at the file it looks like this.

{run_list:[role[monitor_server]]}

I need it to to look this this: {"run_list":["role[monitor_server]"]}

How to I keep the quotes?

Upvotes: 1

Views: 256

Answers (2)

bobince
bobince

Reputation: 536675

The quotes would need to be escaped once to fit in the argument to the echo command. This is double-quote-delimited ‘weak escaping’: every " would have to be escaped to \" and you would also have to worry about \, $ and `. The results are then dropped into the argument to the su command, in single-quote-delimited ‘strong escaping’. Here, any single quote characters have to be included by breaking out of the string, eg by replacing with '\''.

Nested escaping is tricky to get right, and given su is involved the consequences of any mistake would appear to be dire for security. Avoid nested templating, and templating shell commands, at all costs.

A potentially better solution would be to cat > /etc/chef/first-boot.json and then pipe in the contents you want stored through the stdin file-like object that exec_command returns. No need to worry about escaping then.

Or simply use Paramiko's SFTPClient to transfer the file.

(Also, str() on the first line is completely redundant.)

Upvotes: 1

San4ez
San4ez

Reputation: 8251

Try escaping quotes. This is specific solution but should work.

>>> rl = """ {"run_list":["role[monitor_server]"]}""".replace('"', '\\"')
>>> print """sudo touch /etc/chef/first-boot.json;sudo su - -c 'echo "%s" >> /etc/chef/first-boot.json'""" % (rl)
sudo touch /etc/chef/first-boot.json;sudo su - -c 'echo " {\"run_list\":[\"role[monitor_server]\"]}" >> /etc/chef/first-boot.json'

Upvotes: 1

Related Questions