pythonrcs

subprocess.call command for executing "ci -u <filename>"


I am trying to execute a python script that first creates a new file(if it does not exist) and then executes ci(on the newly created file) to create a rcs file with initial revision number. But when I run the script it asks me for description and ending with period '.'. I want this part to be automated with a default description and create the rcs file without user input. Any help would be much appreciated. Following is my code:

import os
import subprocesss

if os.path.isfile(location):

    print "File already exists"

else:

    f = open(location,'a')
    subprocess.call(["ci", "-u", location])
    f.close()
    print "new file has been created"

I tried this and I am getting the following error:

import os

import subprocess

if os.path.isfile(location):

    print "File already exists"

else:

    f = open(location,'a')
    cmd = "ci -u "+location
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
    stdout_data = p.communicate(input='change\n.')[0]
    f.close()
    print "new file has been created"

Traceback (most recent call last): File "testshell.py", line 15, in p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True) File "/usr/local/pythonbrew/pythons/Python-2.7/lib/python2.7/subprocess.py", line 672, in init errread, errwrite) File "/usr/local/pythonbrew/pythons/Python-2.7/lib/python2.7/subprocess.py", line 1201, in _execute_child raise child_exception OSError: [Errno 2] No such file or directory


Solution

  • You can use subprocess.call's stdin argument to give the subprocess a file-like object to use as its standard input (what you would enter by hand).

    The StringIO module contains a class called StringIO that offers a file-like interface to an in-memory string.

    Combining these two pieces together will let you send a specific string to ci, as if the user had entered it manually

    from StringIO import StringIO
    import subprocess
    
    ...
    
    subprocess.call(['command', 'with', 'args'], stdin=StringIO('StandardInput'))
    

    Alternately, as CharlesDuffy suggests, you can use Popen and its communicate method:

    import subprocess
    proc = subprocess.Popen(['command', 'with', 'args'],
        stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = proc.communicate('StandardInput')