def run_shell_command(cmd, args=None, filename_out=None, filename_err=None):
<EOL>if args:<EOL><INDENT>args = tuple(args)<EOL><DEDENT>else:<EOL><INDENT>args = ()<EOL><DEDENT>try:<EOL><INDENT>cmd = cmd % tuple([escape_shell_arg(x) for x in args])<EOL><DEDENT>except TypeError:<EOL><INDENT>raise<EOL><DEDENT>cmd_out = '<STR_LIT>'<EOL>cmd_err = '<STR_LIT>'<EOL>if filename_out:<EOL><INDENT>cmd_out_fd = os.open(filename_out, os.O_CREAT, <NUM_LIT>)<EOL>file_cmd_out = filename_out<EOL><DEDENT>else:<EOL><INDENT>cmd_out_fd, file_cmd_out =tempfile.mkstemp("<STR_LIT>")<EOL><DEDENT>if filename_err:<EOL><INDENT>cmd_err_fd = os.open(filename_err, os.O_CREAT, <NUM_LIT>)<EOL>file_cmd_err = filename_err<EOL><DEDENT>else:<EOL><INDENT>cmd_err_fd, file_cmd_err =tempfile.mkstemp("<STR_LIT>")<EOL><DEDENT>cmd_exit_code = os.system("<STR_LIT>" % (cmd,<EOL>file_cmd_out,<EOL>file_cmd_err))<EOL>if not filename_out:<EOL><INDENT>if os.path.exists(file_cmd_out):<EOL><INDENT>cmd_out_fo = open(file_cmd_out)<EOL>cmd_out = cmd_out_fo.read()<EOL>cmd_out_fo.close()<EOL>os.remove(file_cmd_out)<EOL><DEDENT><DEDENT>if not filename_err:<EOL><INDENT>if os.path.exists(file_cmd_err):<EOL><INDENT>cmd_err_fo = open(file_cmd_err)<EOL>cmd_err = cmd_err_fo.read()<EOL>cmd_err_fo.close()<EOL>os.remove(file_cmd_err)<EOL><DEDENT><DEDENT>os.close(cmd_out_fd)<EOL>os.close(cmd_err_fd)<EOL>return cmd_exit_code, cmd_out, cmd_err<EOL>
Run operating system command cmd with arguments from the args
    tuple in a sub-shell and return tuple (exit status code, stdout
    info, stderr info).

    @param cmd: Command to execute in a shell; may contain %s
        placeholders for arguments that will be expanded from the args
        tuple. Example: cmd='echo %s', args = ('hello',).
    @type cmd: string

    @param args: Arguments to be escaped and substituted for %s
        placeholders in cmd.
    @type args: tuple of strings

    @param filename_out: Desired filename for stdout output
        (optional; see below).
    @type filename_out: string

    @param filename_err: Desired filename for stderr output
        (optional; see below).
    @type filename_err: string

    @return: Tuple (exit code, string containing stdout output buffer,
        string containing stderr output buffer).

        However, if either filename_out or filename_err are defined,
        then the output buffers are not passed back but rather written
        into filename_out/filename_err pathnames.  This is useful for
        commands that produce big files, for which it is not practical
        to pass results back to the callers in a Python text buffer.
        Note that it is the client's responsibility to name these
        files in the proper fashion (e.g. to be unique) and to close
        these files after use.
    @rtype: (number, string, string)

    @raise TypeError: if the number of args does not correspond to the
       number of placeholders in cmd.

    @note: Uses temporary files to store out/err output, not pipes due
        to potential pipe race condition on some systems.  If either
        filename_out or filename_err are defined, then do not create
        temporary files, but store stdout or stderr output directly in
        these files instead, and do not delete them after execution.