# How to run a bash command within a tool?

**URL:** <https://cwl.discourse.group/t/how-to-run-a-bash-command-within-a-tool/952>\
**Category:** CWL Questions\
**Created:** [September 27, 2024, 2:56pm UTC](https://cwl.discourse.group/t/how-to-run-a-bash-command-within-a-tool/952 "2024-09-27T14:56:36Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![kvertacnik](https://yyz2.discourse-cdn.com/free1/user_avatar/cwl.discourse.group/kvertacnik/32/573_2.png) [@kvertacnik](https://cwl.discourse.group/u/kvertacnik)\
**Post date:** [September 27, 2024, 2:56pm UTC](https://cwl.discourse.group/t/how-to-run-a-bash-command-within-a-tool/952/1 "2024-09-27T14:56:36Z")

</div>

I have a tool that utilizes a singularity container, however, I am on an HPC where the singularity module must be loaded prior to using a container. The command for this is “module load singularity”.

I’m trying to load the singularity module before running my command but the below code gives me an “Expression evaluation error”.

What am I doing wrong? Is there a better way to do this?

```auto
class: CommandLineTool
cwlVersion: v1.2

requirements:
  - class: InlineJavascriptRequirement

baseCommand: ["bash", "-c"]

inputs:
    in_gff:
        type: File

    singularity_image:
        type: string

arguments:  
    - valueFrom: |
        module load singularity && 
        singularity exec ${inputs.singularity_image} flatfile-to-json.pl --gff ${inputs.in_gff} --tracklabel 1 --out data/

outputs: 
    out_trackList:
        type: File
        outputBinding: 
            glob: data/trackList.json
    out_tracks:
        type: Directory
        outputBinding: 
            glob: data/tracks

```

---

<div class="post-metadata">

**Author:** ![brunokinoshita](https://yyz2.discourse-cdn.com/free1/user_avatar/cwl.discourse.group/brunokinoshita/32/226_2.png) [@brunokinoshita](https://cwl.discourse.group/u/brunokinoshita)\
**Post date:** [September 28, 2024, 4:43pm UTC](https://cwl.discourse.group/t/how-to-run-a-bash-command-within-a-tool/952/2 "2024-09-28T16:43:55Z")

</div>

To use JavaScript in your `valueFrom`, you have to specify whether you want to return a single value (`$()`) or run JavaScript code that will return a value (`${}`). You can [read more about it here](https://www.commonwl.org/v1.2/Workflow.html#Expressions_(Optional)).

For your example, check if this produces the desired result:

```auto
arguments:  
    - valueFrom: |
        ${
          return `module load singularity && 
          singularity exec ${inputs.singularity_image} flatfile-to-json.pl --gff ${inputs.in_gff} --tracklabel 1 --out data/`
        }

```

The idea is to write some code that will be wrapped in a JavaScript code like `(function() { .... })()`, so it must return a string that will be appended to `bash -c`. I think the backticks are supported, and they allow for multiline strings. Otherwise, you can just return a simple JS string.

---

<div class="post-metadata">

**Author:** ![kvertacnik](https://yyz2.discourse-cdn.com/free1/user_avatar/cwl.discourse.group/kvertacnik/32/573_2.png) [@kvertacnik](https://cwl.discourse.group/u/kvertacnik)\
**Post date:** [September 29, 2024, 6:58pm UTC](https://cwl.discourse.group/t/how-to-run-a-bash-command-within-a-tool/952/3 "2024-09-29T18:58:47Z")

</div>

It worked after I added quotes, otherwise bash tried to execute “module”.

```auto
arguments:  
    - valueFrom: |
        ${
        return `"module load singularityCE && 
        singularity exec ${inputs.singularity_image} flatfile-to-json.pl --gff ${inputs.in_gff} --tracklabel 1 --out json"`
        }

```

---

<div class="post-metadata">

**Author:** ![alexiswl](https://yyz2.discourse-cdn.com/free1/user_avatar/cwl.discourse.group/alexiswl/32/93_2.png) [@alexiswl](https://cwl.discourse.group/u/alexiswl)\
**Post date:** [November 5, 2024, 11:12pm UTC](https://cwl.discourse.group/t/how-to-run-a-bash-command-within-a-tool/952/4 "2024-11-05T23:12:08Z")

</div>

`InitialWorkDirRequirement` might make this a little more readable

```auto
requirements:
  InitialWorkDirRequirement:
    listing:
      - entryname: run.sh
        entry: |
        #!/usr/bin/env bash
        
        # Set up
        set -euo pipefail
        
        # Load singularity
        module load singularity
        
        # Run Singularity exec
        singularity exec "$(inputs.singluarity_image.path)" \\
          flatfile-to-json.pl \\
            --gff "$(inputs.in_gff.path)" \\
            --tracklabel 1 \\
            --out data/

baseCommand: ['bash', 'run.sh']

```

Loading singularity into the tool doesn’t seem like the right way to go about it, and certainly reduces the reproducibility.

Have you tried using something like

```auto
requirements:
  DockerPull: docker/uri/to/jbrowse

baseCommand: ["flatfile-to-json.pl"]

...

```

And running cwltool with the --singlularity parameter?
