<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def grid_search(script: str, params: typing.Iterable[str], dry_run: bool=False) -> None: """ Build all grid search parameter configurations and optionally run them. :param script: String of command prefix, e.g. ``cxflow train -v -o log``. :param params: Iterable collection of strings in standard **cxflow** param form, e.g. ``'numerical_param=[1, 2]'`` or ``'text_param=["hello", "cio"]'``. :param dry_run: If set to ``True``, the built commands will only be printed instead of executed. """


    commands = _build_grid_search_commands(script=script, params=params)

    if dry_run:
        logging.warning('Dry run')
        for command in commands:
            logging.info(command)
    else:
        for command in commands:
            try:
                completed_process = subprocess.run(command)
                logging.info('Command `%s` completed with exit code %d', command, completed_process.returncode)
            except Exception as _:  # pylint: disable=broad-except
                logging.error('Command `%s` failed.', command)