0

I'm trying to control mdadm from a Python script, and have a call similar to this:

subprocess.Popen('mdadm --create /dev/md1 --raid-devices=4 /dev/md-0 /dev/md-1 /dev/md-2 /dev/md-3'.split())

mdadm then complains with mdadm: You have listed more devices (5) than are in the array(4)!

When I use shell=True (or os.system), it works just fine. For example:

subprocess.Popen('mdadm --create /dev/md1 --raid-devices=4 /dev/md-0 /dev/md-1 /dev/md-2 /dev/md-3', shell=True)

Why does the call fail without shell=True?

EDIT: Here is the full string that I'm splitting up and passing to subprocess.Popen:

mdadm --create /dev/md10 --name /dev/md/demo --chunk=128K --level=raid6 --size=104857600 $MDADM_r6_OPT --spare-device=0 --raid-devices=8 /dev/mapper/mpathbp2 /dev/mapper/mpathbp3 /dev/mapper/mpathbp4 /dev/mapper/mpathbp5 /dev/mapper/mpathcp2 /dev/mapper/mpathcp3 /dev/mapper/mpathcp4 /dev/mapper/mpathcp5
user1769868
  • 133
  • 7
  • 2
    Do the code snippets you've posted exhibit the behavior you describe when you try them? If not, we'll need to see the actual arguments. – user2357112 Jun 16 '15 at 02:06
  • 2
    Does it work if you use `shlex.split('your string here')` instead of `'your string here'.split()`? – dano Jun 16 '15 at 02:06
  • Why are you writing it as a single string (and then telling the interpreter to split it) rather than as a list of individual arguments anyhow? Writing in the less-ambiguous format in the first place is The Right Thing; indeed, having a less ambiguous method for passing argv is part of the point of avoiding `shell=True`. – Charles Duffy Jun 16 '15 at 02:29
  • As it is, this doesn't contain a standalone reproducer, so nobody can actually test their answers. If your _real_ string contains quotes or escaping, that would provide a clear answer to what's going on -- but since you're redacting "irrelevant" parts, we can't detect any such issues, or rule them out. – Charles Duffy Jun 16 '15 at 02:31
  • @dano, that just raises this exception for some reason: `TypeError: execv() argument 1 must be encoded string without NULL bytes, not str` – user1769868 Jun 16 '15 at 03:20
  • @user1769868 You can't use an environment variable in a format like `'$MDADM_r6_OPT'` unless you use `shell=True`, since the shell is what actually knows how to interpret the `$VAR_NAME` format. Instead, use `os.environ['MDMADM_r6_OPT']`. – dano Jun 16 '15 at 03:49

0 Answers0