سؤال

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...

هل كانت مفيدة؟

المحلول

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).

نصائح أخرى

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.)

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']

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top