Python subproces.call not working as expected
Question: I can not get the subprocess.call() to work properly:

    
    
    >>> from subprocess import call
    >>> call(['adduser', '--home=/var/www/myusername/', '--gecos', 'GECOS', '--disabled-login', 'myusername'], shell=True)
    adduser: Only one or two names allowed.
    1
    

But without shell=True:

    
    
    >>> call(['adduser', '--home=/var/www/myusername/', '--gecos', 'GECOS', '--disabled-login', 'myusername'])
    Adding user `myusername' ...
    Adding new group `myusername' (1001) ...
    Adding new user `myusername' (1001) with group `myusername' ...
    Creating home directory `/var/www/myusername/' ...
    Copying files from `/etc/skel' ...
    0
    

Or the same directly in shell:

    
    
    root@www1:~# adduser --home=/var/www/myusername/ --gecos GECOS --disabled-login myusername
    Adding user `myusername' ...
    Adding new group `myusername' (1001) ...
    Adding new user `myusername' (1001) with group `myusername' ...
    Creating home directory `/var/www/myusername/' ...
    Copying files from `/etc/skel' ...
    

I miss some logic in the shell=True behavior. Can somebody explain me why?
What is wrong with the first example? From the adduser command error message
it seems that arguments are somehow crippled.

Thanks!


Answer: When you specify shell=True you switch to quite different behaviour. From the
docs:

> On Unix with shell=True, the shell defaults to /bin/sh. If args is a string,
> the string specifies the command to execute through the shell. This means
> that the string must be formatted exactly as it would be when typed at the
> shell prompt. This includes, for example, quoting or backslash escaping
> filenames with spaces in them. If args is a sequence, the first item
> specifies the command string, and any additional items will be treated as
> additional arguments to the shell itself. That is to say, Popen does the
> equivalent of:
>
> Popen(['/bin/sh', '-c', args[0], args[1], ...])

So you are running the equivalent of

    
    
    /bin/sh -c "adduser" --home=/var/www/myusername/ --gecos GECOS --disabled-login myusername
    

The error message you are getting is what happens when you try and run
`adduser` without any arguments as all the arguments are being passed to `sh`.

If you want to set shell=True then you would need to call it like this:

    
    
    call('adduser --home=/var/www/myusername/ --gecos GECOS --disabled-login myusername', shell=True)
    

OR like this:

    
    
    call(['adduser --home=/var/www/myusername/ --gecos GECOS --disabled-login myusername'], shell=True)
    

But mostly you just want to use `call` without the `shell=True` and use a list
of arguments. As per your second, working, example.

