Question

I have spent hours working on this and reading through other questions on SO and the python docs, but haven't yet resolved this issue.

I am attempting to get python to send an echo command with double-quotes(") and correct spacing over ssh, using variables.

Here is the relevant code snippet:

ssh_upd = Popen([
    'ssh', server, 'sudo', '-S',
    "echo' " "" + mtpt + "  " + "   " +filervol + "'",
    "|", "sudo tee -a", "/etc/"+map, ">", "/dev/null" ], stdout=None, stdin=PIPE, stderr=STDOUT)

mtpt and filervol are both variables defined earlier in the code.

The above code produces this output:

sudo: echo junk         junk:/vol/junk: command not found

python needs to send:

echo "junk              junk:/vol/junk"

Thanks in advance for any help.

Was it helpful?

Solution

I'm not sure what you're trying to do here:

"echo' " ""

… but here's how Python will interpret it:

First, "echo' " is a 6-character string (the word echo, a single ', and a space). Then "" is an empty string. These are concatenated together (forming the same 6-character string, of course).

If you want to put double-quote characters into a double-quoted string, you have to escape them with a backslash, like this:

"echo' \" \""

However, there's a much, much easier way to deal with this stuff: just using triple-quoting. Most people learn about triple-quoting as a way to handle multi-line strings, and it is great for that—but it's also great for strings that have both kinds of quotes inside:

'''echo' " "'''

Also, instead of opening and closing the quotes over and over again so you can use string concatenation, it's a lot simpler to use a single format string and call format on it (or, if you prefer, to use the % operator).


But meanwhile, if what you're trying to send is this:

echo "junk              junk:/vol/junk"

I have no idea why you're starting off with echo' as the start of the string, but you've clearly gone wrong right off the bat. What you want is something like:

'''echo "{0}     {1}"'''.format(mtpt, filervol)

I put 5 spaces there because your original code had a 2-space string added to a 3-space string. But your desired output has 14 spaces, so… I'm not sure what you actually want there. If there were tabs involved in your actual code that got lost in copy-pasting to StackOverflow, I'd recommend using \t escapes in your literals instead of actual tabs.

OTHER TIPS

If you use | or > in your command, then you need to also use shell=True.

If you use shell=True, then the first argument to Popen should be a string, not a list:

ssh_upd = Popen(
    'ssh {server} sudo -S echo "{mtpt}      {filervol}" | sudo tee -a /etc/{map} > /dev/null'.format(server=server, mtpt=mtpt, filervol=filervol, map=map), stdout=None, stdin=PIPE, stderr=STDOUT, shell=True)

Note that if the command sent to Popen includes user input, then you should not use shell=True, since it can be a security risk. (Be sure to read the Warning in the docs.)

You can avoid using shell=True and the pipe |, and the redirect > by using multiple Popens -- connecting one's stdout to the next one's stdin.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top