code: def run_bash_jobs(
      jobs: Iterator[Job], directory: PathLike = Path.cwd(), dry_run: bool = False
  ) -> None:
      
      logger.debug("Running commands in bash shell")
      # iterate through command groups
      for job in jobs:
          # Check shell exists
          if shutil.which(job.shell) is None:
              raise ProcessLookupError(f"The shell '{job.shell}' was not found.")
  
          failed = False
          for command in job:
              for cmd in command:
                  logger.info(cmd)
                  if dry_run:
                      print(f"{job.shell} -c '{cmd}'")
                  else:
                      result = subprocess.run(
                          [job.shell, "-c", f"{cmd}"], cwd=str(directory)
                      )
                      if result.returncode != 0:
                          failed = True
                          logger.error("Command failed: %s", command)
                          break
          if failed:
              logger.error("A command failed, not continuing further.")
              return
docs: Submit commands to the bash shell.
  
      This function runs the commands iteratively but handles errors in the
      same way as with the pbs_commands function. A command will run for all
      combinations of variables in the variable matrix, however if any one of
      those commands fails then the next command will not run.