def create_robot_cmd_string(robot_file_path, *parms): r""" Create a robot command string and return it. On failure, return an empty string. Description of arguments: robot_file_path The path to the robot file to be run. parms The list of parms to be included in the command string. The name of each variable in this list must be the same as the name of the corresponding parm. This function figures out that name. This function is also able to distinguish robot parms (e.g. --outputdir) from robot program parms (all other parms which will be passed as "-v PARM_NAME:parm_value").. Example: The following call to this function... cmd_buf = create_robot_cmd_string("tools/start_sol_console.robot", OPENBMC_HOST, quiet, test_mode, debug, outputdir, output, log, report) Would return a string something like this. robot -v OPENBMC_HOST:beye6 -v quiet:0 -v test_mode:1 -v debug:1 --outputdir=/gsa/ausgsa/projects/a/autoipl/status --output=beye6.OS_Console.output.xml --log=beye6.OS_Console.log.html --report=beye6.OS_Console.report.html tools/start_sol_console.robot """ robot_file_path = init_robot_file_path(robot_file_path) robot_parm_names = get_robot_parm_names() robot_parm_list = [] stack_frame = 2 ix = 2 for arg in parms: parm = arg parm = gm.quote_bash_parm(gm.escape_bash_quotes(str(parm))) var_name = gp.get_arg_name(None, ix, stack_frame) if var_name in robot_parm_names: p_string = "--" + var_name + "=" + str(parm) robot_parm_list.append(p_string) else: p_string = "-v " + var_name + ":" + str(parm) robot_parm_list.append(p_string) ix += 1 robot_cmd_buf = "robot " + ' '.join(robot_parm_list) + " " +\ robot_file_path return robot_cmd_buf
def create_command_string(command, *pos_parms, **options): r""" Create and return a bash command string consisting of the given arguments formatted as text. The default formatting of options is as follows: <single dash><option name><space delim><option value> Example: -parm value The caller can change the kind of dashes/delimiters used by specifying "arg_dashes" and/or "arg_delims" as options. These options are processed specially by the create_command_string function and do NOT get inserted into the resulting command string. All options following the arg_dashes/arg_delims options will then use the specified values for dashes/delims. In the special case of arg_dashes equal to "--", the arg_delim will automatically be changed to "=". See examples below. Quoting rules: The create_command_string function will single quote option values as needed to prevent bash expansion. If the caller wishes to defeat this action, they may single or double quote the option value themselves. See examples below. pos_parms are NOT automatically quoted. The caller is advised to either explicitly add quotes or to use the quote_bash_parm functions to quote any pos_parms. Examples: command_string = create_command_string('cd', '~') Result: cd ~ Note that the pos_parm ("~") does NOT get quoted, as per the aforementioned rules. If quotes are desired, they may be added explicitly by the caller: command_string = create_command_string('cd', '\'~\'') Result: cd '~' command_string = create_command_string('grep', '\'^[^ ]*=\'', '/tmp/myfile', i=None, m='1', arg_dashes='--', color='always') Result: grep -i -m 1 --color=always '^[^ ]*=' /tmp/myfile In the preceding example, note the use of None to cause the "i" parm to be treated as a flag (i.e. no argument value is generated). Also, note the use of arg_dashes to change the type of dashes used on all subsequent options. The following example is equivalent to the prior. Note that quote_bash_parm is used instead of including the quotes explicitly. command_string = create_command_string('grep', quote_bash_parm('^[^ ]*='), '/tmp/myfile', i=None, m='1', arg_dashes='--', color='always') Result: grep -i -m 1 --color=always '^[^ ]*=' /tmp/myfile In the following example, note the automatic quoting of the password option, as per the aforementioned rules. command_string = create_command_string('my_pgm', '/tmp/myfile', i=None, m='1', arg_dashes='--', password='******') However, let's say that the caller wishes to have bash expand the password value. To achieve this, the caller can use double quotes: command_string = create_command_string('my_pgm', '/tmp/myfile', i=None, m='1', arg_dashes='--', password='******') Result: my_pgm -i -m 1 --password="******" /tmp/myfile command_string = create_command_string('ipmitool', 'power status', I='lanplus', C='3', U='root', P='0penBmc', H='wsbmc010') Result: ipmitool -I lanplus -C 3 -U root -P 0penBmc -H wsbmc010 power status By default create_command_string will take measures to preserve the order of the callers options. In some cases, this effort may fail (as when calling directly from a robot program). In this case, the caller can accept the responsibility of keeping an ordered list of options by calling this function with the last positional parm as some kind of dictionary (preferably an OrderedDict) and avoiding the use of any actual option args. Example: kwargs = collections.OrderedDict([('pass', 0), ('fail', 0)]) command_string = create_command_string('my program', 'pos_parm1', kwargs) Result: my program -pass 0 -fail 0 pos_parm1 Note to programmers who wish to write a wrapper to this function: If the python version is less than 3.6, to get the options to be processed correctly, the wrapper function must include a _stack_frame_ix_ keyword argument to allow this function to properly re-order options: def create_ipmi_ext_command_string(command, **kwargs): return create_command_string('ipmitool', command, _stack_frame_ix_=2, **kwargs) Example call of wrapper function: command_string = create_ipmi_ext_command_string('power status', I='lanplus') Description of argument(s): command The command (e.g. "cat", "sort", "ipmitool", etc.). pos_parms The positional parms for the command (e.g. PATTERN, FILENAME, etc.). These will be placed at the end of the resulting command string. options The command options (e.g. "-m 1", "--max-count=NUM", etc.). Note that if the value of any option is None, then it will be understood to be a flag (for which no value is required). """ arg_dashes = "-" delim = default_arg_delim(arg_dashes) command_string = command if len(pos_parms) > 0 and gp.is_dict(pos_parms[-1]): # Convert pos_parms from tuple to list. pos_parms = list(pos_parms) # Re-assign options to be the last pos_parm value (which is a # dictionary). options = pos_parms[-1] # Now delete the last pos_parm. del pos_parms[-1] else: # Either get stack_frame_ix from the caller via options or set it to # the default value. stack_frame_ix = options.pop('_stack_frame_ix_', 1) if gm.python_version < gm.ordered_dict_version: # Re-establish the original options order as specified on the # original line of code. This function depends on correct order. options = re_order_kwargs(stack_frame_ix, **options) for key, value in options.items(): # Check for special values in options and process them. if key == "arg_dashes": arg_dashes = str(value) delim = default_arg_delim(arg_dashes) continue if key == "arg_delim": delim = str(value) continue # Format the options elements into the command string. command_string += " " + arg_dashes + key if value is not None: command_string += delim if re.match(r'^(["].*["]|[\'].*[\'])$', str(value)): # Already quoted. command_string += str(value) else: command_string += gm.quote_bash_parm(str(value)) # Finally, append the pos_parms to the end of the command_string. Use # filter to eliminate blank pos parms. command_string = ' '.join([command_string] + list(filter(None, pos_parms))) return command_string