45

I am trying to pass my variables from raw_input to my subprocess command. I am new to Python. Any help would he appreciated.

#!/usr/bin/python

import subprocess

print "\nWhat user name"
username = str(raw_input('username: '))
print "\nWhat is the user id"
userid = int(raw_input('Enter user id: '))
print "\nWhat is the user\'s primary group?"
primarygroup = int(raw_input('Enter group: '))
print "\nWhat is the user\'s secondary group?"
secondarygroup = int(raw_input('Enter group: '))

subprocess.call(['useradd' '-m' '-g' _primarygroup '-G' _secondarygroup '-u' _userid _username])

print"\nThe user has been added"
Helgi
  • 5,428
  • 1
  • 31
  • 48
rsouthard
  • 467
  • 1
  • 4
  • 4
  • 4
    What problem are you having? Please be specific. – S.Lott Jan 25 '11 at 15:19
  • 1
    Really old but I'll note that, for example, the primary group was read into `primarygroup` but then attempted to be accessed via `_primarygroup`. – altendky Sep 15 '17 at 12:55

6 Answers6

40

Try separating the values with commas:

subprocess.call(['useradd', '-m', '-g', _primarygroup, '-G', _secondarygroup, '-u', _userid, _username])

See http://docs.python.org/library/subprocess.html#subprocess.call - It takes an array where the first argument is the program and all other arguments are passed as arguments to the program.

Also don't forget to check the return value of the function for a zero return code which means "success" unless it doesn't matter for your script if the user was added successfully or not.

ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
8

Try to add commas between your list items:

subprocess.call(['useradd', '-m', '-g', _primarygroup, '-G', _secondarygroup, \
                 '-u' ,_userid, _username])

subprocess.call takes the same arguments as subprocess.Popen:

args should be a string, or a sequence of program arguments.


Edit

To turn all your arguments into strings at once you could you a list comprehension:

args = ['useradd', '-m', '-g', _primarygroup, '-G', _secondarygroup, \
        '-u' ,_userid, _username]
str_args = [ str(x) for x in args ]
miku
  • 181,842
  • 47
  • 306
  • 310
  • Unfortunately the values for _primarygroup, _secondarygroup, and _username have to be integers. IE: useradd -g 501 -503 -u 501 – rsouthard Jan 25 '11 at 16:01
  • 1
    Maybe your problem is with the shell. Arguments to programs and scripts can only ever be passed as strings (eg. the string '501' is passed instead of integer 501). It is up the called process to parse these strings into the correct format. – Dunes Jan 25 '11 at 16:23
  • You can turn your arguments into strings before passing them to `call`; see my edit. – miku Jan 25 '11 at 16:25
  • Or just `subprocess.check_call(['useradd', '-m', '-g', str(_primarygroup), '-G', str(_secondarygroup), '-u', str(_userid)])` – tripleee Mar 09 '21 at 15:17
2

You can create the arg string first and then just past this variable to the subprocess.call. For example:

projects_csv_fn = 'projects_csv_2.csv'
prjects_json_fn = 'projects.json'

args ='python json_to_csv.py id ' + prjects_json_fn + ' ' + projects_csv_fn

subprocess.call(args, shell=True)
  • 10
    If someone tries to upload a project CSV named `$(rm -rf ~).csv`, running this code means someone'll have a really bad day. – Charles Duffy May 18 '18 at 16:29
  • There are several other [reasons to avoid `shell=True`](https://stackoverflow.com/questions/4795190/passing-variables-to-a-subprocess-call) and gluing strings together so that the shell needs to split them apart again is obviously just wasteful. – tripleee Mar 09 '21 at 15:15
0
subprocess.call(['useradd', '-m','-g', _primarygroup, '-G', _secondarygroup, '-u', _userid, _username])

Pass a list to subprocess.call

user225312
  • 126,773
  • 69
  • 172
  • 181
0

have you tried just using 'xxx{0}'.format(variable) ? see link1 or link2

subprocess.run(['useradd', '-m', '-g {0}'.format(_primarygroup), '-G {0}'.format(_secondarygroup), '-u {0}'.format(_userid)], capture_output=True)

or

subprocess.call(['useradd', '-m', '-g {0}'.format(_primarygroup), '-G {0}'.format(_secondarygroup), '-u {0}'.format(_userid)])

just worked fine to me

Javi
  • 913
  • 2
  • 13
  • 15
  • This is wrong; `'-g'` and the group name need to be separate strings, and similarly for `'-G'` and `'-u'`. Try `subprocess.check_call(['useradd', '-m', '-g', _primarygroup, '-G', _secondarygroup, '-u', _userid])` – tripleee Mar 31 '22 at 09:16
0

You can also use f-strings.

 import subprocess

 site = 'google.com'
 subprocess.run(['nslookup', f'{site}'])
Testing123
  • 363
  • 2
  • 12
  • `f'{site}'` is just a silly way to say `site` if `site` is already a string. – tripleee Mar 09 '21 at 15:13
  • @tripleee `f"{site}"` calls the `__format__` specifier which can also convert non strings into strings, and change the formatting of different things like integers. – Edwin Shepherd Jun 24 '22 at 15:05
  • Of course; that's why it's (more) silly specifically if the value is already a string. For just converting a value into a string, `str(site)` would be clearer and more idiomatic. – tripleee Jun 25 '22 at 09:54