0

I want to execute a shell script with 3 arguments from a python script. (as described here: Python: executing shell script with arguments(variable), but argument is not read in shell script)

Here is my code:

subprocess.call('/root/bin/xen-limit %s %s %s' % (str(dom),str(result),str('--nosave'),), shell=True)

variables dom and result are containing strings.

And here is the output:

/bin/sh: --nosave: not found

UPDATE:

That is the variable "result":

c1 = ['/bin/cat', '/etc/xen/%s.cfg' % (str(dom))]
p1 = subprocess.Popen(c1, stdout=subprocess.PIPE)

c2 = ['grep', 'limited']
p2 = subprocess.Popen(c2, stdin=p1.stdout, stdout=subprocess.PIPE)

c3 = ['cut', '-d=', '-f2']
p3 = subprocess.Popen(c3, stdin=p2.stdout, stdout=subprocess.PIPE)

c4 = ['tr', '-d', '\"']
p4 = subprocess.Popen(c4, stdin=p3.stdout, stdout=subprocess.PIPE)

result = p4.stdout.read()

After that, the variable result is containing a number with mbit (for example 16mbit)

And dom is a string like "myserver"

Community
  • 1
  • 1
Vince
  • 1,133
  • 3
  • 17
  • 34
  • how about `subprocess.call('/root/bin/xen-limit %s %s %s' % (str(dom),str(result),'--nosave'), shell=True)` ? – yakiang Oct 14 '13 at 11:41
  • @yakiang got the same error :/ – Vince Oct 14 '13 at 11:48
  • What is the value of `result`? It sounds like it contains some shell metacharacter which terminates a command, making `--nosave` look like a second command instead of an option to `xen-limit`. – chepner Oct 14 '13 at 12:41
  • @chepner Its containing a number with mbit (for example 16mbit) I have updated my first post. – Vince Oct 14 '13 at 13:15
  • if you put `--nosave` first, do you get the same error? What do you mean "echo the 3 parameters" in the comment below? – beroe Oct 15 '13 at 05:34
  • Yes, If I put the --nosave parameter first, it works. I mean: If I run the script on the console (xen-limit myserver 16mbit --nosave) and echo in this script the 3 arguments (echo $1, echo $2, echo $3, echo $4) Not the best english, I'm sorry :S – Vince Oct 15 '13 at 06:03

3 Answers3

2
from subprocess import Popen, STDOUT, PIPE
print('Executing: /root/bin/xen-limit ' + str(dom) + ' ' + str(result) + ' --nosave')
handle = Popen('/root/bin/xen-limit ' + str(dom) + ' ' + str(result) + ' --nosave', shell=True, stdout=PIPE, stderr=STDOUT, stdin=PIPE)
print(handle.stdout.read())

If this doesn't work i honestly don't know what would. This is the most basic but yet error describing way of opening a 3:d party application or script while still giving you the debug you need.

Torxed
  • 22,866
  • 14
  • 82
  • 131
  • Here is the output: `Executing: /root/bin/xen-limit test1 016mbit --nosave` But `--nosave` is on a new line.. And I get the same error (--nosave not found) – Vince Oct 14 '13 at 12:54
  • 1
    @Vince Try the following `print([str(dom), str(result)])`, something tells me you just have a `\n` in the string somewhere that you forgot to parse out. – Torxed Oct 15 '13 at 12:42
  • How it got there? :P Ok I have removed it with tr and now, it works. Thank you very much! (Y) – Vince Oct 15 '13 at 13:22
  • Hehe, who knows.. IT Ghosts probably ;) You're welcome, often the most simplest solution is to print whatever data it is inside a `[..]` list and you'll see any inconsistencies which might affect your outcome, **tl;dr**: It helps you analyze your data :) Glad it fixed it and GL with your endeavors ;) – Torxed Oct 15 '13 at 13:27
0

Why not you save --nosave to a variable and pass the variable in subprocess

Sathy
  • 303
  • 2
  • 8
  • 18
  • I believe its not an issue with the Python call. Have you checked your shell script separately passing this third argument ? Are you successful ? – Sathy Oct 14 '13 at 12:35
  • If I run the script manually (xen-limit myserver 16mbit --nosave) and echo the 3 parameters, it works. But when I start the python script, the 3. argument is empty – Vince Oct 14 '13 at 13:06
0

It's simpler (and safer) to pass a list consisting of the command name and its arguments.

subprocess.call(['/root/bin/xen-limit]',
                str(dom),
                str(result),
                str('--nosave')
                ])

str('--nosave') is a no-op, as '--nosave' is already a string. The same may be true for dom and result as well.

chepner
  • 497,756
  • 71
  • 530
  • 681