0

I'm using Paramiko's exec_command() to run wp-cli commands on a remote server. Any command argument with spaces in it (no matter how I quote it) gives me a "Too many positional arguments" error. Here's sample code:

sshClient.exec_command("wp option update blogname \"Text with spaces\" 2>&1")

I've ssh'd into the remote machine from my local terminal and the command (wp option update blogname "Text with spaces") works fine there. I've also tried using combinations of double and single quotes.

Basically it's like the inner quotes are being ignored entirely and "Text with spaces" is being seen as 3 additional arguments. Is this about how Python parses strings with quotes, or about paramiko's exec_command()? What am I missing?

Matt Dietsche
  • 578
  • 5
  • 17

1 Answers1

1

So this ended up being an issue with how the shell handles quotes in a command. Thanks to Martin for his comment pointing me in the right direction. Here is what finally worked for me:

sshClient.exec_command("wp option update blogname '\"Text with spaces\"' 2>&1")

After some Googling, I found this guide very helpful in understanding what was going on:

Shell Command Line Quoting Mechanisms

My understanding of the issue is that the shell on the remote machine where the command is being run strips out quotes, and always uses spaces as separators for arguments. So in order for "Text with spaces" to be interpreted by the remote shell as a single argument, you have to wrap it in single quotes, and escaped double quotes.

With some deeper understanding of how the shell interprets commands it makes more sense, but at face value it's not intuitive at all.

Matt Dietsche
  • 578
  • 5
  • 17
  • `exec_command` seems to be doing something weird. From the command line, I would have written `ssh remoteHost 'wp option update blogname "Text with spaces" 2>&1'` to avoid making `ssh` construct a single string from my individual arguments. I would have expected `sshClient` to work similarly. – chepner Dec 15 '22 at 15:55
  • @chepner The Paramiko `exec_command` is not doing anything with the `command`. It sends it *literally* to the server. – Martin Prikryl Dec 15 '22 at 17:34
  • So does `ssh`: it's not clear why you need to put two sets of quotation marks around `Text with spaces`. (To be clear, the string is sent as the argument to `$SHELL -c`, which is why you need to be careful with the quotes in the first place.) – chepner Dec 15 '22 at 18:25
  • @chepner Sure, and but we do not know what syntax that OP would have to use with `ssh`. Likely the same as in Python/Paramiko. So it's probably something server-side that needs that strange syntax. – Martin Prikryl Dec 19 '22 at 08:23