9

I'm try to run this script:

hostname = '192.168.3.4'
port = 22
username = 'username'
password = 'mypassword'
y = "2012"
m = "02"
d = "27"

if __name__ == "__main__":
   s = paramiko.SSHClient()
   s.load_system_host_keys()
   s.connect(hostname, port, username, password)
   command = 'ls /home/user/images/cappi/03000/y/m/d'
   s.close

The question is: how can I put the variables y,m,d into the variable command ?

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
marcelorodrigues
  • 919
  • 5
  • 12
  • 22

4 Answers4

22

Python has lots of ways to perform string formatting. One of the simplest is to simply concatenate the parts of your string together:

#!/usr/bin/env python
import paramiko

hostname = "192.168.3.4"
port = 22
username = "username"
password = "mypassword"
y = "2012"
m = "02"
d = "27"

def do_it():
    s = paramiko.SSHClient()
    s.load_system_host_keys()
    s.connect(hostname, port, username, password)
    command = "ls /home/user/images/cappi/03000/" + y + "/" + m + "/" + d
    stdin, stdout, stderr = s.exec_command(command)
    for line in stdout.readlines():
        print line
    s.close()

if __name__ == "__main__":
    do_it()
Leogout
  • 1,187
  • 1
  • 13
  • 32
mattbornski
  • 11,895
  • 4
  • 31
  • 25
  • 1
    I don't see that that's significantly better. Now if you had said '/'.join([y, m, d]) you'd have a case. – mattbornski Feb 27 '12 at 20:24
  • 1
    The problem here is not syntax, the problem is that if you run `a1 + a2 + a3 + ... + an`, you're creating and destroying `n-1` temporary strings. `join` in Python only creates 1 string. This is a bad habit to get into. – cha0site Feb 27 '12 at 21:16
  • 2
    I would point out 1. n is very small here, 2. the + operator is very readable here, and 3. http://greaterdebater.com/blog/gabe/post/7 – mattbornski Feb 27 '12 at 21:23
  • 1
    @matt: I think we're going to have to agree to disagree here. This is a convention, and getting in the habit of doing it properly is best, IMO. – cha0site Feb 27 '12 at 21:46
  • Using the plus sign for string concatenation is the most un-Pythonic way to do it. Python has like 4 ways to format stings. Percent encoding, f strings, .format, and templates are all preferred over the plus sign. ALSO escape terminal input. pipes.quote is there for a reason. – kagronick Apr 21 '18 at 17:10
  • 1
    This answer is generally correct. But the code is not reliable. It can deadlock in some scenarios. For details, see [Wait to finish command executed with Python Paramiko](https://stackoverflow.com/q/34181078/850848#66839039). – Martin Prikryl Jun 14 '21 at 06:34
3
command = 'ls /home/user/images/cappi/03000/%s/%s/%s' %(y,m,d)
V123456
  • 181
  • 3
3

Using the new format specifications, you can access arguments by name:

'ls /home/user/images/cappi/03000/{year}/{month}/{day}'.format(year=y, month=m, day=d)
BioGeek
  • 21,897
  • 23
  • 83
  • 145
  • You need to put an f in front of the string. – kagronick Apr 21 '18 at 17:11
  • 2
    @kagronick [since Python 3.6 you can use f-strings (PEP 498)](https://docs.python.org/3/whatsnew/3.6.html#whatsnew36-pep498), but the above `.format(...)` string is perfectly valid [since Python 2.6](https://docs.python.org/2/library/stdtypes.html#str.format) and in [Python 3.x](https://docs.python.org/3/library/stdtypes.html#str.format). – BioGeek Apr 21 '18 at 21:07
  • Oh I didn't scroll to the right on my phone. .format was new in 2006 so I assumed f strings were what you were talking about. – kagronick Apr 22 '18 at 12:52
2

I prefer

command = f"ls /home/user/images/cappi/03000/{y}/{m}/{d}"
cucu8
  • 891
  • 10
  • 12