views:

120

answers:

4

Hello,

For the first time, I am asking a little bit of help over here as I am more of a ServerFault person.

I am doing some scripting in Python and I've been loving the language so far yet I have this little problem which is keeping my script from working.

Here is the code line in question :

subprocess.call('xen-create-image --hostname '+nom+' --memory '+memory+' --partitions=/root/scripts/part.tmp --ip '+ip+' --netmask '+netmask+' --gateway '+gateway+' --passwd',shell=True)

I have tried the same thing with os.popen. All the variables are correctly set.

When I execute the command in question in my regular Linux shell, it works perfectly fine but when I execute it using my Python scripts, I get bizarre errors. I even replaced subprocess.call() by the print function to make sure I am using the exact output of the command.

I went looking into environment variables of my shell but they are pretty much the same... I'll post the error I am getting but I'm not sure it's relevant to my problem.

Use of uninitialized value $lines[0] in substitution (s///) at /usr/share/perl5/Config/IniFiles.pm line 614. Use of uninitialized value $_ in pattern match (m//) at /usr/share/perl5/Config/IniFiles.pm line 628.

I am not a Python expert so I'm most likely missing something here.

Thank you in advance for your help,

Antoine


EDIT

Following miax's advice, I stopped using shell=True. Instead I took a look at the Python documentation for subprocess and used the following piece of code :

cmd = 'xen-create-image --hostname '+nom+' --memory '+memory+' --partitions=/root/scripts/part.tmp --ip '+ip+' --netmask '+netmask+' --gateway '+gateway+' --passwd'
args = shlex.split(cmd)
subprocess.call(args)

Sadly, it doesn't change anything...


EDIT2

I have used the tip given by miax but I still get the above error... Here is the code that I have used.

cmd = ['xen-create-image', '--hostname', nom, '--memory', memory, '--partitions=/root/scripts/part.tmp', '--ip', ip, '--netmask', netmask, '--gateway', gateway, '--passwd']
subprocess.call(cmd)

This is really strange... The exact command works fine when I run it in the regular shell...

+2  A: 

You (in most cases) don't want to use subprocess with shell=True. Pass it a list of arguments to the command. That is

  • more secure: Imagine a user manages to pass foo; rm -rf /; echo as some of the values.
  • more reliable: Imagine one of the strings contains a $ or something – it will be expanded by the shell and replaced by the content of that environment variable.

Without knowing your code and xen-create-image, I assume that is the cause of your problem.

PS: Be sure to look if the exit code of the command is zero, and act appropriately if not. (If you are certain that it will always be zero, use check_call, which raises if it does not; that way you'll at least have a defined behavior if it fails.)

Marian
Ok, what do I use then ? Because not mentionning shell=False or nothing leads to an error...
Antoine Benkemoun
Pass a list, for example `call(['xen-create-image', '--hostname', nom, '--memory', memory, 'and', 'so', 'on'])`(It leads to an error because it tries to run a command named like the *whole* string, which does not exist of course)
Marian
A: 

In your Edit2 example which is failing, you think you are giving the following options to xen-create-image:

  • --hostname
  • --memory
  • --partitions=...
  • etc

... but you are actually specifying the following options:

  • --hostnamespace
  • space--memoryspace
  • space--partitions=...
  • etc

You have this line:

cmd = ['xen-create-image', '--hostname ', nom, ' --memory ', memory, ' --partitions=/root/scripts/part.tmp', ' --ip ', ip, ' --netmask ', netmask, ' --gateway ', gateway, ' --passwd']

But you need to take out the extra spaces:

cmd = ['xen-create-image', '--hostname', nom, '--memory', memory, '--partitions=/root/scripts/part.tmp', '--ip', ip, '--netmask', netmask, '--gateway', gateway, '--passwd']
too much php
Modified my edit2 to take this into account...
Antoine Benkemoun
Yes but what error message do you get now?
too much php
I get the exact same error message then at the beginning.
Antoine Benkemoun
A: 

You need to print the command you are using:

cmd = 'xen-create-image --hostname '+nom+' --memory '+memory+' --partitions=/root/scripts/part.tmp --ip '+ip+' --netmask '+netmask+' --gateway '+gateway+' --passwd'
print "COMMAND:", cmd

And then paste the command into your shell to make sure it is exactly the same.

too much php
I'll give this another try :) Thx for your help !
Antoine Benkemoun
I have tried this and the command works perfectly fine !
Antoine Benkemoun
A: 

Does the xen-create-image script start with a hashbang? That is, is the first line something like

#!/bin/sh

? That is one thing to check. Another is that you can try to call your command as:

cmd = ['/bin/sh', '-c', 'xen-create-image --hostname %s --memory %s --partitions=/root/scripts/part.tmp --ip %s --netmask %s --gateway %s --passwd' % (nom, memory, ip, netmask, gateway)]
subprocess.call(cmd, shell=False)

You might want to print cmd to verify this is the command you intend to run (i.e. check the substitutions).

ΤΖΩΤΖΙΟΥ