Piduna
Piduna

Reputation: 637

Execute a shell command with python variables

I had script on bash where I generated username, password, ssh-key for user. Part for creating of ssh-key:

su $user -c "ssh-keygen -f /home/$user/.ssh/id_rsa -t rsa -b 4096 -N ''"

How can I do the same in Python with os.system? I tried this:

os.system('su %s -c "ssh-keygen -f /home/%s/.ssh/id_rsa -t rsa -b 4096 -N ''"', user)
TypeError: system() takes at most 1 argument (2 given)

Also I tried:

os.system('su user -c "ssh-keygen -f /home/user/.ssh/id_rsa -t rsa -b 4096 -N ''"')

Of course, it doesn't work either.

Upvotes: 1

Views: 760

Answers (3)

Ariel Otilibili
Ariel Otilibili

Reputation: 280

Format your instructions with the os package; for instance:

import os

user = 'joe'
ssh_dir = "/home/{}/.ssh/id_rsa".format(user)
os.system("ssh-keygen -f {} -t rsa -b 4096 -N ''".format(ssh_dir))

Upvotes: 2

Jean-François Fabre
Jean-François Fabre

Reputation: 140276

os.system is very close to a bash command line because it uses an underlying shell (like its cousins subprocess.call... using shell=True)

In your case, there's little interest using subprocess since your command runs a command, so you cannot really use argument protection by subprocess fully.

Pass the exact command, but the only change would be to protect the simple quotes, else python sees that as string end+string start (your string is protected by simple quotes already) and they're eliminated.

Check this simpler example:

>>> 'hello '' world'
'hello  world'
>>> 'hello \'\' world'
"hello '' world"

that's a kind of worst-case when you cannot use either double or simple quotes to protect the string because you're using the other flavour within. In that case, escape the quotes using \:

os.system('su $user -c "ssh-keygen -f /home/$user/.ssh/id_rsa -t rsa -b 4096 -N \'\'"')

Upvotes: 1

M. Matt
M. Matt

Reputation: 77

Use the subprocess module:

import subprocess
username = 'user'
result, err = subprocess.Popen(
            'su %s -c "ssh-keygen -f /home/%s/.ssh/id_rsa -t rsa -b 4096 -N ''"' % (username, username),
            stdout=subprocess.PIPE,
            shell=True
          ).communicate()
if err:
    print('Something went wrong')
else:
    print(result)

Edit: this is the 'fast' way to do that, you should't use shell=True if you can't control the input since it allows code execution as said here

Upvotes: 1

Related Questions